Refactoring Basyx c# implementation

Signed-off-by: Michael Schoeffler <michael.schoeffler@de.bosch.com>
diff --git a/sdks/csnet/BaSys40.API/Agents/IAssetAdministrationShellAgent.cs b/sdks/csnet/BaSys40.API/Agents/IAssetAdministrationShellAgent.cs
deleted file mode 100644
index b8eb0e1..0000000
--- a/sdks/csnet/BaSys40.API/Agents/IAssetAdministrationShellAgent.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using BaSys40.Utils.ResultHandling;
-
-namespace BaSys40.API.Agents
-{
-    public interface IAssetAdministrationShellAgent
-    {
-        #region SubModel - CRUD-Operations
-
-        IResult<ISubModel> CreateSubModel(string aasId, ISubModel submodel);
-
-        IResult<IElementContainer<ISubModel>> RetrieveSubModels(string aasId);
-
-        IResult<ISubModel> RetrieveSubModel(string aasId, string subModelId);
-
-        IResult DeleteSubModel(string aasId, string subModelId);
-
-        #endregion
-    }    
-}
diff --git a/sdks/csnet/BaSys40.API/Agents/ISubModelAgent.cs b/sdks/csnet/BaSys40.API/Agents/ISubModelAgent.cs
deleted file mode 100644
index 7b3748c..0000000
--- a/sdks/csnet/BaSys40.API/Agents/ISubModelAgent.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using BaSys40.Utils.ResultHandling;
-using System.Collections.Generic;
-
-namespace BaSys40.API.Agents
-{
-    public interface ISubModelAgent
-    {
-
-        #region Operation - CRUD-Operations
-        IResult<IOperationDescription> CreateOperation(string aasId, string subModelId, IOperationDescription operation);
-
-        IResult<IElementContainer<IOperationDescription>> RetrieveOperations(string aasId, string subModelId);
-
-        IResult<IOperationDescription> RetrieveOperation(string aasId, string subModelId, string operationId);
-
-        IResult DeleteOperation(string aasId, string subModelId, string operationId);
-
-        IResult InvokeOperation(string aasId, string subModelId, string operationId, List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout);
-        #endregion
-
-        #region Property - CRUD-Operations
-        IResult<IPropertyDescription> CreateProperty(string aasId, string subModelId, IPropertyDescription property);
-
-        IResult<IElementContainer<IPropertyDescription>> RetrieveProperties(string aasId, string subModelId);
-
-        IResult<IPropertyDescription> RetrieveProperty(string aasId, string subModelId, string propertyId);
-
-        IResult UpdateProperty(string aasId, string subModelId, string propertyId, IValue value);
-
-        IResult DeleteProperty(string aasId, string subModelId, string propertyId);
-        #endregion
-
-        #region Event - CRUD-Operations
-        IResult<IEventDescription> CreateEvent(string aasId, string subModelId, IEventDescription eventable);
-
-        IResult<IElementContainer<IEventDescription>> RetrieveEvents(string aasId, string subModelId);
-
-        IResult<IEventDescription> RetrieveEvent(string aasId, string subModelId, string eventId);
-
-        IResult DeleteEvent(string aasId, string subModelId, string eventId);
-        #endregion
-    }
-}
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedAssetAdministrationShell.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedAssetAdministrationShell.cs
index db44a84..a994a2a 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedAssetAdministrationShell.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedAssetAdministrationShell.cs
@@ -1,6 +1,11 @@
 using BaSys40.Models.Core.AssetAdministrationShell.Generics;
 using BaSys40.Utils.ResultHandling;
-using BaSys40.API.Agents;
+using BaSys40.API.Platform.Agents;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.API.ServiceProvider;
+using System.Collections.Generic;
+using System.Linq;
+using BaSys40.Models.Connectivity;
 
 namespace BaSys40.API.AssetAdministrationShell.Connectables
 {
@@ -8,12 +13,15 @@
     {
         public IAssetAdministrationShell AssetAdministrationShell { get; private set; }
 
-        private readonly IAssetAdministrationShellAgent serviceImpl;
+        public IServiceDescriptor ServiceDescriptor { get; private set; }
 
-        public ConnectedAssetAdministrationShell(IAssetAdministrationShellAgent service,  IAssetAdministrationShell aas)
+        private readonly IAssetAdministrationShellAgent serviceImpl;
+        private Dictionary<string, ISubmodelServiceProvider> submodelServiceProviders;
+
+        public ConnectedAssetAdministrationShell(IAssetAdministrationShellAgent service)
         {
-            AssetAdministrationShell = aas;
             serviceImpl = service;
+            submodelServiceProviders = new Dictionary<string, ISubmodelServiceProvider>();
         }
         
         public void BindTo(IAssetAdministrationShell element)
@@ -26,26 +34,42 @@
             return AssetAdministrationShell;
         }
         
-        public IResult<ISubModel> CreateSubModel(ISubModel subModel)
+        public IResult<ISubmodel> CreateSubmodel(ISubmodel submodel)
         {
-            return serviceImpl.CreateSubModel(AssetAdministrationShell.Identification.Id, subModel);
+            return serviceImpl.CreateSubmodel(AssetAdministrationShell.IdShort, submodel);
         }
 
-        public IResult DeleteSubModel(string subModelId)
+        public IResult DeleteSubmodel(string submodelId)
         {
-            return serviceImpl.DeleteSubModel(AssetAdministrationShell.Identification.Id, subModelId);
+            return serviceImpl.DeleteSubmodel(AssetAdministrationShell.IdShort, submodelId);
         }
 
-        public IResult<ISubModel> RetrieveSubModel(string subModelId)
+        public IResult<ISubmodel> RetrieveSubmodel(string submodelId)
         {
-            return serviceImpl.RetrieveSubModel(AssetAdministrationShell.Identification.Id, subModelId);
+            return serviceImpl.RetrieveSubmodel(AssetAdministrationShell.IdShort, submodelId);
         }
 
-        public IResult<IElementContainer<ISubModel>> RetrieveSubModels()
+        public IResult<ElementContainer<ISubmodel>> RetrieveSubmodels()
         {
-            return serviceImpl.RetrieveSubModels(AssetAdministrationShell.Identification.Id);
+            return serviceImpl.RetrieveSubmodels(AssetAdministrationShell.IdShort);
         }
 
-        
+        public void RegisterSubmodelServiceProvider(string id, ISubmodelServiceProvider submodelServiceProvider)
+        {
+            submodelServiceProviders.Add(id, submodelServiceProvider);
+        }
+
+        public ISubmodelServiceProvider GetSubmodelServiceProvider(string id)
+        {
+            if (submodelServiceProviders.TryGetValue(id, out ISubmodelServiceProvider submodelServiceProvider))
+                return submodelServiceProvider;
+            else
+                return null;
+        }
+
+        public IEnumerable<ISubmodelServiceProvider> GetSubmodelServiceProviders()
+        {
+            return submodelServiceProviders.Values?.ToList();
+        }
     }
 }
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedDataElement.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedDataElement.cs
new file mode 100644
index 0000000..bafdcb9
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedDataElement.cs
@@ -0,0 +1,48 @@
+using BaSys40.API.Platform.Agents;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+
+namespace BaSys40.API.AssetAdministrationShell.Connectables
+{
+    public class ConnectedDataElement : IConnectableDataElement
+    {
+        public IDataElement DataElement { get; }
+        public IAssetAdministrationShell AssetAdministrationShell { get; }
+        public ISubmodel Submodel { get; }
+
+        public event SetDataElementValueEventHandler SetDataElementValueHandler;
+        public event GetDataElementValueEventHandler GetDataElementValueHandler;
+
+        private readonly ISubmodelAgent serviceImpl;
+
+        public ConnectedDataElement(ISubmodelAgent service, IAssetAdministrationShell aas, ISubmodel submodel, IDataElement dataElement)
+        {
+            AssetAdministrationShell = aas;
+            Submodel = submodel;
+            DataElement = dataElement;
+
+            serviceImpl = service;
+        }
+
+        public IValue GetLocalValue()
+        {
+            var result = GetDataElementValueHandler?.Invoke(this);
+            return result;
+        }
+
+        public void SetLocalValue(IValue value)
+        {
+            SetDataElementValueHandler?.Invoke(this, value);
+        }
+
+        public IValue GetRemoteValue()
+        {
+            var result = serviceImpl.RetrieveDataElementValue(AssetAdministrationShell.IdShort, Submodel.IdShort, DataElement.IdShort);
+            return result.Entity;
+        }
+
+        public void SetRemoteValue(IValue value)
+        {
+            serviceImpl.UpdateDataElementValue(AssetAdministrationShell.IdShort, Submodel.IdShort, DataElement.IdShort, value);
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedEvent.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedEvent.cs
index 7348e46..f2e2012 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedEvent.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedEvent.cs
@@ -2,24 +2,25 @@
 using System.IO;
 using System.Xml;
 using System.Xml.Schema;
-using BaSys40.API.Agents;
+using BaSys40.API.Platform.Agents;
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
 
 namespace BaSys40.API.AssetAdministrationShell.Connectables
 {
     public class ConnectedEvent : IConnectableEvent
     {
-        public IEventDescription Event { get; }
-        private IAssetAdministrationShell AssetAdministrationShell { get; }
-        private ISubModel SubModel { get; }
+        public IEvent Event { get; }
+        public IAssetAdministrationShell AssetAdministrationShell { get; }
+        public ISubmodel Submodel { get; }
 
         public event EventHandler EventHandler;
 
-        private readonly ISubModelAgent serviceImpl;
+        private readonly ISubmodelAgent serviceImpl;
 
-        public ConnectedEvent(ISubModelAgent service, IAssetAdministrationShell aas, ISubModel subModel, IEventDescription eventDescription)
+        public ConnectedEvent(ISubmodelAgent service, IAssetAdministrationShell aas, ISubmodel submodel, IEvent eventDescription)
         {
             AssetAdministrationShell = aas;
-            SubModel = subModel;
+            Submodel = submodel;
             Event = eventDescription;
             serviceImpl = service;
         }
@@ -47,11 +48,11 @@
 
         public bool Validate(IPublishableEvent eventToValidate)
         {
-            if (!string.IsNullOrEmpty(Event.Schema))
+            if (!string.IsNullOrEmpty(Event.DataType.Schema))
             {
-                if (Event.SchemaType.HasValue && Event.SchemaType.Value == SchemaType.XSD)
+                if (Event.DataType.SchemaType.HasValue && Event.DataType.SchemaType.Value == SchemaType.XSD)
                 {
-                    using (var stream = GenerateStreamFromString(Event.Schema))
+                    using (var stream = GenerateStreamFromString(Event.DataType.Schema))
                     {
                         XmlSchema schema = XmlSchema.Read(stream, SchemaValidationEventHandler);
                         XmlDocument message = new XmlDocument();
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedOperation.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedOperation.cs
index 0f75e2b..0503374 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedOperation.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedOperation.cs
@@ -1,4 +1,4 @@
-using BaSys40.API.Agents;
+using BaSys40.API.Platform.Agents;
 using BaSys40.Models.Core.AssetAdministrationShell.Generics;
 using BaSys40.Utils.ResultHandling;
 using System.Collections.Generic;
@@ -7,28 +7,28 @@
 {
     public class ConnectedOperation : IConnectableOperation
     {
-        public IOperationDescription Operation { get; }
-        private IAssetAdministrationShell AssetAdministrationShell { get; }
-        private ISubModel SubModel { get; }
+        public IOperation Operation { get; }
+        public IAssetAdministrationShell AssetAdministrationShell { get; }
+        public ISubmodel Submodel { get; }
 
         public event MethodCalledEventHandler OnCallMethod;
 
-        private readonly ISubModelAgent serviceImpl;
+        private readonly ISubmodelAgent serviceImpl;
 
-        public ConnectedOperation(ISubModelAgent service, IAssetAdministrationShell aas, ISubModel subModel, IOperationDescription operationDescription)
+        public ConnectedOperation(ISubmodelAgent service, IAssetAdministrationShell aas, ISubmodel submodel, IOperation operation)
         {
             AssetAdministrationShell = aas;
-            SubModel = subModel;
-            Operation = operationDescription;
+            Submodel = submodel;
+            Operation = operation;
 
             serviceImpl = service;
         }
 
-        public IResult InvokeLocal(List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout)
+        public IResult InvokeLocal(List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout)
         {
             object result;
             if (OnCallMethod != null)
-                result = OnCallMethod.Invoke(this, inputArguments, out outputArguments);
+                result = OnCallMethod.Invoke(this, inputArguments, outputArguments);
             else
             {
                 result = null;
@@ -37,9 +37,9 @@
             return new Result(result != null, result, result?.GetType());  
         }
 
-        public IResult InvokeRemote(List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout)
+        public IResult InvokeRemote(List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout)
         {
-            var result = serviceImpl.InvokeOperation(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, Operation.Identification.Id, inputArguments, out outputArguments, timeout);
+            var result = serviceImpl.InvokeOperation(AssetAdministrationShell.IdShort, Submodel.IdShort, Operation.IdShort, inputArguments, outputArguments, timeout);
             return result;
         }
     }
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedProperty.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedProperty.cs
deleted file mode 100644
index da8a936..0000000
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedProperty.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using BaSys40.API.Agents;
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-
-namespace BaSys40.API.AssetAdministrationShell.Connectables
-{
-    public class ConnectedProperty : IConnectableProperty
-    {
-        public IPropertyDescription Property { get; }
-        private IAssetAdministrationShell AssetAdministrationShell { get; }
-        private ISubModel SubModel { get; }
-
-        public event SetPropertyValueHandler SetPropertyValueHandler;
-        public event GetPropertyValueHandler GetPropertyValueHandler;
-
-        private readonly ISubModelAgent serviceImpl;
-
-        public ConnectedProperty(ISubModelAgent service, IAssetAdministrationShell aas, ISubModel subModel, IPropertyDescription propertyDescription)
-        {
-            AssetAdministrationShell = aas;
-            SubModel = subModel;
-            Property = propertyDescription;
-
-            serviceImpl = service;
-        }
-
-        public IValue GetLocalValue()
-        {
-            var result = GetPropertyValueHandler?.Invoke(this);
-            return result;
-        }
-
-        public void SetLocalValue(IValue value)
-        {
-            SetPropertyValueHandler?.Invoke(this, value);
-        }
-
-        public IValue GetRemoteValue()
-        {
-            var result = serviceImpl.RetrieveProperty(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, Property.Identification.Id);
-            return result.Entity.Value;
-        }
-
-        public void SetRemoteValue(IValue value)
-        {
-            serviceImpl.UpdateProperty(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, Property.Identification.Id, value);
-        }
-    }
-}
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedSubModel.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedSubModel.cs
index 160761e..dc57a54 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedSubModel.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/Connectables/ConnectedSubModel.cs
@@ -1,104 +1,206 @@
 using BaSys40.Models.Core.AssetAdministrationShell.Generics;
 using BaSys40.Utils.ResultHandling;
-using BaSys40.API.Agents;
+using BaSys40.API.Platform.Agents;
 using System.Collections.Generic;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Utils.Client;
+using System;
+using System.Reflection;
+using System.Linq.Expressions;
+using System.Linq;
+using Newtonsoft.Json;
+using BaSys40.Models.Connectivity;
 
 namespace BaSys40.API.AssetAdministrationShell.Connectables
 {
-    public class ConnectedSubModel : IConnectableSubModel
+    public class ConnectedSubmodel : IConnectableSubmodel
     {
-        public ISubModel SubModel { get; private set; }
+        public ISubmodel Submodel { get; private set; }
         private IAssetAdministrationShell AssetAdministrationShell { get; }
+        private IMessageClient messageClient;
 
-        private readonly ISubModelAgent serviceImpl;
+        private readonly ISubmodelAgent submodelServiceImpl;
+        private Dictionary<string, Delegate> methodCalledHandler;
+        private Dictionary<string, DataElementHandler> dataElementHandler;
+        private Dictionary<string, Action<IValue>> updateFunctions;
 
-        public ConnectedSubModel(ISubModelAgent service, IAssetAdministrationShell aas,  ISubModel subModel)
+        public IServiceDescriptor ServiceDescriptor { get; private set; }
+
+        public ConnectedSubmodel(ISubmodelAgent submodelService, IAssetAdministrationShell aas)
         {
-            SubModel = subModel;
             AssetAdministrationShell = aas;
-            serviceImpl = service;
+            submodelServiceImpl = submodelService;
+            methodCalledHandler = new Dictionary<string, Delegate>();
+            dataElementHandler = new Dictionary<string, DataElementHandler>();
+            updateFunctions = new Dictionary<string, Action<IValue>>();
         }
 
-        public void BindTo(ISubModel element)
+        public void BindTo(ISubmodel element)
         {
-            SubModel = element;
+            Submodel = element;
         }
 
-        public ISubModel GetBinding()
+        public ISubmodel GetBinding()
         {
-            return SubModel;
+            return Submodel;
         }
 
-        public IResult<IEventDescription> CreateEvent(IEventDescription eventable)
+        public IResult<IEvent> CreateEvent(IEvent eventable)
         {
-            return serviceImpl.CreateEvent(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, eventable);
+            return submodelServiceImpl.CreateEvent(AssetAdministrationShell.IdShort, Submodel.IdShort, eventable);
         }
 
-        public IResult<IOperationDescription> CreateOperation(IOperationDescription operation)
+        public IResult<IOperation> CreateOperation(IOperation operation)
         {
-            return serviceImpl.CreateOperation(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, operation);
+            return submodelServiceImpl.CreateOperation(AssetAdministrationShell.IdShort, Submodel.IdShort, operation);
         }
 
-        public IResult<IPropertyDescription> CreateProperty(IPropertyDescription property)
+        public IResult<IDataElement> CreateDataElement(IDataElement property)
         {
-            return serviceImpl.CreateProperty(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, property);
+            return submodelServiceImpl.CreateDataElement(AssetAdministrationShell.IdShort, Submodel.IdShort, property);
         }
 
         public IResult DeleteEvent(string eventId)
         {
-            return serviceImpl.DeleteEvent(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, eventId);
+            return submodelServiceImpl.DeleteEvent(AssetAdministrationShell.IdShort, Submodel.IdShort, eventId);
         }
 
         public IResult DeleteOperation(string operationId)
         {
-            return serviceImpl.DeleteOperation(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, operationId);
+            return submodelServiceImpl.DeleteOperation(AssetAdministrationShell.IdShort, Submodel.IdShort, operationId);
         }
 
-        public IResult DeleteProperty(string propertyId)
+        public IResult DeleteDataElement(string dataElementId)
         {
-            return serviceImpl.DeleteProperty(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, propertyId);
+            return submodelServiceImpl.DeleteDataElement(AssetAdministrationShell.IdShort, Submodel.IdShort, dataElementId);
         }
 
-        public IResult<IEventDescription> RetrieveEvent(string eventId)
+        public IResult<IEvent> RetrieveEvent(string eventId)
         {
-            return serviceImpl.RetrieveEvent(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, eventId);
+            return submodelServiceImpl.RetrieveEvent(AssetAdministrationShell.IdShort, Submodel.IdShort, eventId);
         }
 
-        public IResult<IElementContainer<IEventDescription>> RetrieveEvents()
+        public IResult<ElementContainer<IEvent>> RetrieveEvents()
         {
-            return serviceImpl.RetrieveEvents(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id);
+            return submodelServiceImpl.RetrieveEvents(AssetAdministrationShell.IdShort, Submodel.IdShort);
         }
 
-        public IResult<IOperationDescription> RetrieveOperation(string operationId)
+        public IResult<IOperation> RetrieveOperation(string operationId)
         {
-            return serviceImpl.RetrieveOperation(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, operationId);
+            return submodelServiceImpl.RetrieveOperation(AssetAdministrationShell.IdShort, Submodel.IdShort, operationId);
         }
 
-        public IResult<IElementContainer<IOperationDescription>> RetrieveOperations()
+        public IResult<ElementContainer<IOperation>> RetrieveOperations()
         {
-            return serviceImpl.RetrieveOperations(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id);   
+            return submodelServiceImpl.RetrieveOperations(AssetAdministrationShell.IdShort, Submodel.IdShort);   
         }
 
-        public IResult<IElementContainer<IPropertyDescription>> RetrieveProperties()
+        public IResult<ElementContainer<IDataElement>> RetrieveDataElements()
         {
-            return serviceImpl.RetrieveProperties(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id);
+            return submodelServiceImpl.RetrieveDataElements(AssetAdministrationShell.IdShort, Submodel.IdShort);
         }
 
-        public IResult<IPropertyDescription> RetrieveProperty(string propertyId)
+        public IResult<IDataElement> RetrieveDataElement(string dataElementId)
         {
-            return serviceImpl.RetrieveProperty(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, propertyId);
+            return submodelServiceImpl.RetrieveDataElement(AssetAdministrationShell.IdShort, Submodel.IdShort, dataElementId);
         }
 
-        public IResult UpdateProperty(string propertyId, IValue value)
+        public IResult<IValue> RetrieveDataElementValue(string dataElementId)
         {
-            return serviceImpl.UpdateProperty(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, propertyId, value);
+            return submodelServiceImpl.RetrieveDataElementValue(AssetAdministrationShell.IdShort, Submodel.IdShort, dataElementId);
         }
 
-        public IResult InvokeOperation(string operationId, List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout)
+        public IResult UpdateDataElementValue(string dataElementId, IValue value)
         {
-            return serviceImpl.InvokeOperation(AssetAdministrationShell.Identification.Id, SubModel.Identification.Id, operationId, inputArguments, out outputArguments, timeout);
+            return submodelServiceImpl.UpdateDataElementValue(AssetAdministrationShell.IdShort, Submodel.IdShort, dataElementId, value);
         }
 
-       
+        public IResult InvokeOperation(string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout)
+        {
+            return submodelServiceImpl.InvokeOperation(AssetAdministrationShell.IdShort, Submodel.IdShort, operationId, inputArguments, outputArguments, timeout);
+        }
+        public DataElementHandler RetrieveDataElementHandler(string dataElementId)
+        {
+            if (dataElementHandler.TryGetValue(dataElementId, out DataElementHandler handler))
+                return handler;
+            else
+                return null;
+        }
+
+        public void RegisterDataElementHandler(string dataElementId, DataElementHandler handler)
+        {
+            if (!dataElementHandler.ContainsKey(dataElementId))
+                dataElementHandler.Add(dataElementId, handler);
+            else
+                dataElementHandler[dataElementId] = handler;
+        }
+
+        public void RegisterMethodCalledHandler(string operationId, MethodCalledHandler handler)
+        {
+            if (!methodCalledHandler.ContainsKey(operationId))
+                methodCalledHandler.Add(operationId, handler);
+            else
+                methodCalledHandler[operationId] = handler;
+        }
+        public void RegisterMethodCalledHandler(string operationId, Delegate handler)
+        {
+            if (!methodCalledHandler.ContainsKey(operationId))
+                methodCalledHandler.Add(operationId, handler);
+            else
+                methodCalledHandler[operationId] = handler;
+        }
+
+        public void RegisterMethodCalledHandler(string operationId, MethodInfo methodInfo, object target)
+        {
+            var parameters = from parameter in methodInfo.GetParameters() select parameter.ParameterType;
+            Delegate del = methodInfo.CreateDelegate(Expression.GetDelegateType(parameters.Concat(new[] { methodInfo.ReturnType }).ToArray()), target);
+            RegisterMethodCalledHandler(operationId, del);
+        }
+
+        public IResult ThrowEvent(IPublishableEvent publishableEvent, string topic, Action<IMessagePublishedEventArgs> MessagePublished, byte qosLevel)
+        {
+            var settings = new JsonSerializerSettings()
+            {
+                Formatting = Formatting.Indented,
+                NullValueHandling = NullValueHandling.Ignore,
+            };
+            settings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
+
+            string message = JsonConvert.SerializeObject(publishableEvent, settings);
+            return messageClient.Publish(topic, message, MessagePublished, qosLevel);
+        }
+
+        public void ConfigureEventHandler(IMessageClient messageClient)
+        {
+            this.messageClient = messageClient;
+        }
+        public Delegate RetrieveMethodDelegate(string operationId)
+        {
+            if (methodCalledHandler.TryGetValue(operationId, out Delegate handler))
+                return handler;
+            else
+                return null;
+        }
+        public MethodCalledHandler RetrieveMethodCalledHandler(string operationId)
+        {
+            if (methodCalledHandler.TryGetValue(operationId, out Delegate handler))
+                return (MethodCalledHandler)handler;
+            else
+                return null;
+        }
+        public virtual void SubscribeUpdates(string dataElementId, Action<IValue> updateFunction)
+        {
+            if (!updateFunctions.ContainsKey(dataElementId))
+                updateFunctions.Add(dataElementId, updateFunction);
+            else
+                updateFunctions[dataElementId] = updateFunction;
+        }
+
+        public virtual void PublishUpdate(string dataElementId, IValue value)
+        {
+            if (updateFunctions.TryGetValue(dataElementId, out Action<IValue> updateFunction))
+                updateFunction.Invoke(value);
+
+        }
     }
 }
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/DataElementHandler.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/DataElementHandler.cs
new file mode 100644
index 0000000..05538a2
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/DataElementHandler.cs
@@ -0,0 +1,24 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+
+namespace BaSys40.API.AssetAdministrationShell
+{
+    public delegate IValue GetDataElementValueEventHandler(IConnectableDataElement dataElement);
+    public delegate void SetDataElementValueEventHandler(IConnectableDataElement dataElement, IValue value);
+
+    public delegate IValue GetDataElementValueHandler(IDataElement dataElement);
+    public delegate void SetDataElementValueHandler(IDataElement dataElement, IValue value);
+
+    public class DataElementHandler
+    {
+        public string IdShort { get; }
+        public GetDataElementValueHandler GetHandler { get; }
+        public SetDataElementValueHandler SetHandler { get; private set; }
+        public DataElementHandler(string idShort, GetDataElementValueHandler getHandler, SetDataElementValueHandler setHandler)
+        {
+            IdShort = idShort;
+            GetHandler = getHandler;
+            SetHandler = setHandler;
+        }
+    }
+
+}
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableAssetAdministrationShell.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableAssetAdministrationShell.cs
index 174e6e2..d635646 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableAssetAdministrationShell.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableAssetAdministrationShell.cs
@@ -1,12 +1,7 @@
 using BaSys40.API.ServiceProvider;
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using BaSys40.Utils.ResultHandling;
 
 namespace BaSys40.API.AssetAdministrationShell
 {
     public interface IConnectableAssetAdministrationShell : IAssetAdministrationShellServiceProvider
-    {
-        IAssetAdministrationShell AssetAdministrationShell { get; }
-
-    }
+    {  }
 }
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableDataElement.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableDataElement.cs
new file mode 100644
index 0000000..4346f15
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableDataElement.cs
@@ -0,0 +1,21 @@
+using BaSys40.API.ServiceProvider;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+
+namespace BaSys40.API.AssetAdministrationShell
+{
+    public interface IConnectableDataElement
+    {
+        IAssetAdministrationShell AssetAdministrationShell { get; }
+        ISubmodel Submodel { get; }
+        IDataElement DataElement { get; }
+
+        event SetDataElementValueEventHandler SetDataElementValueHandler;
+        event GetDataElementValueEventHandler GetDataElementValueHandler;
+
+        IValue GetLocalValue();
+        void SetLocalValue(IValue value);
+        IValue GetRemoteValue();
+        void SetRemoteValue(IValue value);
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableEvent.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableEvent.cs
index 7eed34e..8ee910a 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableEvent.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableEvent.cs
@@ -5,7 +5,9 @@
 {
     public interface IConnectableEvent 
     {
-        IEventDescription Event { get; }
+        IAssetAdministrationShell AssetAdministrationShell { get; }
+        ISubmodel Submodel { get; }
+        IEvent Event { get; }
 
         event EventHandler EventHandler;
 
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableOperation.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableOperation.cs
index b98a4d7..7b1d0c3 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableOperation.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableOperation.cs
@@ -7,10 +7,13 @@
 {
     public interface IConnectableOperation
     {
-        IOperationDescription Operation { get; }
+        IAssetAdministrationShell AssetAdministrationShell { get; }
+        ISubmodel Submodel { get; }
+        IOperation Operation { get; }
+
         event MethodCalledEventHandler OnCallMethod;
 
-        IResult InvokeLocal(List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout);
-        IResult InvokeRemote(List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout);
+        IResult InvokeLocal(List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout);
+        IResult InvokeRemote(List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout);
     }
 }
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableProperty.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableProperty.cs
deleted file mode 100644
index c240bb6..0000000
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableProperty.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using BaSys40.API.ServiceProvider;
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-
-namespace BaSys40.API.AssetAdministrationShell
-{
-    public interface IConnectableProperty
-    {
-        IPropertyDescription Property { get; }
-
-        event SetPropertyValueHandler SetPropertyValueHandler;
-        event GetPropertyValueHandler GetPropertyValueHandler;
-
-        IValue GetLocalValue();
-        void SetLocalValue(IValue value);
-        IValue GetRemoteValue();
-        void SetRemoteValue(IValue value);
-
-    }
-}
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableSubModel.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableSubModel.cs
index e9c565f..7b58891 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableSubModel.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/IConnectableSubModel.cs
@@ -1,11 +1,9 @@
 using BaSys40.API.ServiceProvider;
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
 
 namespace BaSys40.API.AssetAdministrationShell
 {
-    public interface IConnectableSubModel : ISubModelServiceProvider
+    public interface IConnectableSubmodel : ISubmodelServiceProvider
     {
-        ISubModel SubModel { get; }
 
-     }
+    }
 }
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/MethodCalledEventHandler.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/MethodCalledEventHandler.cs
index 59493df..0c9f813 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/MethodCalledEventHandler.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/MethodCalledEventHandler.cs
@@ -5,7 +5,9 @@
 
 namespace BaSys40.API.AssetAdministrationShell
 {
-    public delegate OperationResult MethodCalledEventHandler(IConnectableOperation operation, List<IArgument> inputArguments, out List<IArgument> outputArguments);
+    public delegate OperationResult MethodCalledEventHandler(IConnectableOperation operation, List<IArgument> inputArguments, List<IArgument> outputArguments);
+
+    public delegate OperationResult MethodCalledHandler(IOperation operation, List<IArgument> inputArguments, List<IArgument> outputArguments);
 
     public class OperationResult : Result
     {
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/PropertyHandler.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/PropertyHandler.cs
deleted file mode 100644
index bdfc2d2..0000000
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/PropertyHandler.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-
-namespace BaSys40.API.AssetAdministrationShell
-{
-    public delegate IValue GetPropertyValueHandler(IConnectableProperty property);
-    public delegate void SetPropertyValueHandler(IConnectableProperty property, IValue value);
-
-}
diff --git a/sdks/csnet/BaSys40.API/AssetAdministrationShell/PublishableEvent.cs b/sdks/csnet/BaSys40.API/AssetAdministrationShell/PublishableEvent.cs
index 35fac29..411ab09 100644
--- a/sdks/csnet/BaSys40.API/AssetAdministrationShell/PublishableEvent.cs
+++ b/sdks/csnet/BaSys40.API/AssetAdministrationShell/PublishableEvent.cs
@@ -1,4 +1,6 @@
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
 using BaSys40.Models.Core.Identification;
 using System.Collections.Generic;
 
@@ -14,13 +16,21 @@
 
         public Identifier Identification { get; set; }
 
-        public Identifier EventDescriptionReference { get; set; }
+        public Reference<IEvent> EventDescriptionReference { get; set; }
 
-        public string Description { get; set; }
+        public List<Description> Descriptions { get; set; }
 
         public string DisplayName { get; set; }
-        public IIdentifiable Parent { get; set; }
+        public IReference Parent { get; set; }
 
         public Dictionary<string, string> MetaData { get; set; }
+
+        public AdministrativeInformation Administration { get; set; }
+        public string IdShort { get; set; }
+
+        public string Category { get; set; }
+
+        public ModelType ModelElementType => ModelType.Event;
+
     }
 }
diff --git a/sdks/csnet/BaSys40.API/BaSys40.API.csproj b/sdks/csnet/BaSys40.API/BaSys40.API.csproj
index 69c192f..426d624 100644
--- a/sdks/csnet/BaSys40.API/BaSys40.API.csproj
+++ b/sdks/csnet/BaSys40.API/BaSys40.API.csproj
@@ -1,15 +1,22 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
+    <Configurations>Debug;Release</Configurations>
+    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
+	<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
   </PropertyGroup>
   
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugType>Full</DebugType>
-</PropertyGroup>
-
+  </PropertyGroup>
+  
   <ItemGroup>
     <ProjectReference Include="..\BaSys40.Models\BaSys40.Models.csproj" />
   </ItemGroup>
 
+  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+    <Exec Command="copy &quot;$(ProjectDir)bin\Debug\BaSys40.API.1.0.0.nupkg&quot; &quot;C:\Development\BaSys40\SDK\packages&quot; /Y" />
+  </Target>
+
 </Project>
diff --git a/sdks/csnet/BaSys40.API/Components/ComponentAggregatorServiceProvider.cs b/sdks/csnet/BaSys40.API/Components/ComponentAggregatorServiceProvider.cs
new file mode 100644
index 0000000..252a34a
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/Components/ComponentAggregatorServiceProvider.cs
@@ -0,0 +1,87 @@
+using BaSys40.API.ServiceProvider;
+using BaSys40.Models.Connectivity;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Utils.ResultHandling;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace BaSys40.API.Components
+{
+    public class ComponentAggregatorServiceProvider : IAssetAdministrationShellAggregatorServiceProvider
+    {
+        public IEnumerable<IAssetAdministrationShell> AssetAdministrationShells { get; protected set; }
+
+        private Dictionary<string, IAssetAdministrationShellServiceProvider> AssetAdministrationShellServiceProviders { get; } = new Dictionary<string, IAssetAdministrationShellServiceProvider>();
+
+        public IServiceDescriptor ServiceDescriptor { get; private set; }
+
+        public ComponentAggregatorServiceProvider()
+        {
+            AssetAdministrationShells = new List<IAssetAdministrationShell>();
+        }
+
+        public void BindTo(IEnumerable<IAssetAdministrationShell> element)
+        {
+            AssetAdministrationShells = element;
+        }
+        public IEnumerable<IAssetAdministrationShell> GetBinding()
+        {
+            return AssetAdministrationShells;
+        }
+
+        public IResult<IAssetAdministrationShell> CreateAssetAdministrationShell(IAssetAdministrationShell aas)
+        {
+            AssetAdministrationShells.ToList().Add(aas);
+            return new Result<IAssetAdministrationShell>(true, aas);
+        }
+
+        public IResult DeleteAssetAdministrationShell(string aasId)
+        {
+            AssetAdministrationShells.ToList().RemoveAll(a => a.IdShort == aasId);
+            return new Result(true);
+        }
+
+        public IAssetAdministrationShellServiceProvider GetAssetAdministrationShellServiceProvider(string id)
+        {
+            if (AssetAdministrationShellServiceProviders.TryGetValue(id, out IAssetAdministrationShellServiceProvider assetAdministrationShellServiceProvider))
+                return assetAdministrationShellServiceProvider;
+            else
+                return null;
+        }
+
+        public IEnumerable<IAssetAdministrationShellServiceProvider> GetAssetAdministrationShellServiceProviders()
+        {
+           return AssetAdministrationShellServiceProviders?.Values.ToList();
+        }
+
+        public void RegisterAssetAdministrationShellServiceProvider(string id, IAssetAdministrationShellServiceProvider assetAdministrationShellServiceProvider)
+        {
+            AssetAdministrationShellServiceProviders.Add(id, assetAdministrationShellServiceProvider);
+        }
+
+        public IResult<IAssetAdministrationShell> RetrieveAssetAdministrationShell(string aasId)
+        {
+            var aas = AssetAdministrationShells.ToList().Find(a => a.IdShort == aasId);
+            if (aas != null)
+                return new Result<IAssetAdministrationShell>(true, aas);
+            else
+                return new Result<IAssetAdministrationShell>(false, new Message(MessageType.Error, "Not found"));
+        }
+
+        public IResult<List<IAssetAdministrationShell>> RetrieveAssetAdministrationShells()
+        {
+            return new Result<List<IAssetAdministrationShell>>(true, AssetAdministrationShells.ToList());
+        }
+
+        public IResult UpdateAssetAdministrationShell(string aasId, IAssetAdministrationShell aas)
+        {
+            int i = AssetAdministrationShells.ToList().FindIndex(a => a.IdShort == aas.IdShort);
+            if (i >= 0)
+            {
+                AssetAdministrationShells.ToList()[i] = aas;
+                return new Result<List<IAssetAdministrationShell>>(true);
+            }
+            return new Result(false, new Message(MessageType.Error, "Not found"));
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.API/Components/ComponentAssetAdministrationShellServiceProvider.cs b/sdks/csnet/BaSys40.API/Components/ComponentAssetAdministrationShellServiceProvider.cs
new file mode 100644
index 0000000..32ebb52
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/Components/ComponentAssetAdministrationShellServiceProvider.cs
@@ -0,0 +1,81 @@
+using BaSys40.API.ServiceProvider;
+using BaSys40.Models.Connectivity;
+using BaSys40.Models.Core.AssetAdministrationShell;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Utils.ResultHandling;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace BaSys40.API.Components
+{
+    public abstract class ComponentAssetAdministrationShellServiceProvider : IAssetAdministrationShellServiceProvider
+    {
+        public abstract IAssetAdministrationShell AssetAdministrationShell { get; protected set; }
+        private Dictionary<string, ISubmodelServiceProvider> SubmodelServiceProviders { get; } = new Dictionary<string, ISubmodelServiceProvider>();
+        public IServiceDescriptor ServiceDescriptor { get; private set; }
+
+        public ComponentAssetAdministrationShellServiceProvider(AssetAdministrationShellDescriptor assetAdministrationShellDescriptor) : this()
+        {
+            ServiceDescriptor = assetAdministrationShellDescriptor;
+        }
+        public ComponentAssetAdministrationShellServiceProvider(IAssetAdministrationShell assetAdministrationShell)
+        {
+            BindTo(assetAdministrationShell);
+        }
+
+        public ComponentAssetAdministrationShellServiceProvider()
+        {
+            AssetAdministrationShell = GenerateAssetAdministrationShell();
+            BindTo(AssetAdministrationShell);
+        }
+
+        public virtual void RegisterSubmodelServiceProvider(string submodelId, ISubmodelServiceProvider submodelServiceProvider)
+        {
+            SubmodelServiceProviders.Add(submodelId, submodelServiceProvider);
+        }
+        public virtual ISubmodelServiceProvider GetSubmodelServiceProvider(string submodelId)
+        {
+            if (SubmodelServiceProviders.TryGetValue(submodelId, out ISubmodelServiceProvider submodelServiceProvider))
+                return submodelServiceProvider;
+            else
+                return null;
+        }
+
+        public abstract IAssetAdministrationShell GenerateAssetAdministrationShell();
+
+        public virtual void BindTo(IAssetAdministrationShell element)
+        {
+            AssetAdministrationShell = element;
+        }
+        public virtual IAssetAdministrationShell GetBinding()
+        {
+            return AssetAdministrationShell;
+        }
+
+        public virtual IResult<ISubmodel> CreateSubmodel(ISubmodel submodel)
+        {
+            return AssetAdministrationShell.Submodels.Create(submodel);
+        }
+
+        public virtual IResult DeleteSubmodel(string submodelId)
+        {
+            return AssetAdministrationShell.Submodels.Delete(submodelId);
+        }
+
+        public virtual IResult<ISubmodel> RetrieveSubmodel(string submodelId)
+        {
+            return AssetAdministrationShell.Submodels.Retrieve(submodelId);
+        }
+
+        public virtual IResult<ElementContainer<ISubmodel>> RetrieveSubmodels()
+        {
+            return AssetAdministrationShell.Submodels.RetrieveAll();
+        }
+
+        public virtual IEnumerable<ISubmodelServiceProvider> GetSubmodelServiceProviders()
+        {
+            return SubmodelServiceProviders.Values?.ToList();
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.API/Components/ComponentSubModelServiceProvider.cs b/sdks/csnet/BaSys40.API/Components/ComponentSubModelServiceProvider.cs
new file mode 100644
index 0000000..79ac92f
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/Components/ComponentSubModelServiceProvider.cs
@@ -0,0 +1,259 @@
+using BaSys40.API.AssetAdministrationShell;
+using BaSys40.API.ServiceProvider;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Utils.ResultHandling;
+using BaSys40.Utils.Client;
+using System.Collections.Generic;
+using System;
+using Newtonsoft.Json;
+using System.Reflection;
+using System.Linq.Expressions;
+using System.Linq;
+using BaSys40.Models.Connectivity;
+using BaSys40.Models.Core.AssetAdministrationShell;
+
+namespace BaSys40.API.Components
+{
+    public class ComponentSubmodelServiceProvider : ISubmodelServiceProvider
+    {
+
+        static ComponentSubmodelServiceProvider()
+        {
+            JsonSerializerSettings = new JsonSerializerSettings()
+            {
+                Formatting = Formatting.Indented,
+                NullValueHandling = NullValueHandling.Ignore,
+            };
+            JsonSerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
+        }
+        public static JsonSerializerSettings JsonSerializerSettings { get; set; }
+
+        public ISubmodel Submodel { get; protected set; }
+
+        public IServiceDescriptor ServiceDescriptor { get; internal set; }
+
+        private Dictionary<string, Delegate> methodCalledHandler;
+        private Dictionary<string, DataElementHandler> dataElementHandler;
+        private Dictionary<string, Action<IValue>> updateFunctions;
+        private IMessageClient messageClient;
+      
+        public ComponentSubmodelServiceProvider(SubmodelDescriptor submodelDescriptor) : this()
+        {
+            ServiceDescriptor = submodelDescriptor;
+        }
+
+        public ComponentSubmodelServiceProvider()
+        {
+            methodCalledHandler = new Dictionary<string, Delegate>();
+            dataElementHandler = new Dictionary<string, DataElementHandler>();
+            updateFunctions = new Dictionary<string, Action<IValue>>();
+        }
+
+        public ComponentSubmodelServiceProvider(ISubmodel submodel) : this()
+        {
+            BindTo(submodel);
+        }
+
+        public void BindTo(ISubmodel element)
+        {
+            Submodel = element;
+        }
+        public ISubmodel GetBinding()
+        {
+            return Submodel;
+        }
+
+        public IResult<IEvent> CreateEvent(IEvent eventable)
+        {
+            return Submodel.Events.Create(eventable);
+        }
+
+        public IResult<IOperation> CreateOperation(IOperation operation)
+        {
+            return Submodel.Operations.Create(operation);
+        }
+
+        public IResult<IDataElement> CreateDataElement(IDataElement property)
+        {
+            return Submodel.DataElements.Create(property);
+        }
+
+        public IResult DeleteEvent(string eventId)
+        {
+            return Submodel.Events.Delete(eventId);
+        }
+
+        public IResult DeleteOperation(string operationId)
+        {
+            return Submodel.Operations.Delete(operationId);
+        }
+
+        public IResult DeleteDataElement(string dataElementId)
+        {
+            return Submodel.DataElements.Delete(dataElementId);
+        }
+
+        public MethodCalledHandler RetrieveMethodCalledHandler(string operationId)
+        {
+            if (methodCalledHandler.TryGetValue(operationId, out Delegate handler))
+                return (MethodCalledHandler)handler;
+            else
+                return null;
+        }
+
+        public Delegate RetrieveMethodDelegate(string operationId)
+        {
+            if (methodCalledHandler.TryGetValue(operationId, out Delegate handler))
+                return handler;
+            else
+                return null;
+        }
+
+        public DataElementHandler RetrieveDataElementHandler(string dataElementId)
+        {
+            if (dataElementHandler.TryGetValue(dataElementId, out DataElementHandler handler))
+                return handler;
+            else
+                return null;
+        }
+
+        public void RegisterDataElementHandler(string dataElementId, DataElementHandler handler)
+        {
+            if (!dataElementHandler.ContainsKey(dataElementId))
+                dataElementHandler.Add(dataElementId, handler);
+            else
+                dataElementHandler[dataElementId] = handler;
+        }
+
+        public void RegisterMethodCalledHandler(string operationId, MethodCalledHandler handler)
+        {
+            if (!methodCalledHandler.ContainsKey(operationId))
+                methodCalledHandler.Add(operationId, handler);
+            else
+                methodCalledHandler[operationId] = handler;
+        }
+
+        public void RegisterMethodCalledHandler(string operationId, Delegate handler)
+        {
+            if (!methodCalledHandler.ContainsKey(operationId))
+                methodCalledHandler.Add(operationId, handler);
+            else
+                methodCalledHandler[operationId] = handler;
+        }
+
+        public void RegisterMethodCalledHandler(string operationId, MethodInfo methodInfo, object target)
+        {
+            var parameters = from parameter in methodInfo.GetParameters() select parameter.ParameterType;
+            Delegate del = methodInfo.CreateDelegate(Expression.GetDelegateType(parameters.Concat(new[] { methodInfo.ReturnType }).ToArray()), target);
+            RegisterMethodCalledHandler(operationId, del);
+        }
+
+        public IResult InvokeOperation(string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout)
+        {
+            var operation_Retrieved = RetrieveOperation(operationId);
+            if (methodCalledHandler.TryGetValue(operationId, out Delegate handler) && operation_Retrieved.Success && operation_Retrieved.Entity != null)
+            {
+                var result = (IResult)handler.DynamicInvoke(operation_Retrieved.Entity, inputArguments, outputArguments);
+                return result;
+            }
+            outputArguments = null;
+            return operation_Retrieved;
+        }
+
+        public IResult ThrowEvent(IPublishableEvent publishableEvent, string topic = "/", Action<IMessagePublishedEventArgs> MessagePublished = null, byte qosLevel = 2)
+        {
+            if (messageClient == null || !messageClient.IsConnected)
+                return new Result(false, new Message(MessageType.Warning, "MessageClient is not initialized or not connected"));
+
+            if (publishableEvent == null)
+                return new Result(new ArgumentNullException("publishableEvent"));
+
+            string message = JsonConvert.SerializeObject(publishableEvent, JsonSerializerSettings);
+            return messageClient.Publish(topic, message, MessagePublished, qosLevel);
+        }
+
+        public IResult<IEvent> RetrieveEvent(string eventId)
+        {
+            return Submodel.Events.Retrieve(eventId);
+        }
+
+        public IResult<ElementContainer<IEvent>> RetrieveEvents()
+        {
+            return Submodel.Events.RetrieveAll();
+        }
+
+        public IResult<IOperation> RetrieveOperation(string operationId)
+        {
+            return Submodel.Operations.Retrieve(operationId);
+        }
+
+        public IResult<ElementContainer<IOperation>> RetrieveOperations()
+        {
+            return Submodel.Operations.RetrieveAll();
+        }
+
+        public IResult<ElementContainer<IDataElement>> RetrieveDataElements()
+        {
+            return Submodel.DataElements.RetrieveAll();
+        }
+
+        public IResult<IDataElement> RetrieveDataElement(string dataElementId)
+        {
+            return Submodel.DataElements.Retrieve(dataElementId);
+        }
+
+        public IResult<IValue> RetrieveDataElementValue(string dataElementId)
+        {
+            if (dataElementHandler.TryGetValue(dataElementId, out DataElementHandler handler) && handler.GetHandler != null)
+            {
+                var dataElement = RetrieveDataElement(dataElementId);
+                if(dataElement.Success && dataElement.Entity != null)
+                    return new Result<IValue>(true, handler.GetHandler.Invoke(dataElement.Entity));
+                else
+                    return new Result<IValue>(false, new Message(MessageType.Error, "DataElement not found"));
+            }
+            else
+                return new Result<IValue>(false, new Message(MessageType.Error, "DataElementHandler or GetHandler not found"));
+        }
+
+
+        public IResult UpdateDataElementValue(string dataElementId, IValue value)
+        {
+            if (dataElementHandler.TryGetValue(dataElementId, out DataElementHandler handler) && handler.SetHandler != null)
+            {
+                var dataElement = RetrieveDataElement(dataElementId);
+                if (dataElement.Success && dataElement.Entity != null)
+                {
+                    handler.SetHandler.Invoke(dataElement.Entity, value);
+                    return new Result(true);
+                }
+                else
+                    return new Result<IValue>(false, new Message(MessageType.Error, "DataElement not found"));
+            }
+            else
+                return new Result<IValue>(false, new Message(MessageType.Error, "DataElementHandler or SetHandler not found"));
+        }
+
+        public virtual void ConfigureEventHandler(IMessageClient messageClient)
+        {
+            this.messageClient = messageClient;
+        }
+
+        public virtual void SubscribeUpdates(string dataElementId, Action<IValue> updateFunction)
+        {
+            if (!updateFunctions.ContainsKey(dataElementId))
+                updateFunctions.Add(dataElementId, updateFunction);
+            else
+                updateFunctions[dataElementId] = updateFunction;
+        }
+
+        public virtual void PublishUpdate(string dataElementId, IValue value)
+        {
+            if (updateFunctions.TryGetValue(dataElementId, out Action<IValue> updateFunction))
+                updateFunction.Invoke(value);
+
+        }
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.API/Platform/Agents/IAssetAdministrationShellAgent.cs b/sdks/csnet/BaSys40.API/Platform/Agents/IAssetAdministrationShellAgent.cs
new file mode 100644
index 0000000..bc8b986
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/Platform/Agents/IAssetAdministrationShellAgent.cs
@@ -0,0 +1,22 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Utils.ResultHandling;
+
+namespace BaSys40.API.Platform.Agents
+{
+    public interface IAssetAdministrationShellAgent
+    {
+
+        #region Submodel - CRUD-Operations
+
+        IResult<ISubmodel> CreateSubmodel(string aasId, ISubmodel submodel);
+
+        IResult<ElementContainer<ISubmodel>> RetrieveSubmodels(string aasId);
+
+        IResult<ISubmodel> RetrieveSubmodel(string aasId, string submodelId);
+
+        IResult DeleteSubmodel(string aasId, string submodelId);
+
+        #endregion
+    }    
+}
diff --git a/sdks/csnet/BaSys40.API/Platform/Agents/ISubModelAgent.cs b/sdks/csnet/BaSys40.API/Platform/Agents/ISubModelAgent.cs
new file mode 100644
index 0000000..488888d
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/Platform/Agents/ISubModelAgent.cs
@@ -0,0 +1,47 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Utils.ResultHandling;
+using System.Collections.Generic;
+
+namespace BaSys40.API.Platform.Agents
+{
+    public interface ISubmodelAgent
+    {
+
+        #region Operation - CRUD-Operations
+        IResult<IOperation> CreateOperation(string aasId, string submodelId, IOperation operation);
+
+        IResult<ElementContainer<IOperation>> RetrieveOperations(string aasId, string submodelId);
+
+        IResult<IOperation> RetrieveOperation(string aasId, string submodelId, string operationId);
+
+        IResult DeleteOperation(string aasId, string submodelId, string operationId);
+
+        IResult InvokeOperation(string aasId, string submodelId, string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout);
+        #endregion
+
+        #region DataElement - CRUD-Operations
+        IResult<IDataElement> CreateDataElement(string aasId, string submodelId, IDataElement dataElement);
+
+        IResult<ElementContainer<IDataElement>> RetrieveDataElements(string aasId, string submodelId);
+
+        IResult<IDataElement> RetrieveDataElement(string aasId, string submodelId, string dataElementId);
+
+        IResult UpdateDataElementValue(string aasId, string submodelId, string dataElementId, IValue value);
+
+        IResult<IValue> RetrieveDataElementValue(string aasId, string submodelId, string dataElementId);
+
+        IResult DeleteDataElement(string aasId, string submodelId, string dataElementId);
+        #endregion
+
+        #region Event - CRUD-Operations
+        IResult<IEvent> CreateEvent(string aasId, string submodelId, IEvent eventable);
+
+        IResult<ElementContainer<IEvent>> RetrieveEvents(string aasId, string submodelId);
+
+        IResult<IEvent> RetrieveEvent(string aasId, string submodelId, string eventId);
+
+        IResult DeleteEvent(string aasId, string submodelId, string eventId);
+        #endregion
+    }
+}
diff --git a/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellAggregator.cs b/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellAggregator.cs
index 461968a..967ff1f 100644
--- a/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellAggregator.cs
+++ b/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellAggregator.cs
@@ -12,7 +12,7 @@
 
         IResult<List<IAssetAdministrationShell>> RetrieveAssetAdministrationShells();
 
-        IResult UpdateAssetAdministrationShell(string aasId, Dictionary<string, string> metaData);
+        IResult UpdateAssetAdministrationShell(string aasId, IAssetAdministrationShell aas);
 
         IResult DeleteAssetAdministrationShell(string aasId);       
     }
diff --git a/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellHandler.cs b/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellHandler.cs
index 92db45c..7bce300 100644
--- a/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellHandler.cs
+++ b/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellHandler.cs
@@ -4,9 +4,9 @@
 {
     public interface IAssetAdministrationShellHandler
     {
-        void RegisterSetPropertyValueHandler(IConnectableSubModel connectableSubModel, IConnectableProperty connectableProperty, SetPropertyValueHandler setPropertyValueHandler);
-        void RegisterGetPropertyValueHandler(IConnectableSubModel connectableSubModel, IConnectableProperty connectableProperty, GetPropertyValueHandler getPropertyValueHandler);
-        void RegisterMethodCalledEventHandler(IConnectableSubModel connectableSubModel, IConnectableOperation connectableOperation, MethodCalledEventHandler handler);
-        void RegisterEventHandler(IConnectableSubModel connectableSubModel, IConnectableEvent connectableEvent, EventHandler handler);
+        void RegisterSetPropertyValueHandler(IConnectableSubmodel connectableSubmodel, IConnectableDataElement connectableProperty, SetDataElementValueEventHandler setPropertyValueHandler);
+        void RegisterGetPropertyValueHandler(IConnectableSubmodel connectableSubmodel, IConnectableDataElement connectableProperty, GetDataElementValueEventHandler getPropertyValueHandler);
+        void RegisterMethodCalledEventHandler(IConnectableSubmodel connectableSubmodel, IConnectableOperation connectableOperation, MethodCalledEventHandler handler);
+        void RegisterEventHandler(IConnectableSubmodel connectableSubmodel, IConnectableEvent connectableEvent, EventHandler handler);
     }
 }
diff --git a/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellManager.cs b/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellManager.cs
index 270ff60..78d349e 100644
--- a/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellManager.cs
+++ b/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellManager.cs
@@ -1,8 +1,8 @@
-using BaSys40.API.Agents;
+using BaSys40.API.Platform.Agents;
 
 namespace BaSys40.API.Platform
 {
-    public interface IAssetAdministrationShellManager : IAssetAdministrationShellAggregator, IAssetAdministrationShellAgent, ISubModelAgent
+    public interface IAssetAdministrationShellManager : IAssetAdministrationShellAggregator, IAssetAdministrationShellAgent, ISubmodelAgent
     {
     }
 }
diff --git a/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellRegistry.cs b/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellRegistry.cs
index 23e03a2..9645b77 100644
--- a/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellRegistry.cs
+++ b/sdks/csnet/BaSys40.API/Platform/IAssetAdministrationShellRegistry.cs
@@ -1,16 +1,20 @@
-using BaSys40.API.Agents;
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell;
 using BaSys40.Utils.ResultHandling;
 using System.Collections.Generic;
 
 namespace BaSys40.API.Platform
 {
-    public interface IAssetAdministrationShellRegistry : IAssetAdministrationShellAgent
+    public interface IAssetAdministrationShellRegistry
     {
-        IResult<IAssetAdministrationShell> CreateAssetAdministrationShell(IAssetAdministrationShell aas);
-        IResult<IAssetAdministrationShell> RetrieveAssetAdministrationShell(string aasId);
-        IResult<List<IAssetAdministrationShell>> RetrieveAssetAdministrationShells();
+        IResult<AssetAdministrationShellDescriptor> CreateAssetAdministrationShell(AssetAdministrationShellDescriptor aas);
+        IResult<AssetAdministrationShellDescriptor> RetrieveAssetAdministrationShell(string aasId);
+        IResult<List<AssetAdministrationShellDescriptor>> RetrieveAssetAdministrationShells();
         IResult UpdateAssetAdministrationShell(string aasId, Dictionary<string, string> metaData);
-        IResult DeleteAssetAdministrationShell(string aasId);       
+        IResult DeleteAssetAdministrationShell(string aasId);
+
+        IResult<SubmodelDescriptor> CreateSubmodel(string aasId, SubmodelDescriptor submodel);
+        IResult<List<SubmodelDescriptor>> RetrieveSubmodels(string aasId);
+        IResult<SubmodelDescriptor> RetrieveSubmodel(string aasId, string submodelId);
+        IResult DeleteSubmodel(string aasId, string submodelId);
     }
 }
diff --git a/sdks/csnet/BaSys40.API/Components/IComponentConnector.cs b/sdks/csnet/BaSys40.API/Platform/IPlatformConnector.cs
similarity index 75%
rename from sdks/csnet/BaSys40.API/Components/IComponentConnector.cs
rename to sdks/csnet/BaSys40.API/Platform/IPlatformConnector.cs
index b48ba13..a7e81ff 100644
--- a/sdks/csnet/BaSys40.API/Components/IComponentConnector.cs
+++ b/sdks/csnet/BaSys40.API/Platform/IPlatformConnector.cs
@@ -1,15 +1,15 @@
 using BaSys40.API.Platform;
+using BaSys40.Models.Core.AssetAdministrationShell;
 using BaSys40.Models.Core.AssetAdministrationShell.Generics;
 using BaSys40.Utils.ResultHandling;
-using System;
 
-namespace BaSys40.API.Components
+namespace BaSys40.API.Platform
 {
-    public interface IComponentConnector
+    public interface IPlatformConnector
     {
         IAssetAdministrationShell GenerateAssetAdministrationShell();
 
-        IResult Register(IAssetAdministrationShellRegistry registry, IAssetAdministrationShell aas);
+        IResult Register(IAssetAdministrationShellRegistry registry, AssetAdministrationShellDescriptor aas);
 
         IResult CreateStructure(IAssetAdministrationShellManager manager, IAssetAdministrationShellHandler handler, IAssetAdministrationShell aas);
 
diff --git a/sdks/csnet/BaSys40.API/ServiceProvider/IAssetAdministrationShellAggregatorServiceProvider.cs b/sdks/csnet/BaSys40.API/ServiceProvider/IAssetAdministrationShellAggregatorServiceProvider.cs
new file mode 100644
index 0000000..841209f
--- /dev/null
+++ b/sdks/csnet/BaSys40.API/ServiceProvider/IAssetAdministrationShellAggregatorServiceProvider.cs
@@ -0,0 +1,14 @@
+using BaSys40.API.Platform;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using System.Collections.Generic;
+
+namespace BaSys40.API.ServiceProvider
+{
+    public interface IAssetAdministrationShellAggregatorServiceProvider : IServiceProvider<IEnumerable<IAssetAdministrationShell>>, IAssetAdministrationShellAggregator
+    {
+        IEnumerable<IAssetAdministrationShell> AssetAdministrationShells { get; }
+        void RegisterAssetAdministrationShellServiceProvider(string id, IAssetAdministrationShellServiceProvider assetAdministrationShellServiceProvider);
+        IAssetAdministrationShellServiceProvider GetAssetAdministrationShellServiceProvider(string id);
+        IEnumerable<IAssetAdministrationShellServiceProvider> GetAssetAdministrationShellServiceProviders();
+    }
+}
diff --git a/sdks/csnet/BaSys40.API/ServiceProvider/IAssetAdministrationShellServiceProvider.cs b/sdks/csnet/BaSys40.API/ServiceProvider/IAssetAdministrationShellServiceProvider.cs
index f92a064..9329bca 100644
--- a/sdks/csnet/BaSys40.API/ServiceProvider/IAssetAdministrationShellServiceProvider.cs
+++ b/sdks/csnet/BaSys40.API/ServiceProvider/IAssetAdministrationShellServiceProvider.cs
@@ -1,22 +1,29 @@
 using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
 using BaSys40.Utils.ResultHandling;
+using System.Collections.Generic;
 
 namespace BaSys40.API.ServiceProvider
 {
     public interface IAssetAdministrationShellServiceProvider : IServiceProvider<IAssetAdministrationShell>
     {
-        #region SubModel - CRUD-Operations
+        IAssetAdministrationShell AssetAdministrationShell { get; }
 
-        IResult<ISubModel> CreateSubModel(ISubModel submodel);
 
-        IResult<IElementContainer<ISubModel>> RetrieveSubModels();
+        #region Submodel - CRUD-Operations
 
-        IResult<ISubModel> RetrieveSubModel(string subModelId);
+        IResult<ISubmodel> CreateSubmodel(ISubmodel submodel);
 
-        IResult DeleteSubModel(string subModelId);
+        IResult<ElementContainer<ISubmodel>> RetrieveSubmodels();
+
+        IResult<ISubmodel> RetrieveSubmodel(string submodelId);
+
+        IResult DeleteSubmodel(string submodelId);
 
         #endregion
 
-  
+        void RegisterSubmodelServiceProvider(string id, ISubmodelServiceProvider submodelServiceProvider);
+        ISubmodelServiceProvider GetSubmodelServiceProvider(string id);
+        IEnumerable<ISubmodelServiceProvider> GetSubmodelServiceProviders();
     }
 }
diff --git a/sdks/csnet/BaSys40.API/ServiceProvider/IServiceProvider.cs b/sdks/csnet/BaSys40.API/ServiceProvider/IServiceProvider.cs
index 3fd4532..fcc596a 100644
--- a/sdks/csnet/BaSys40.API/ServiceProvider/IServiceProvider.cs
+++ b/sdks/csnet/BaSys40.API/ServiceProvider/IServiceProvider.cs
@@ -1,12 +1,10 @@
-using BaSys40.Models.Core.Identification;
-using System;
-using System.Collections.Generic;
-using System.Text;
+using BaSys40.Models.Connectivity;
 
 namespace BaSys40.API.ServiceProvider
 {
     public interface IServiceProvider<T>
     {
+        IServiceDescriptor ServiceDescriptor { get; }
         void BindTo(T element);
         T GetBinding();
     }
diff --git a/sdks/csnet/BaSys40.API/ServiceProvider/ISubModelServiceProvider.cs b/sdks/csnet/BaSys40.API/ServiceProvider/ISubModelServiceProvider.cs
index 86b1abc..37aaf56 100644
--- a/sdks/csnet/BaSys40.API/ServiceProvider/ISubModelServiceProvider.cs
+++ b/sdks/csnet/BaSys40.API/ServiceProvider/ISubModelServiceProvider.cs
@@ -1,44 +1,62 @@
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Utils.Client;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
 using BaSys40.Utils.ResultHandling;
 using System.Collections.Generic;
+using System;
+using BaSys40.API.AssetAdministrationShell;
 
 namespace BaSys40.API.ServiceProvider
 {
-    public interface ISubModelServiceProvider : IServiceProvider<ISubModel>
+    public interface ISubmodelServiceProvider : IServiceProvider<ISubmodel>
     {
-        
+        ISubmodel Submodel { get; }
+
         #region Operation - CRUD-Operations
-        IResult<IOperationDescription> CreateOperation(IOperationDescription operation);
+        IResult<IOperation> CreateOperation(IOperation operation);
 
-        IResult<IElementContainer<IOperationDescription>> RetrieveOperations();
+        IResult<ElementContainer<IOperation>> RetrieveOperations();
 
-        IResult<IOperationDescription> RetrieveOperation(string operationId);
+        IResult<IOperation> RetrieveOperation(string operationId);
 
         IResult DeleteOperation(string operationId);
-
-        IResult InvokeOperation(string operationId, List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout);
+    
+        IResult InvokeOperation(string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout);
         #endregion
 
-        #region Property - CRUD-Operations
-        IResult<IPropertyDescription> CreateProperty(IPropertyDescription property);
+        #region DataElement - CRUD-Operations
+        IResult<IDataElement> CreateDataElement(IDataElement dataElement);
 
-        IResult<IElementContainer<IPropertyDescription>> RetrieveProperties();
+        IResult<ElementContainer<IDataElement>> RetrieveDataElements();
 
-        IResult<IPropertyDescription> RetrieveProperty(string propertyId);
+        IResult<IDataElement> RetrieveDataElement(string dataElementId);
 
-        IResult UpdateProperty(string propertyId, IValue value);
+        IResult<IValue> RetrieveDataElementValue(string dataElementId);
 
-        IResult DeleteProperty(string propertyId);
+        IResult UpdateDataElementValue(string dataElementId, IValue value);
+
+        IResult DeleteDataElement(string dataElementId);
+
+        void SubscribeUpdates(string dataElementId, Action<IValue> updateFunction);
+        void PublishUpdate(string dataElementId, IValue value);
         #endregion
 
         #region Event - CRUD-Operations
-        IResult<IEventDescription> CreateEvent(IEventDescription eventable);
+        IResult<IEvent> CreateEvent(IEvent eventable);
 
-        IResult<IElementContainer<IEventDescription>> RetrieveEvents();
+        IResult<ElementContainer<IEvent>> RetrieveEvents();
 
-        IResult<IEventDescription> RetrieveEvent(string eventId);
+        IResult<IEvent> RetrieveEvent(string eventId);
+
+        IResult ThrowEvent(IPublishableEvent publishableEvent, string topic, Action<IMessagePublishedEventArgs> MessagePublished, byte qosLevel);
 
         IResult DeleteEvent(string eventId);
         #endregion
+
+        DataElementHandler RetrieveDataElementHandler(string dataElementId);
+        void RegisterDataElementHandler(string dataElementId, DataElementHandler handler);
+        Delegate RetrieveMethodDelegate(string operationId);
+        void RegisterMethodCalledHandler(string operationId, Delegate handler);
+        void ConfigureEventHandler(IMessageClient messageClient);
     }
 }
diff --git a/sdks/csnet/BaSys40.API/ServiceProvider/Implementations/InMemoryAssetAdministrationShellServiceProvider.cs b/sdks/csnet/BaSys40.API/ServiceProvider/Implementations/InMemoryAssetAdministrationShellServiceProvider.cs
deleted file mode 100644
index 3a0b1e6..0000000
--- a/sdks/csnet/BaSys40.API/ServiceProvider/Implementations/InMemoryAssetAdministrationShellServiceProvider.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using System;
-using System.Collections.Generic;
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using BaSys40.Models.Core.Identification;
-using BaSys40.Utils.ResultHandling;
-
-namespace BaSys40.API.ServiceProvider.Implementations
-{
-    public class InMemoryAssetAdministrationShellServiceProvider : IAssetAdministrationShellServiceProvider
-    {
-        internal IAssetAdministrationShell AssetAdministrationShell { get; set; }
-
-        public InMemoryAssetAdministrationShellServiceProvider()
-        { }
-
-        public void BindTo(IAssetAdministrationShell aas)
-        {
-            if (aas != null)
-                AssetAdministrationShell = aas;
-        }
-
-        public IAssetAdministrationShell GetBinding()
-        {
-            return AssetAdministrationShell;
-        }
-
-
-        public IResult<ISubModel> CreateSubModel(ISubModel subModel)
-        {
-            try
-            {
-                AssetAdministrationShell.SubModels.Add(subModel);
-                return new Result<ISubModel>(true, subModel);
-            }
-            catch (Exception e)
-            {
-                return new Result<ISubModel>(e);
-            }
-        }
-
-        public IResult<IElementContainer<ISubModel>> RetrieveSubModels()
-        {
-            try
-            {
-                return new Result<IElementContainer<ISubModel>>(true, AssetAdministrationShell.SubModels);
-            }
-            catch (Exception e)
-            {
-                return new Result<IElementContainer<ISubModel>>(e);
-            }
-        }
-
-        public IResult<ISubModel> RetrieveSubModel(string subModelId)
-        {
-            try
-            {
-                var subModel = AssetAdministrationShell.SubModels[subModelId];
-                if (subModel == null)
-                    throw new KeyNotFoundException("subModelId not found");
-                return new Result<ISubModel>(true, subModel);
-            }
-            catch (Exception e)
-            {
-                return new Result<ISubModel>(e);
-            }
-        }
-
-        public IResult DeleteSubModel(string subModelId)
-        {
-            try
-            {
-                var subModel = AssetAdministrationShell.SubModels[subModelId];
-                if (subModel == null)
-                    throw new KeyNotFoundException("subModelId not found");
-                AssetAdministrationShell.SubModels.Remove(subModel);
-                return new Result(true);
-            }
-            catch (Exception e)
-            {
-                return new Result(e);
-            }
-        }
-
-        
-    }
-}
diff --git a/sdks/csnet/BaSys40.API/ServiceProvider/Implementations/InMemorySubModelServiceProvider.cs b/sdks/csnet/BaSys40.API/ServiceProvider/Implementations/InMemorySubModelServiceProvider.cs
deleted file mode 100644
index bc3d8a0..0000000
--- a/sdks/csnet/BaSys40.API/ServiceProvider/Implementations/InMemorySubModelServiceProvider.cs
+++ /dev/null
@@ -1,217 +0,0 @@
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using BaSys40.Utils.ResultHandling;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace BaSys40.API.ServiceProvider.Implementations
-{
-    public class InMemorySubModelServiceProvider : ISubModelServiceProvider
-    {
-        private ISubModel SubModel { get; set; }
-
-        public InMemorySubModelServiceProvider()
-        { }
-
-        public void BindTo(ISubModel subModel)
-        {
-            if (subModel != null)
-                SubModel = subModel;
-        }
-
-        public ISubModel GetBinding()
-        {
-            return SubModel;
-        }
-
-        public IResult<IOperationDescription> CreateOperation(IOperationDescription operation)
-        {
-            try
-            {
-                SubModel.Operations.Add(operation);
-                return new Result<IOperationDescription>(true, operation);
-            }
-            catch (Exception e)
-            {
-                return new Result<IOperationDescription>(e);
-            }
-        }
-
-        public IResult<IElementContainer<IOperationDescription>> RetrieveOperations()
-        {
-            try
-            {
-                return new Result<IElementContainer<IOperationDescription>>(true, SubModel.Operations);
-            }
-            catch (Exception e)
-            {
-                return new Result<IElementContainer<IOperationDescription>>(e);
-            }
-        }
-
-        public IResult<IOperationDescription> RetrieveOperation(string operationId)
-        {
-            try
-            {
-                var operation = SubModel.Operations[operationId];
-                if (operation == null)
-                    throw new KeyNotFoundException("operationId not found");
-                return new Result<IOperationDescription>(true, operation);
-            }
-            catch (Exception e)
-            {
-                return new Result<IOperationDescription>(e);
-            }
-        }
-
-        public IResult DeleteOperation(string operationId)
-        {
-            try
-            {
-                var operation = SubModel.Operations[operationId];
-                if (operation == null)
-                    throw new KeyNotFoundException("operationId not found");
-                SubModel.Operations.Remove(operation);
-                return new Result(true);
-            }
-            catch (Exception e)
-            {
-                return new Result(e);
-            }
-        }
-
-        public IResult InvokeOperation(string operationId, List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout)
-        {
-            throw new NotImplementedException();
-        }
-
-        public IResult<IPropertyDescription> CreateProperty(IPropertyDescription property)
-        {
-            try
-            {
-                SubModel.Properties.Add(property);
-                return new Result<IPropertyDescription>(true, property);
-            }
-            catch (Exception e)
-            {
-                return new Result<IPropertyDescription>(e);
-            }
-        }
-
-        public IResult<IElementContainer<IPropertyDescription>> RetrieveProperties()
-        {
-            try
-            {
-                return new Result<IElementContainer<IPropertyDescription>>(true, SubModel.Properties);
-            }
-            catch (Exception e)
-            {
-                return new Result<IElementContainer<IPropertyDescription>>(e);
-            }
-        }
-
-        public IResult<IPropertyDescription> RetrieveProperty(string propertyId)
-        {
-            try
-            {
-                var property = SubModel.Properties[propertyId];
-                if (property == null)
-                    throw new KeyNotFoundException("propertyId not found");
-                return new Result<IPropertyDescription>(true, property);
-            }
-            catch (Exception e)
-            {
-                return new Result<IPropertyDescription>(e);
-            }
-        }
-
-        public IResult UpdateProperty(string propertyId, IValue value)
-        {
-            try
-            {
-                var property = SubModel.Properties[propertyId];
-                if (property == null)
-                    throw new KeyNotFoundException("propertyId not found");
-
-                SubModel.Properties[propertyId].Value = value;
-                return new Result<IValue>(true, value);
-            }
-            catch (Exception e)
-            {
-                return new Result(e);
-            }
-        }
-
-        public IResult DeleteProperty(string propertyId)
-        {
-            try
-            {
-                var property = SubModel.Properties[propertyId];
-                if (property == null)
-                    throw new KeyNotFoundException("propertyId not found");
-                SubModel.Properties.Remove(property);
-                return new Result(true);
-            }
-            catch (Exception e)
-            {
-                return new Result(e);
-            }
-        }
-
-        public IResult<IEventDescription> CreateEvent(IEventDescription eventable)
-        {
-            try
-            {
-                SubModel.Events.Add(eventable);
-                return new Result<IEventDescription>(true, eventable);
-            }
-            catch (Exception e)
-            {
-                return new Result<IEventDescription>(e);
-            }
-        }
-
-        public IResult<IElementContainer<IEventDescription>> RetrieveEvents()
-        {
-            try
-            {
-                return new Result<IElementContainer<IEventDescription>>(true, SubModel.Events);
-            }
-            catch (Exception e)
-            {
-                return new Result<IElementContainer<IEventDescription>>(e);
-            }
-        }
-
-        public IResult<IEventDescription> RetrieveEvent(string eventId)
-        {
-            try
-            {
-                var eventable = SubModel.Events[eventId];
-                if (eventable == null)
-                    throw new KeyNotFoundException("eventId not found");
-                return new Result<IEventDescription>(true, eventable);
-            }
-            catch (Exception e)
-            {
-                return new Result<IEventDescription>(e);
-            }
-        }
-
-        public IResult DeleteEvent(string eventId)
-        {
-            try
-            {
-                var eventable = SubModel.Events[eventId];
-                if (eventable == null)
-                    throw new KeyNotFoundException("eventId not found");
-                SubModel.Events.Remove(eventable);
-                return new Result(true);
-            }
-            catch (Exception e)
-            {
-                return new Result(e);
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Component.Loader/App.config b/sdks/csnet/BaSys40.Component.Loader/App.config
deleted file mode 100644
index 731f6de..0000000
--- a/sdks/csnet/BaSys40.Component.Loader/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<configuration>
-    <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
-    </startup>
-</configuration>
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Component.Loader/BaSys40.Component.Loader.csproj b/sdks/csnet/BaSys40.Component.Loader/BaSys40.Component.Loader.csproj
deleted file mode 100644
index e9e415a..0000000
--- a/sdks/csnet/BaSys40.Component.Loader/BaSys40.Component.Loader.csproj
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{2EB12FD0-435E-47B9-A8A4-6BDC3B2E1762}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>BaSys40.Component.Loader</RootNamespace>
-    <AssemblyName>BaSys40.Component.Loader</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
-    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup>
-    <StartupObject>BaSys40.Component.Loader.Program</StartupObject>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\BaSys40.API\BaSys40.API.csproj">
-      <Project>{ff2a5450-3904-4466-89ec-2ab915b1d516}</Project>
-      <Name>BaSys40.API</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\BaSys40.Models\BaSys40.Models.csproj">
-      <Project>{d6a23558-6cc3-4240-8d74-e520be7e319a}</Project>
-      <Name>BaSys40.Models</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\BaSys40.RI.AAS.SmartControl\BaSys40.RI.AAS.SmartControl.csproj">
-      <Project>{0E169503-1D59-4748-A932-2483C0CE465C}</Project>
-      <Name>BaSys40.RI.AAS.SmartControl</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\BaSys40.Technologies.oneM2M\BaSys40.Technologies.oneM2M.csproj">
-      <Project>{f0f9a5b5-123f-4c1f-863c-64da918dd89b}</Project>
-      <Name>BaSys40.Technologies.oneM2M</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\BaSys40.Utils\BaSys40.Utils.csproj">
-      <Project>{46b8719a-dcf3-433e-bd64-8936f7f5e623}</Project>
-      <Name>BaSys40.Utils</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Component.Loader/Program.cs b/sdks/csnet/BaSys40.Component.Loader/Program.cs
deleted file mode 100644
index 3b8608c..0000000
--- a/sdks/csnet/BaSys40.Component.Loader/Program.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using BaSys40.API.Components;
-using BaSys40.API.Platform;
-using BaSys40.RI.AAS.SmartControl;
-using BaSys40.Utils.Settings;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace BaSys40.Component.Loader
-{
-    public class Program
-    {
-        static DirectoryWatcher assemblyFolderWatcher;
-        static IAssetAdministrationShellRegistry registry;
-        static IAssetAdministrationShellManager manager;
-        static IAssetAdministrationShellHandler handler;
-
-        static Dictionary<string, CancellationTokenSource> updaters = new Dictionary<string, CancellationTokenSource>();
-        static void Main(string[] args)
-        {
-            Initialize();
-
-            string loaderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Loader");
-            var files = Directory.GetFiles(loaderPath);
-            foreach (var file in files)
-            {
-                LoadIComponentConnectorAssembly(file);
-            }
-
-            assemblyFolderWatcher = new DirectoryWatcher(loaderPath, "*.*", true, LoadIComponentConnectorAssembly);
-
-            while (!Console.KeyAvailable)
-            {
-                Console.Write("Type Q to quit application: ");
-                var key = Console.ReadLine();
-
-                if (key == "Q")
-                    Environment.Exit(0);
-            }
-        }
-
-        public static void Initialize()
-        {
-            registry = SmartControl.Instance;
-            manager = SmartControl.Instance;
-            handler = new SmartControlHandler(8544);
-        }
-
-        public static void LoadIComponentConnectorAssembly(string fullPath)
-        {
-            try
-            {
-                Console.WriteLine("New file detected: " + fullPath);
-                var assembly = Assembly.LoadFrom(fullPath);
-
-                var allTypes = assembly.GetTypes();
-                var types = (from type in allTypes
-                             where (type.GetInterfaces().Contains(typeof(IComponentConnector)) && !type.IsAbstract)
-                             select type).ToList();
-
-                foreach (var type in types)
-                {
-                    IComponentConnector instance = (IComponentConnector)Activator.CreateInstance(type);
-
-                    //retrieve AAS from component
-                    var aas = instance.GenerateAssetAdministrationShell();
-                    Console.WriteLine("AAS with Id '" + aas.Identification.Id + "' generated");
-
-                    //delete if AAS is already registered
-                    instance.Unregister(registry, aas.Identification.Id);
-
-                    //register AAS
-                    var registered = instance.Register(registry, aas);
-                    if(registered.Success)
-                        Console.WriteLine("Registered successfully");
-                    else
-                    {
-                        Console.WriteLine("Registration failed:");
-                        foreach (var message in registered.Messages)
-                            Console.WriteLine(message.ToString());
-                        
-                    }
-                    var created = instance.CreateStructure(manager, handler, aas);
-
-                    if (created.Success)
-                        Console.WriteLine("Created successfully");
-                    else
-                    {
-                        Console.WriteLine("Creation failed:");
-                        foreach (var message in created.Messages)
-                            Console.WriteLine(message.ToString());
-
-                        return;
-                    }
-                    updaters.Add(aas.Identification.Id, new CancellationTokenSource());
-                    Task.Factory.StartNew(async () =>
-                    {
-                        while (!updaters[aas.Identification.Id].IsCancellationRequested)
-                        {
-                            var exists = manager.RetrieveAssetAdministrationShell(aas.Identification.Id);
-                            if (!exists.Success || exists.Entity == null)
-                                instance.CreateStructure(manager, handler, aas);
-
-                            await Task.Delay(10000);
-                        }
-                    }, updaters[aas.Identification.Id].Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
-                }
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("Exception while loading assembly ': " + fullPath + "' - Message: " +e.Message);
-            }
-        }
-    }
-}
diff --git a/sdks/csnet/BaSys40.Component.Loader/Properties/AssemblyInfo.cs b/sdks/csnet/BaSys40.Component.Loader/Properties/AssemblyInfo.cs
deleted file mode 100644
index 7af197f..0000000
--- a/sdks/csnet/BaSys40.Component.Loader/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("BaSys40.Devices")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("BOSCH")]
-[assembly: AssemblyProduct("BaSys40.Devices")]
-[assembly: AssemblyCopyright("Copyright © BOSCH 2018")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components.  If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("2eb12fd0-435e-47b9-a8a4-6bdc3b2e1762")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/sdks/csnet/BaSys40.Component.REST.Client/BaSys40.Component.REST.Client.csproj b/sdks/csnet/BaSys40.Component.REST.Client/BaSys40.Component.REST.Client.csproj
new file mode 100644
index 0000000..fc7c6f7
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST.Client/BaSys40.Component.REST.Client.csproj
@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Library</OutputType>
+    <TargetFramework>netstandard2.0</TargetFramework>
+    <ApplicationIcon />
+    <StartupObject />
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugType>full</DebugType>
+  </PropertyGroup>
+  
+  <ItemGroup>
+    <PackageReference Include="NLog" Version="4.5.11" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\BaSys40.API\BaSys40.API.csproj" />
+    <ProjectReference Include="..\BaSys40.Utils\BaSys40.Utils.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/sdks/csnet/BaSys40.Component.REST.Client/RestClient.cs b/sdks/csnet/BaSys40.Component.REST.Client/RestClient.cs
new file mode 100644
index 0000000..9b6b1c6
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST.Client/RestClient.cs
@@ -0,0 +1,196 @@
+using BaSys40.API.Platform.Agents;
+using BaSys40.API.ServiceProvider;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Models.Extensions;
+using BaSys40.Utils.Client.Http;
+using BaSys40.Utils.ResultHandling;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+
+namespace BaSys40.Component.REST.Client
+{
+    public class RestClient : SimpleHttpClient    
+    {
+        private const string AAS = "aas";
+        private const string SUBMODELS = "submodels";
+        private const string DATAELEMENTS = "dataElements";
+        private const string OPERATIONS = "operations";
+        private const string EVENTS = "events";
+        private const string VALUE = "value";
+
+        private const string SEPERATOR = "/";
+        private const int TIMEOUT = 30000;
+
+        public IPEndPoint Endpoint { get; }
+
+        public RestClient(IPEndPoint endPoint)
+        {
+            Endpoint = endPoint;
+            JsonSerializerSettings = new JsonStandardSettings();
+        }
+
+        public Uri GetUri(params string[] pathElements)
+        {
+            string path = "http://" + Endpoint.Address + ":" + Endpoint.Port + SEPERATOR + AAS;
+
+            if (pathElements?.Length > 0)
+                foreach (var pathElement in pathElements)
+                {
+                    if (!pathElement.EndsWith("/") && !pathElement.StartsWith("/"))
+                        path = path + SEPERATOR + pathElement;
+                    else
+                        path = path + pathElement;
+                }
+            return new Uri(path);
+        }
+
+        public IResult<IAssetAdministrationShell> RetrieveAssetAdministrationShell()
+        {
+            var request = base.CreateRequest(GetUri(), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<IAssetAdministrationShell>(response, response.Entity);
+        }
+
+        public IResult<ISubmodel> CreateSubmodel(ISubmodel submodel)
+        {
+            var request = base.CreateJsonContentRequest(GetUri(SUBMODELS), HttpMethod.Post, submodel);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<ISubmodel>(response, response.Entity);
+        }
+
+        public IResult<ElementContainer<ISubmodel>> RetrieveSubmodels()
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<ElementContainer<ISubmodel>>(response, response.Entity);
+        }
+
+        public IResult<ISubmodel> RetrieveSubmodel(string submodelId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<ISubmodel>(response, response.Entity);
+        }
+
+        public IResult DeleteSubmodel(string submodelId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId), HttpMethod.Delete);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse(response, response.Entity);
+        }
+
+        public IResult<IOperation> CreateOperation(string submodelId, IOperation operation)
+        {
+            var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, OPERATIONS), HttpMethod.Post, operation);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<IOperation>(response, response.Entity);
+        }
+
+        public IResult<ElementContainer<IOperation>> RetrieveOperations(string submodelId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, OPERATIONS), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<ElementContainer<IOperation>>(response, response.Entity);
+        }
+
+        public IResult<IOperation> RetrieveOperation(string submodelId, string operationId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, OPERATIONS, operationId), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<IOperation>(response, response.Entity);
+        }
+
+        public IResult DeleteOperation(string submodelId, string operationId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, OPERATIONS, operationId), HttpMethod.Delete);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse(response, response.Entity);
+        }
+
+        public IResult InvokeOperation(string submodelId, string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout)
+        {
+            var uri = GetUri(SUBMODELS, submodelId, OPERATIONS, operationId);
+            var requestUri = new Uri(uri.OriginalString + "?timeout=" + timeout);
+            var request = base.CreateJsonContentRequest(requestUri, HttpMethod.Post, inputArguments);
+            var response = base.SendRequest(request, TIMEOUT);
+            var evaluatedResponse = base.EvaluateResponse(response, response.Entity);
+            outputArguments = evaluatedResponse.GetEntity<List<IArgument>>();
+            return evaluatedResponse;
+        }
+
+        public IResult<IDataElement> CreateDataElement(string submodelId, IDataElement dataElement)
+        {
+            var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, DATAELEMENTS), HttpMethod.Post, dataElement);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<IDataElement>(response, response.Entity);
+        }
+
+        public IResult<ElementContainer<IDataElement>> RetrieveDataElements(string submodelId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, DATAELEMENTS), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<ElementContainer<IDataElement>>(response, response.Entity);
+        }
+
+        public IResult<IDataElement> RetrieveDataElement(string submodelId, string dataElementId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, DATAELEMENTS, dataElementId), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<IDataElement>(response, response.Entity);
+        }
+
+        public IResult UpdateDataElementValue(string submodelId, string dataElementId, IValue value)
+        {
+            var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, DATAELEMENTS, dataElementId, VALUE), HttpMethod.Put, value);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse(response, response.Entity);
+        }
+
+        public IResult<IValue> RetrieveDataElementValue(string submodelId, string dataElementId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, DATAELEMENTS, dataElementId, VALUE), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<IValue>(response, response.Entity);
+        }
+
+        public IResult DeleteDataElement(string submodelId, string dataElementId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, DATAELEMENTS, dataElementId), HttpMethod.Delete);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse(response, response.Entity);
+        }
+
+        public IResult<IEvent> CreateEvent(string submodelId, IEvent eventable)
+        {
+            var request = base.CreateJsonContentRequest(GetUri(SUBMODELS, submodelId, EVENTS), HttpMethod.Post, eventable);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<IEvent>(response, response.Entity);
+        }
+
+        public IResult<ElementContainer<IEvent>> RetrieveEvents(string submodelId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, EVENTS), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<ElementContainer<IEvent>>(response, response.Entity);
+        }
+
+        public IResult<IEvent> RetrieveEvent(string submodelId, string eventId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, EVENTS, eventId), HttpMethod.Get);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse<IEvent>(response, response.Entity);
+        }
+
+        public IResult DeleteEvent(string submodelId, string eventId)
+        {
+            var request = base.CreateRequest(GetUri(SUBMODELS, submodelId, EVENTS, eventId), HttpMethod.Delete);
+            var response = base.SendRequest(request, TIMEOUT);
+            return base.EvaluateResponse(response, response.Entity);
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Component.REST/AAS_Icon.ico b/sdks/csnet/BaSys40.Component.REST/AAS_Icon.ico
new file mode 100644
index 0000000..d0827f3
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/AAS_Icon.ico
Binary files differ
diff --git a/sdks/csnet/BaSys40.Component.REST/BaSys40.Component.REST.csproj b/sdks/csnet/BaSys40.Component.REST/BaSys40.Component.REST.csproj
new file mode 100644
index 0000000..0dcf1a3
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/BaSys40.Component.REST.csproj
@@ -0,0 +1,67 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
+    <ApplicationIcon>AAS_Icon.ico</ApplicationIcon>
+    <OutputType>Exe</OutputType>
+    <StartupObject />
+    <Configurations>Debug;Release</Configurations>
+    <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
+  </PropertyGroup>
+  
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <DocumentationFile>bin\Release\netcoreapp2.2\BaSys40.Component.REST.xml</DocumentationFile>
+  </PropertyGroup>
+  
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DocumentationFile>bin\Debug\netcoreapp2.2\BaSys40.Component.REST.xml</DocumentationFile>
+    <DefineConstants>TRACE;DEBUG</DefineConstants>
+    <OutputPath>bin\Debug\</OutputPath>
+  </PropertyGroup>
+  
+  
+ <ItemGroup>
+   <None Remove="ServerSettings.xml" />
+ </ItemGroup>
+  
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Rewrite" Version="2.2.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Server.HttpSys" Version="2.2.0" />
+    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.0" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.1" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.0">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+    </PackageReference>
+    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.1.0" />
+    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.0" />
+    <PackageReference Include="NLog.Config" Version="4.5.11" />
+    <PackageReference Include="NLog.Web.AspNetCore" Version="4.8.0" />
+    <PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
+    <PackageReference Include="System.IO.Ports" Version="4.5.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Include="ServerSettings.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </EmbeddedResource>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\BaSys40.API\BaSys40.API.csproj" />
+    <ProjectReference Include="..\BaSys40.Models\BaSys40.Models.csproj" />
+    <ProjectReference Include="..\BaSys40.Utils\BaSys40.Utils.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Folder Include="wwwroot\" />
+  </ItemGroup>
+
+</Project>
diff --git a/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/AssetAdministrationShellAggregatorServices.cs b/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/AssetAdministrationShellAggregatorServices.cs
new file mode 100644
index 0000000..9b9eb5d
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/AssetAdministrationShellAggregatorServices.cs
@@ -0,0 +1,195 @@
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Mvc;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Utils.ResultHandling;
+using static BaSys40.Utils.ResultHandling.Utils;
+using BaSys40.API.ServiceProvider;
+using BaSys40.Models.Connectivity;
+
+namespace BaSys40.Component.REST.Controllers
+{
+    /// <summary>
+    /// All Asset Administration Shell Services provided by the component
+    /// </summary>
+    public class AssetAdministrationShellAggregatorServices : Controller, IAssetAdministrationShellAggregatorServiceProvider
+    {
+
+        private readonly IAssetAdministrationShellAggregatorServiceProvider aggregator;
+
+        public IEnumerable<IAssetAdministrationShell> AssetAdministrationShells => aggregator.AssetAdministrationShells;
+        public IServiceDescriptor ServiceDescriptor { get; }
+
+
+        public AssetAdministrationShellAggregatorServices(IAssetAdministrationShellAggregatorServiceProvider assetAdministrationShellAggregatorServiceProvider)
+        {
+            aggregator = assetAdministrationShellAggregatorServiceProvider;
+            ServiceDescriptor = assetAdministrationShellAggregatorServiceProvider.ServiceDescriptor;
+        }
+
+        #region REST-Interface AssetAdministrationShellAggregator
+
+        /// <summary>
+        /// Retrieves all Asset Administration Shells from the endpoint
+        /// </summary>
+        /// <returns></returns>
+        /// <response code="200">Returns a list of found Asset Administration Shells</response>
+        /// <response code="404">No Asset Administration Shells found</response>            
+        /// <response code="400">Bad Request</response>    
+        /// <response code="502">Bad Gateway</response>
+        [HttpGet("aasList", Name = "RetrieveAASList")]
+        [ProducesResponseType(typeof(IResult<List<IAssetAdministrationShell>>), 200)]
+        public IActionResult RetrieveAASList()
+        {
+            var result = RetrieveAssetAdministrationShells();
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+        /// <summary>
+        /// Retrieves a specific Asset Administration Shell
+        /// </summary>
+        /// <param name="aasId">The AAS's unique id</param>
+        /// <returns></returns>
+        /// <response code="200">Returns the requested Asset Administration Shell</response>
+        /// <response code="404">No Asset Administration Shell found</response>     
+        /// <response code="400">Bad Request</response>         
+        /// <response code="502">Bad Gateway</response>
+        [HttpGet("aasList/{aasId}", Name = "RetrieveAAS")]
+        [ProducesResponseType(typeof(IResult<IAssetAdministrationShell>), 200)]
+        public IActionResult RetrieveAAS(string aasId)
+        {
+            var result = RetrieveAssetAdministrationShell(aasId);
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+        /// <summary>
+        /// Updates a specific Asset Administration Shell
+        /// </summary>
+        /// <param name="aasId">The AAS's unique id</param>
+        /// <param name="aas">The updated AAS</param>
+        /// <returns></returns>
+        /// <response code="204">Asset Administration Shell updated successfully</response>
+        /// <response code="400">Bad Request</response>           
+        /// <response code="502">Bad Gateway</response>   
+        [HttpPut("aasList/{aasId}", Name = "UpdateAAS")]
+        [ProducesResponseType(typeof(IResult), 204)]
+        public IActionResult UpdateAAS(string aasId, [FromBody] IAssetAdministrationShell aas)
+        {
+            var result = UpdateAssetAdministrationShell(aasId, aas);
+            return EvaluateResult(result, CrudOperation.Update);
+        }
+        /// <summary>
+        /// Creates a new Asset Administration Shell at the endpoint
+        /// </summary>
+        /// <param name="aas">The AAS's description object</param>
+        /// <returns></returns>
+        /// <response code="201">Asset Administration Shell created successfully</response>
+        /// <response code="400">Bad Request</response>             
+        /// <response code="502">Bad Gateway</response> 
+        [HttpPost("aasList", Name = "CreateAAS")]
+        [ProducesResponseType(typeof(IResult<IAssetAdministrationShell>), 201)]
+        public IActionResult CreateAAS([FromBody] IAssetAdministrationShell aas)
+        {
+            var result = CreateAssetAdministrationShell(aas);
+            return EvaluateResult(result, CrudOperation.Create);
+        }
+        /// <summary>
+        /// Deletes a specific Asset Administration Shell
+        /// </summary>
+        /// <param name="aasId">The AAS's unique id</param>
+        /// <returns></returns>
+        /// <response code="204">Asset Administration Shell deleted successfully</response>
+        /// <response code="400">Bad Request</response>      
+        /// <response code="502">Bad Gateway</response>
+        [HttpDelete("aasList/{aasId}", Name = "DeleteAAS")]
+        [ProducesResponseType(typeof(IResult), 204)]
+        public IActionResult DeleteAAS(string aasId)
+        {
+            var result = DeleteAssetAdministrationShell(aasId);
+            return EvaluateResult(result, CrudOperation.Delete);
+        }
+
+        #endregion
+
+
+        #region Interface Implementation AssetAdministrationShellAggregator
+
+        #endregion
+        #region Helper Methods
+
+        private static IActionResult AggregateResultHandling(IResult result)
+        {
+            if (result != null)
+            {
+                var objResult = new ObjectResult(result);
+
+                if (result.Success)
+                {
+                    if (result.Entity == null)
+                        objResult.StatusCode = 404;
+                    else
+                        objResult.StatusCode = 200;
+                }
+                else if (Utils.ResultHandling.Utils.TryParseStatusCode(result, out int httpStatusCode))
+                    objResult.StatusCode = httpStatusCode;
+                else
+                    objResult.StatusCode = 502;
+
+                return objResult;
+            }
+            return new BadRequestResult();
+        }
+
+        public void RegisterAssetAdministrationShellServiceProvider(string id, IAssetAdministrationShellServiceProvider assetAdministrationShellServiceProvider)
+        {
+            aggregator.RegisterAssetAdministrationShellServiceProvider(id, assetAdministrationShellServiceProvider);
+        }
+
+        public IAssetAdministrationShellServiceProvider GetAssetAdministrationShellServiceProvider(string id)
+        {
+            return aggregator.GetAssetAdministrationShellServiceProvider(id);
+        }
+
+        public IEnumerable<IAssetAdministrationShellServiceProvider> GetAssetAdministrationShellServiceProviders()
+        {
+            return aggregator.GetAssetAdministrationShellServiceProviders();
+        }
+
+        public void BindTo(IEnumerable<IAssetAdministrationShell> element)
+        {
+            aggregator.BindTo(element);
+        }
+
+        public IEnumerable<IAssetAdministrationShell> GetBinding()
+        {
+            return aggregator.GetBinding();
+        }
+
+        public IResult<IAssetAdministrationShell> CreateAssetAdministrationShell(IAssetAdministrationShell aas)
+        {
+            return aggregator.CreateAssetAdministrationShell(aas);
+        }
+
+        public IResult<IAssetAdministrationShell> RetrieveAssetAdministrationShell(string aasId)
+        {
+            return aggregator.RetrieveAssetAdministrationShell(aasId);
+        }
+
+        public IResult<List<IAssetAdministrationShell>> RetrieveAssetAdministrationShells()
+        {
+            return aggregator.RetrieveAssetAdministrationShells();
+        }
+
+        public IResult UpdateAssetAdministrationShell(string aasId, IAssetAdministrationShell aas)
+        {
+            return aggregator.UpdateAssetAdministrationShell(aasId, aas);
+        }
+
+        public IResult DeleteAssetAdministrationShell(string aasId)
+        {
+            return aggregator.DeleteAssetAdministrationShell(aasId);
+        }
+
+
+
+
+        #endregion
+    }
+}
diff --git a/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/AssetAdministrationShellServices.cs b/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/AssetAdministrationShellServices.cs
new file mode 100644
index 0000000..929541b
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/AssetAdministrationShellServices.cs
@@ -0,0 +1,191 @@
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Mvc;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Utils.ResultHandling;
+using BaSys40.API.ServiceProvider;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Models.Core.AssetAdministrationShell;
+using BaSys40.Models.Connectivity;
+using static BaSys40.Utils.ResultHandling.Utils;
+using System.Linq;
+
+namespace BaSys40.Component.REST.Controllers
+{
+    /// <summary>
+    /// All Asset Administration Shell Services provided by the component
+    /// </summary>
+    public class AssetAdministrationShellServices : Controller, IAssetAdministrationShellServiceProvider
+    {
+        private readonly IAssetAdministrationShellServiceProvider assetAdministrationShellServiceProvider;
+
+        public IServiceDescriptor ServiceDescriptor { get; }
+
+        public IAssetAdministrationShell AssetAdministrationShell => assetAdministrationShellServiceProvider.GetBinding();
+
+        public AssetAdministrationShellServices(IAssetAdministrationShellServiceProvider assetAdministrationShellServiceProvider)
+        {
+            this.assetAdministrationShellServiceProvider = assetAdministrationShellServiceProvider;
+            ServiceDescriptor = assetAdministrationShellServiceProvider.ServiceDescriptor;
+        }
+
+        public void BindTo(IAssetAdministrationShell element)
+        {
+            assetAdministrationShellServiceProvider.BindTo(element);
+        }
+        public IAssetAdministrationShell GetBinding()
+        {
+            return assetAdministrationShellServiceProvider.GetBinding();
+        }
+
+
+        #region REST-Interface AssetAdministrationShell
+
+        /// <summary>
+        /// Retrieves the Asset Administration Shell
+        /// </summary>
+        /// <returns></returns>
+        /// <response code="200">Success</response>
+        /// <response code="502">Bad Gateway - Asset Administration Shell not available</response>       
+        [HttpGet("aas", Name = "GetAAS")]
+        [ProducesResponseType(typeof(Result<AssetAdministrationShellDescriptor>), 200)]
+        public IActionResult GetAAS()
+        {
+            var result = GetBinding();
+            if (result != null)
+            {
+                var objResult = new ObjectResult(new Result<AssetAdministrationShellDescriptor>(true, new AssetAdministrationShellDescriptor(result, GetEndpoint())));
+                return objResult;
+            }
+            return StatusCode(502);
+        }
+
+        public HttpEndpoint GetEndpoint()
+        {
+            var host = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}";
+            return new HttpEndpoint(host);
+        }
+
+        #region Submodel - REST-Calls
+        /// <summary>
+        /// Adds a new Submodel to an existing Asset Administration Shell
+        /// </summary>
+        /// <param name="submodel">The Submodel's description object</param>
+        /// <returns></returns>
+        /// <response code="201">Submodel created successfully</response>
+        /// <response code="400">Bad Request</response>       
+        /// <response code="502">Bad Gateway</response>
+        [HttpPost("aas/submodels", Name = "PostSubmodel")]
+        [ProducesResponseType(typeof(IResult<ISubmodel>), 201)]
+        public IActionResult PostSubmodel([FromBody] ISubmodel submodel)
+        {
+            var result = CreateSubmodel(submodel);
+            return EvaluateResult(result, CrudOperation.Create);
+        }
+        /// <summary>
+        /// Retrieves a specific Submodel from a specific Asset Administration Shell
+        /// </summary>
+        /// <param name="submodelId">The Submodel's unique id</param>
+        /// <returns></returns>
+        /// <response code="200">Submodel retrieved successfully</response>
+        /// <response code="404">No Submodel found</response>    
+        /// <response code="502">Bad Gateway</response> 
+        [HttpGet("aas/submodels/{submodelId}", Name = "GetSubmodelServiceProviderBinding")]
+        [ProducesResponseType(typeof(IResult<ISubmodel>), 200)]
+        public IActionResult GetSubmodelServiceProviderBinding(string submodelId)
+        {
+            var submodelProvider = GetSubmodelServiceProvider(submodelId);
+
+            if (submodelProvider == null)
+                return NotFound(new Result(false, new Message(MessageType.Information, "Submodel not found", "404")));
+
+            return new OkObjectResult(new Result<ISubmodel>(true, submodelProvider.GetBinding()));
+        }
+        /// <summary>
+        /// Deletes a specific Submodel from the Asset Administration Shell
+        /// </summary>
+        /// <param name="submodelId">The Submodel's idShort</param>
+        /// <returns></returns>
+        /// <response code="204">Submodel deleted successfully</response>
+        /// <response code="400">Bad Request</response>    
+        /// <response code="502">Bad Gateway</response>
+        [HttpDelete("aas/submodels/{submodelId}", Name = "DelSubmodel")]
+        [ProducesResponseType(typeof(IResult), 204)]
+        public IActionResult DelSubmodel(string submodelId)
+        {
+            var result = DeleteSubmodel(submodelId);
+            return EvaluateResult(result, CrudOperation.Delete);
+        }
+        /// <summary>
+        /// Retrieves all Submodels from the current Asset Administration Shell
+        /// </summary>
+        /// <returns></returns>
+        /// <response code="200">Returns a list of found Submodels</response>
+        /// <response code="404">No Submodels found</response>      
+        /// <response code="502">Bad Gateway</response>   
+        [HttpGet("aas/submodels", Name = "GetSubmodels")]
+        [ProducesResponseType(typeof(IResult<ElementContainer<ISubmodel>>), 200)]
+        public IActionResult GetSubmodels()
+        {
+            var submodelProviders = GetSubmodelServiceProviders();
+
+            if (submodelProviders?.Count() == 0)
+                return NotFound(new Result(false, new Message(MessageType.Information, "No Submodels found", "404")));
+
+            ElementContainer<ISubmodel> submodels = new ElementContainer<ISubmodel>();
+            foreach (var provider in submodelProviders)
+            {
+                var submodel = provider.GetBinding();
+                submodels.Add(submodel);
+            }
+            return new OkObjectResult(new Result<ElementContainer<ISubmodel>>(true, submodels));
+        }
+
+        #endregion
+
+        #endregion
+
+        #region Interface Implementation AssetAdministrationShellServiceProvider
+
+        public void RegisterSubmodelServiceProvider(string id, ISubmodelServiceProvider submodelServiceProvider)
+        {
+            assetAdministrationShellServiceProvider.RegisterSubmodelServiceProvider(id, submodelServiceProvider);
+        }
+
+        public ISubmodelServiceProvider GetSubmodelServiceProvider(string id)
+        {
+            return assetAdministrationShellServiceProvider.GetSubmodelServiceProvider(id);
+        }
+
+        public IResult<ISubmodel> CreateSubmodel(ISubmodel submodel)
+        {
+            return assetAdministrationShellServiceProvider.CreateSubmodel(submodel);
+        }
+
+        public IResult<ISubmodel> RetrieveSubmodel(string submodelId)
+        {
+            return assetAdministrationShellServiceProvider.RetrieveSubmodel(submodelId);
+        }
+
+        public IResult<ElementContainer<ISubmodel>> RetrieveSubmodels()
+        {
+            return assetAdministrationShellServiceProvider.RetrieveSubmodels();
+        }
+
+        public IResult DeleteSubmodel(string submodelId)
+        {
+            return assetAdministrationShellServiceProvider.DeleteSubmodel(submodelId);
+        }
+
+        public IEnumerable<ISubmodelServiceProvider> GetSubmodelServiceProviders()
+        {
+            return assetAdministrationShellServiceProvider.GetSubmodelServiceProviders();
+        }
+
+        #endregion
+
+        #region Helper Methods
+
+
+        #endregion
+    }
+}
diff --git a/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/SubmodelServices.cs b/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/SubmodelServices.cs
new file mode 100644
index 0000000..14ac130
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Controllers/AssetAdministrationShell/SubmodelServices.cs
@@ -0,0 +1,462 @@
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Mvc;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Utils.ResultHandling;
+using BaSys40.API.ServiceProvider;
+using static BaSys40.Utils.ResultHandling.Utils;
+using BaSys40.Utils.Client;
+using System;
+using BaSys40.API.AssetAdministrationShell;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Models.Connectivity;
+
+namespace BaSys40.Component.REST.Controllers
+{
+    /// <summary>
+    /// All Asset Administration Shell Services provided by the component
+    /// </summary>
+    public class SubmodelServices : Controller, ISubmodelServiceProvider
+    {
+        private readonly ISubmodelServiceProvider submodelServiceProvider;
+
+        public ISubmodel Submodel => submodelServiceProvider.GetBinding();
+        public IServiceDescriptor ServiceDescriptor { get; }
+
+        public SubmodelServices(ISubmodelServiceProvider submodelServiceProvider)
+        {
+            this.submodelServiceProvider = submodelServiceProvider;
+            ServiceDescriptor = submodelServiceProvider.ServiceDescriptor;
+        }
+
+        public void BindTo(ISubmodel element)
+        {
+            submodelServiceProvider.BindTo(element);
+        }
+        public ISubmodel GetBinding()
+        {
+            return submodelServiceProvider.GetBinding();
+        }
+
+
+        #region REST-Interface Submodel
+
+        /// <summary>
+        /// Retrieves the Submodel
+        /// </summary>
+        /// <returns></returns>
+        /// <response code="200">Success</response>
+        /// <response code="502">Bad Gateway - Submodel not available</response>       
+        [HttpGet("submodel", Name = "GetSubmodel")]
+        [ProducesResponseType(typeof(IResult<ISubmodel>), 200)]
+        public IActionResult GetSubmodel()
+        {
+            var result = submodelServiceProvider.GetBinding();
+            if (result != null)
+                return new OkObjectResult(new Result<ISubmodel>(true, result));
+
+            return StatusCode(502);
+        }
+
+        /// <summary>
+        /// Retrieves all DataElements from the current Submodel
+        /// </summary>
+        /// <returns></returns>
+        /// <response code="200">Returns a list of found DataElements</response>
+        /// <response code="404">Submodel not found / No DataElements found</response>      
+        /// <response code="502">Bad Gateway</response>   
+        [HttpGet("submodel/dataElements", Name = "GetDataElements")]
+        [ProducesResponseType(typeof(IResult<ElementContainer<IDataElement>>), 200)]
+        public IActionResult GetDataElements(string submodelId)
+        {
+            var result = RetrieveDataElements();
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+
+        /// <summary>
+        /// Retrieves all Operations from the current Submodel
+        /// </summary>
+        /// <returns></returns>
+        /// <response code="200">Success</response>
+        /// <response code="404">Submodel not found / No Operations found</response>      
+        /// <response code="502">Bad Gateway</response>   
+        [HttpGet("submodel/operations", Name = "GetOperations")]
+        [ProducesResponseType(typeof(IResult<ElementContainer<IOperation>>), 200)]
+        public IActionResult GetOperations(string submodelId)
+        {
+            var result = RetrieveOperations();
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+
+        /// <summary>
+        /// Retrieves all Events from the current Submodel
+        /// </summary>
+        /// <returns></returns>
+        /// <response code="200">Success</response>
+        /// <response code="404">Submodel not found / No Events found</response>      
+        /// <response code="502">Bad Gateway</response>   
+        [HttpGet("submodel/events", Name = "GetEvents")]
+        [ProducesResponseType(typeof(IResult<ElementContainer<IEvent>>), 200)]
+        public IActionResult GetEvents(string submodelId)
+        {
+            var result = RetrieveEvents();
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+
+
+
+        #region DataElement - REST-Calls
+        /// <summary>
+        /// Adds a new DataElement to the Asset Administration Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="dataElement">The DataElement's description object</param>
+        /// <returns></returns>
+        /// <response code="201">DataElement created successfully</response>
+        /// <response code="400">Bad Request</response>
+        /// <response code="404">Submodel not found</response>
+        /// <response code="502">Bad Gateway</response>
+        [HttpPost("submodel/dataElements", Name = "PostDataElement")]
+        [ProducesResponseType(typeof(IResult<IDataElement>), 201)]
+        public IActionResult PostDataElement(string submodelId, [FromBody] IDataElement dataElement)
+        {
+            var result = CreateDataElement(dataElement);
+            return EvaluateResult(result, CrudOperation.Create);
+        }
+        /// <summary>
+        /// Retrieves a specific DataElement from the Asset Administrations's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="dataElementId">The DataElement's short id</param>
+        /// <returns></returns>
+        /// <response code="200">Returns the requested DataElement</response>
+        /// <response code="404">Submodel/DataElement not found</response>     
+        /// <response code="502">Bad Gateway</response>
+        [HttpGet("submodel/dataElements/{dataElementId}", Name = "GetDataElement")]
+        [ProducesResponseType(typeof(IResult<IDataElement>), 200)]
+        public IActionResult GetDataElement(string submodelId, string dataElementId)
+        {
+            var result = RetrieveDataElement(dataElementId);
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+
+        /// <summary>
+        /// Retrieves the value of a specific DataElement from the Asset Administrations Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="dataElementId">The DataElement's short id</param>
+        /// <returns></returns>
+        /// <response code="200">Returns the requested DataElement's value</response>
+        /// <response code="404">Submodel/DataElement not found</response>     
+        /// <response code="502">Bad Gateway</response>
+        [HttpGet("submodel/dataElements/{dataElementId}/value", Name = "GetDataElementValue")]
+        [ProducesResponseType(typeof(IResult<IValue>), 200)]
+        public IActionResult GetDataElementValue(string submodelId, string dataElementId)
+        {
+            var result = RetrieveDataElementValue(dataElementId);
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+
+        /// <summary>
+        /// Updates the Asset Administration Shell's Submodel's DataElement
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="dataElementId">The DataElement's short id</param>
+        /// <param name="value">The new value</param>
+        /// <returns></returns>
+        /// <response code="204">DataElement's value changed successfully</response>
+        /// <response code="404">Submodel/DataElement not found</response>     
+        /// <response code="502">Bad Gateway</response>
+        [HttpPut("submodel/dataElements/{dataElementId}/value", Name = "PutDataElementValue")]
+        [ProducesResponseType(typeof(IResult), 204)]
+        public IActionResult PutDataElementValue(string submodelId, string dataElementId, [FromBody] IValue value)
+        {
+            var result = UpdateDataElementValue(dataElementId, value);
+            return EvaluateResult(result, CrudOperation.Update);
+        }
+        /// <summary>
+        /// Deletes a specific DataElement from the Asset Administration Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="dataElementId">The DataElement's short id</param>
+        /// <returns></returns>
+        /// <response code="204">DataElement deleted successfully</response>
+        /// <response code="400">Bad Request</response> 
+        /// <response code="404">Submodel not found</response>
+        /// <response code="502">Bad Gateway</response>
+        [HttpDelete("submodel/dataElements/{dataElementId}", Name = "DelDataElement")]
+        [ProducesResponseType(typeof(IResult), 204)]
+        public IActionResult DelDataElement(string submodelId, string dataElementId)
+        {
+            var result = DeleteDataElement(dataElementId);
+            return EvaluateResult(result, CrudOperation.Delete);
+        }
+        #endregion
+        #region Operation - REST-Calls
+        /// <summary>
+        /// Adds a new operation to the Asset Administraiton Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="operation">The operation description object</param>
+        /// <returns></returns>
+        /// <response code="201">Operation created successfully</response>
+        /// <response code="400">Bad Request</response>
+        /// <response code="404">Submodel not found</response>
+        /// <response code="502">Bad Gateway</response>
+        [HttpPost("submodel/operations", Name = "PostOperation")]
+        [ProducesResponseType(typeof(IResult<IOperation>), 201)]
+        public IActionResult PostOperation(string submodelId, [FromBody] IOperation operation)
+        {
+            var result = CreateOperation(operation);
+            return EvaluateResult(result, CrudOperation.Create);
+        }
+        /// <summary>
+        /// Retrieves a specific Operation from the Asset Administration Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="operationId">The Operation's short id</param>
+        /// <returns></returns>
+        /// <response code="200">Success</response>
+        /// <response code="404">Submodel/Operation not found</response>     
+        /// <response code="502">Bad Gateway</response>
+        [HttpGet("submodel/operations/{operationId}", Name = "GetOperation")]
+        [ProducesResponseType(typeof(IResult<IOperation>), 200)]
+        public IActionResult GetOperation(string submodelId, string operationId)
+        {
+            var result = RetrieveOperation(operationId);
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+        /// <summary>
+        /// Deletes a specific Operation from the Asset Administration Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="operationId">The Operation's short id</param>
+        /// <returns></returns>
+        /// <response code="204">Operation deleted successfully</response>
+        /// <response code="400">Bad Request</response>    
+        /// <response code="404">Submodel not found</response>
+        /// <response code="502">Bad Gateway</response>
+        [HttpDelete("submodel/operations/{operationId}", Name = "DelOperation")]
+        [ProducesResponseType(typeof(IResult), 204)]
+        public IActionResult DelOperation(string submodelId, string operationId)
+        {
+            var result = DeleteOperation(operationId);
+            return EvaluateResult(result, CrudOperation.Delete);
+        }
+        /// <summary>
+        /// Invokes a specific operation from the Asset Administration Shell' Submodel with a list of input parameters 
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="operationId">The operation's short id</param>
+        /// <param name="timeout">Timeout for the operation to finish</param>
+        /// <param name="inputArguments">List of input arguments</param>
+        /// <returns></returns>
+        /// <response code="200">Operation invoked successfully</response>
+        /// <response code="400">Bad Request</response>
+        /// <response code="404">Submodel not found</response>
+        /// <response code="502">Bad Gateway</response>
+        [HttpPost("submodel/operations/{operationId}", Name = "InvokeOperationRest")]
+        [ProducesResponseType(typeof(IResult<List<IArgument>>), 200)]
+        public IActionResult InvokeOperationRest(string submodelId, string operationId, [FromQuery] int timeout, [FromBody] List<IArgument> inputArguments)
+        {
+            List<IArgument> outputArguments = new List<IArgument>();
+            IResult result = InvokeOperation(operationId, inputArguments, outputArguments, timeout);
+
+            if (result != null)
+            {
+                var objResult = new ObjectResult(new Result<List<IArgument>>(result.Success, outputArguments, result.Messages));
+
+                if (result.Success)
+                    objResult.StatusCode = 200;
+                else if (Utils.ResultHandling.Utils.TryParseStatusCode(result, out int httpStatusCode))
+                    objResult.StatusCode = httpStatusCode;
+                else
+                    objResult.StatusCode = 502;
+
+                return objResult;
+            }
+            return StatusCode(502);
+        }
+
+        #endregion
+        #region Event - REST-Calls
+        /// <summary>
+        /// Adds a new event to the Asset Administration Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="eventable">The Event description object</param>
+        /// <returns></returns>
+        /// <response code="201">Event created successfully</response>
+        /// <response code="400">Bad Request</response>
+        /// <response code="404">Submodel not found</response>
+        /// <response code="502">Bad Gateway</response>
+        [HttpPost("submodel/events", Name = "PostEvent")]
+        [ProducesResponseType(typeof(IResult<IEvent>), 201)]
+        public IActionResult PostEvent(string submodelId, [FromBody] IEvent eventable)
+        {
+            var result = CreateEvent(eventable);
+            return EvaluateResult(result, CrudOperation.Create);
+        }
+        /// <summary>
+        /// Retrieves a specific event from the Asset Administration Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="eventId">The Event's short id</param>
+        /// <returns></returns>
+        /// <response code="200">Success</response>
+        /// <response code="404">Submodel/Event not found</response>     
+        /// <response code="502">Bad Gateway</response>
+        [HttpGet("submodel/events/{eventId}", Name = "GetEvent")]
+        [ProducesResponseType(typeof(IResult<IEvent>), 200)]
+        public IActionResult GetEvent(string submodelId, string eventId)
+        {
+            var result = RetrieveEvent(eventId);
+            return EvaluateResult(result, CrudOperation.Retrieve);
+        }
+        /// <summary>
+        /// Deletes a specific event from the Asset Administration Shell's Submodel
+        /// </summary>
+        /// <param name="submodelId">The Submodel's short id</param>
+        /// <param name="eventId">The Event's short id</param>
+        /// <returns></returns>
+        /// <response code="204">Event deleted successfully</response>
+        /// <response code="400">Bad Request</response> 
+        /// <response code="404">Submodel not found</response>
+        /// <response code="502">Bad Gateway</response>
+        [HttpDelete("submodel/events/{eventId}", Name = "DelEvent")]
+        [ProducesResponseType(typeof(IResult), 204)]
+        public IActionResult DelEvent(string submodelId, string eventId)
+        {
+            var result = DeleteEvent(eventId);
+            return EvaluateResult(result, CrudOperation.Delete);
+        }
+
+
+        #endregion
+
+        #endregion
+
+        #region Interface Implementation SubmodelServiceProvider
+
+        public IResult<IOperation> CreateOperation(IOperation operation)
+        {
+            return submodelServiceProvider.CreateOperation(operation);
+        }
+
+        public IResult<ElementContainer<IOperation>> RetrieveOperations()
+        {
+            return submodelServiceProvider.RetrieveOperations();
+        }
+
+        public IResult<IOperation> RetrieveOperation(string operationId)
+        {
+            return submodelServiceProvider.RetrieveOperation(operationId);
+        }
+
+        public IResult DeleteOperation(string operationId)
+        {
+            return submodelServiceProvider.DeleteOperation(operationId);
+        }
+
+        public IResult InvokeOperation(string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout)
+        {
+            return submodelServiceProvider.InvokeOperation(operationId, inputArguments, outputArguments, timeout);
+        }
+
+        public IResult<IDataElement> CreateDataElement(IDataElement dataElement)
+        {
+            return submodelServiceProvider.CreateDataElement(dataElement);
+        }
+
+        public IResult<ElementContainer<IDataElement>> RetrieveDataElements()
+        {
+            return submodelServiceProvider.RetrieveDataElements();
+        }
+
+        public IResult<IDataElement> RetrieveDataElement(string dataElementId)
+        {
+            return submodelServiceProvider.RetrieveDataElement(dataElementId);
+        }
+
+        public IResult UpdateDataElementValue(string dataElementId, IValue value)
+        {
+            return submodelServiceProvider.UpdateDataElementValue(dataElementId, value);
+        }
+
+        public IResult DeleteDataElement(string dataElementId)
+        {
+            return submodelServiceProvider.DeleteDataElement(dataElementId);
+        }
+
+        public IResult<IEvent> CreateEvent(IEvent eventable)
+        {
+            return submodelServiceProvider.CreateEvent(eventable);
+        }
+
+        public IResult<ElementContainer<IEvent>> RetrieveEvents()
+        {
+            return submodelServiceProvider.RetrieveEvents();
+        }
+
+        public IResult<IEvent> RetrieveEvent(string eventId)
+        {
+            return submodelServiceProvider.RetrieveEvent(eventId);
+        }
+
+        public IResult ThrowEvent(IPublishableEvent publishableEvent, string topic, Action<IMessagePublishedEventArgs> MessagePublished, byte qosLevel)
+        {
+            return submodelServiceProvider.ThrowEvent(publishableEvent, topic, MessagePublished, qosLevel);
+        }
+
+        public IResult DeleteEvent(string eventId)
+        {
+            return submodelServiceProvider.DeleteEvent(eventId);
+        }
+
+        public Delegate RetrieveMethodDelegate(string operationId)
+        {
+            return submodelServiceProvider.RetrieveMethodDelegate(operationId);
+        }
+
+        public void RegisterMethodCalledHandler(string operationId, Delegate handler)
+        {
+            submodelServiceProvider.RegisterMethodCalledHandler(operationId, handler);
+        }
+
+        public void ConfigureEventHandler(IMessageClient messageClient)
+        {
+            submodelServiceProvider.ConfigureEventHandler(messageClient);
+        }
+
+        public IResult<IValue> RetrieveDataElementValue(string dataElementId)
+        {
+            return submodelServiceProvider.RetrieveDataElementValue(dataElementId);
+        }
+
+        public DataElementHandler RetrieveDataElementHandler(string dataElementId)
+        {
+            return submodelServiceProvider.RetrieveDataElementHandler(dataElementId);
+        }
+
+        public void RegisterDataElementHandler(string dataElementId, DataElementHandler handler)
+        {
+            submodelServiceProvider.RegisterDataElementHandler(dataElementId, handler);
+        }
+
+        public void SubscribeUpdates(string dataElementId, Action<IValue> updateFunction)
+        {
+            submodelServiceProvider.SubscribeUpdates(dataElementId, updateFunction);
+        }
+
+        public void PublishUpdate(string dataElementId, IValue value)
+        {
+            submodelServiceProvider.PublishUpdate(dataElementId, value);
+        }
+
+        #endregion
+
+        #region Helper Methods
+
+
+        #endregion
+    }
+}
diff --git a/sdks/csnet/BaSys40.Component.REST/Pages/Index.cshtml b/sdks/csnet/BaSys40.Component.REST/Pages/Index.cshtml
new file mode 100644
index 0000000..164b5c2
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Pages/Index.cshtml
@@ -0,0 +1,331 @@
+@page "ui"
+@model BaSys40.Component.REST.Pages.IndexModel
+@{
+    ViewData["Title"] = "Index";
+}
+
+<!doctype html>
+<html>
+<head>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/4.3.1/cerulean/bootstrap.min.css">
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/popper.min.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
+
+    <style>
+        .bd-placeholder-img {
+            font-size: 1.125rem;
+            text-anchor: middle;
+        }
+
+        @@media (min-width: 768px) {
+            .bd-placeholder-img-lg {
+                font-size: 3.5rem;
+            }
+        }
+    </style>
+
+</head>
+<body>
+    @{ var aas = Model.ServiceProvider.AssetAdministrationShell; }
+
+    <nav class="navbar navbar-inverse">
+        <div class="container-fluid">
+            <div class="navbar-header">
+                <img src="~/images/BaSys-Logo-transparent-1080x250.png" width="103" height="25" style="margin-top:15px" />
+                <!-- <a class="navbar-brand" href="#">@aas.IdShort</a>-->
+            </div>
+            <ul class="nav navbar-nav">
+                <li><a href="#">Main</a></li>
+            </ul>
+            <div class="navbar-right"></div>
+        </div>
+    </nav>
+
+    <main role="main" class="container">
+
+        <div class="starter-template">
+            <h1>@aas.IdShort - Asset Administration Shell UI</h1>
+            <p class="lead">Generic UI to discover the Asset Administration Shell </p>
+        </div>
+    </main>
+
+
+    <div class="container">
+        <div class="panel panel-default">
+            <div class="panel-heading" style="background:#7ca1ce"><h4 style="color:white">Asset Administration Shell</h4></div>
+            <div class="list-group">
+                <div class="list-group-item">
+                    <div class="row">
+                        <div class="col-sm-2"><b>Identifier</b></div>
+                        <div class="col-sm-10">@aas.Identification.Id</div>
+                    </div>
+                </div>
+                <div class="list-group-item">
+                    <div class="row">
+                        <div class="col-sm-2"><b>IdShort</b></div>
+                        <div class="col-sm-10">@aas.IdShort</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    @{ var asset = Model.ServiceProvider.AssetAdministrationShell.Asset; }
+    <div class="container">
+        <div class="panel panel-default">
+            <div class="panel-heading" style="background:#b90276"><h4 style="color:white">Asset</h4></div>
+            <div class="list-group">
+                <div class="list-group-item">
+                    <div class="row">
+                        <div class="col-sm-2"><b>Identifier</b></div>
+                        <div class="col-sm-10">@asset.Identification.Id</div>
+                    </div>
+                </div>
+                <div class="list-group-item">
+                    <div class="row">
+                        <div class="col-sm-2"><b>IdShort</b></div>
+                        <div class="col-sm-10">@asset.IdShort</div>
+                    </div>
+                </div>
+                <div class="list-group-item">
+                    <div class="row">
+                        <div class="col-sm-2"><b>Semantic-Id</b></div>
+                        <div class="col-sm-10">@asset.SemanticId?.First?.Value</div>
+                    </div>
+                </div>
+
+                <div class="list-group-item">
+                    <div class="row">
+                        <div class="col-sm-2"><b>Kind</b></div>
+                        <div class="col-sm-10">@asset.Kind?.ToString()</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    @foreach (var submodel in Model.ServiceProvider.AssetAdministrationShell.Submodels)
+    {
+        <div class="container">
+            <div class="panel panel-default">
+                <div class="panel-heading" style="background:darkgreen">
+                    <h4>
+                        <a style="color:white" data-toggle="collapse" href="#@submodel.IdShort">@submodel.IdShort</a>
+                    </h4>
+                </div>
+                <div id="@submodel.IdShort" class="panel-collapse collapse">
+                    <div class="panel-body">
+                        <div class="panel-group">
+                            @if (submodel.DataElements?.Count > 0)
+                            {
+                                <div class="panel panel-default">
+                                    <div class="panel-heading" style="background:#005691"><h4 style="color:white">DataElements</h4></div>
+                                    <div class="panel-body">
+                                        <div class="panel-group">
+                                            @for (int i = 0; i < submodel.DataElements.Count; i++)
+                                            {
+                                                var dataElement = submodel.DataElements[i];
+                                                <div class="panel panel-warning">
+                                                    <div class="panel-heading">
+                                                        <h4 class="panel-title">
+                                                            <a data-toggle="collapse" href="#@dataElement.IdShort">@dataElement.IdShort</a>
+                                                        </h4>
+                                                    </div>
+                                                    <div id="@dataElement.IdShort" class="panel-collapse collapse">
+                                                        <div class="panel-body">
+                                                            <div class="row">
+                                                                <div class="col-sm-2"><b>Data-Type</b></div>
+                                                                <div class="col-sm-10">@dataElement.ValueType?.DataObjectType?.Name?.ToUpper()</div>
+                                                            </div>
+                                                        </div>
+                                                        <div class="panel-body">
+                                                            <div class="row">
+                                                                <div class="col-sm-2"><b>Semantic-Id</b></div>
+                                                                <div class="col-sm-10">@dataElement.SemanticId?.First?.Value</div>
+                                                            </div>
+                                                        </div>
+
+                                                        <div class="panel-footer">
+                                                            <div class="row">
+                                                                <div class="col-sm-8">
+                                                                    <div class="input-group">
+                                                                        <span class="input-group-addon"><i class="glyphicon glyphicon-pencil"></i></span>
+                                                                        <input id="Input_@dataElement.IdShort" type="text" class="form-control" placeholder="Value" value="@dataElement.Value?.ToString()">
+                                                                    </div>
+                                                                </div>
+                                                                <div class="col-sm-1"><button onclick="@("GetDataElementValue('" + submodel.IdShort + "', '" + dataElement.IdShort + "')")" id="@dataElement.IdShort;Retrieve" type="button" class="btn btn-primary">Retrieve</button></div>
+                                                                <div class="col-sm-1"><button onclick="@("SetDataElementValue('" + submodel.IdShort + "', '" + dataElement.IdShort + "', '" + dataElement.ValueType?.DataObjectType?.Name + "', $('#Input_" + dataElement.IdShort + "').val() )")" id="@dataElement.IdShort;Update" type="button" class="btn btn-success">Update</button></div>
+                                                            </div>
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            }
+                                        </div>
+                                    </div>
+                                </div>
+                            }
+                        </div>
+                        <div class="panel-group">
+                            @if (submodel.Operations?.Count > 0)
+                            {
+                                <div class="panel panel-default">
+                                    <div class="panel-heading" style="background:#78be20"><h4 style="color:white">Operations</h4></div>
+                                    <div class="panel-body">
+                                        <div class="panel-group">
+
+                                            @for (int i = 0; i < submodel.Operations.Count; i++)
+                                            {
+                                                var operation = submodel.Operations[i];
+                                                <div class="panel panel-warning">
+                                                    <div class="panel-heading">
+                                                        <h4 class="panel-title">
+                                                            <a data-toggle="collapse" href="#@operation.IdShort">@operation.IdShort</a>
+                                                        </h4>
+                                                    </div>
+                                                    <div id="@operation.IdShort" class="panel-collapse collapse">
+                                                        @if (operation.In?.Count > 0)
+                                                        {
+                                                            foreach (var argument in operation.In)
+                                                            {
+                                                                <div class="panel-body">
+                                                                    <div class="row">
+                                                                        <div class="col-sm-2 argInName @submodel.IdShort @operation.IdShort"><b>@argument.IdShort (IN)</b></div>
+                                                                        <div class="col-sm-2 argInType @submodel.IdShort @operation.IdShort">@argument.DataType.DataObjectType.Name.ToUpper()</div>
+                                                                        <div class="col-sm-8">
+                                                                            <div class="input-group">
+                                                                                <span class="input-group-addon"><i class="glyphicon glyphicon-pencil"></i></span>
+                                                                                <input id="msg" type="text" class="form-control argInValue @submodel.IdShort  @operation.IdShort" name="msg" placeholder="Argument Value">
+                                                                            </div>
+                                                                        </div>
+                                                                    </div>
+                                                                </div>
+                                                            }
+                                                        }
+                                                        @if (operation.Out?.Count > 0)
+                                                        {
+                                                            foreach (var argument in operation.Out)
+                                                            {
+                                                                <div class="panel-body">
+                                                                    <div class="row">
+                                                                        <div class="col-sm-2 argOutName @submodel.IdShort @operation.IdShort"><b>@argument.IdShort (OUT)</b></div>
+                                                                        <div class="col-sm-2 argOutType @submodel.IdShort @operation.IdShort">@argument.DataType.DataObjectType.Name.ToUpper()</div>   
+                                                                        <div class="col-sm-8">
+                                                                            <div class="input-group">
+                                                                                <span class="input-group-addon"><i class="glyphicon glyphicon-pencil"></i></span>
+                                                                                <input id="argOutValue_@submodel.IdShort@operation.IdShort" type="text" class="form-control argOutValue @submodel.IdShort  @operation.IdShort" name="msg" placeholder="Return Value">
+                                                                            </div>
+                                                                        </div>
+                                                                    </div>
+                                                                </div>
+                                                            }
+                                                        }
+                                                        <div class="panel-footer"><button onclick="@("ExecuteOperation('" + submodel.IdShort + "', '" + operation.IdShort + "')")" type="button" class="btn btn-success">Execute</button></div>
+                                                    </div>
+                                                </div>
+                                            }
+                                        </div>
+                                    </div>
+                                </div>
+
+                            }
+                        </div>
+                        <div class="panel-group">
+                            @if (submodel.Events?.Count > 0)
+                            {
+                                <div class="panel panel-default">
+                                    <div class="panel-heading" style="background:#00a8b0"><h4 style="color:white">Events</h4></div>
+                                    <div class="panel-body">
+                                        <div class="panel-group">
+
+                                            @for (int i = 0; i < submodel.Events.Count; i++)
+                                            {
+                                                var eventable = submodel.Events[i];
+                                                <div class="panel panel-warning">
+                                                    <div class="panel-heading">
+                                                        <h4 class="panel-title">
+                                                            <a data-toggle="collapse" href="#@eventable.IdShort">@eventable.IdShort</a>
+                                                        </h4>
+                                                    </div>
+                                                    <div id="@eventable.IdShort" class="panel-collapse collapse">
+
+                                                    </div>
+                                                </div>
+                                            }
+
+                                        </div>
+                                    </div>
+                                </div>
+                            }
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    }
+
+    <script>
+        function ExecuteOperation(submodelId, operationId) {
+            var argNames = document.getElementsByClassName("argInName " + submodelId + " " + operationId);
+            var argTypes = document.getElementsByClassName("argInType " + submodelId + " " + operationId);
+            var argValues = document.getElementsByClassName("argInValue " + submodelId + " " + operationId);
+            var argOutValues = document.getElementsByClassName("argOutValue " + submodelId + " " + operationId);
+
+            var args = [];
+            for (var i = 0; i < argNames.length; i++) {
+                var arg = { index: i, idShort: argNames.item(i).innerText, valueType: { dataObjectType: { name: argTypes.item(i).innerText.toLowerCase() } }, value: argValues.item(i).value };
+                args.push(arg);
+            }
+
+
+            $.ajax({
+                type: 'POST',
+                url: '/aas/submodels/' + submodelId + '/operations/' + operationId,
+                contentType: 'application/json',
+                data: JSON.stringify(args),
+                error: function () {
+                    alert("Failed to exectute with args: " + JSON.stringify(args));
+                },
+                success: function (data) {
+                    $('#argOutValue_' + submodelId + operationId).val(data.entity[0].value);
+                }
+            });
+        }
+    </script>
+    <script>
+        function GetDataElementValue(submodelId, dataElementId) {
+            $.ajax({
+                type: 'GET',
+                url: '/aas/submodels/' + submodelId + '/dataElements/' + dataElementId + '/value',
+                success: function (data) {
+                    $('#Input_' + dataElementId).val(data.entity.value);
+                }
+            });
+        }
+    </script>
+
+    <script>
+        function SetDataElementValue(submodelId, dataElementId, dataObjectTypeName, val) {
+            var value = {
+                valueType: { dataObjectType: { name: dataObjectTypeName } }, value: val
+            };
+            $.ajax({
+                type: 'PUT',
+                url: '/aas/submodels/' + submodelId + '/dataElements/' + dataElementId + '/value',
+                contentType: 'application/json',
+                data: JSON.stringify(value),
+                error: function () {
+                    $('#Input_' + dataElementId).val('Error updating Data-Element-Value');
+                },
+                statusCode: {
+                    204: function () {
+                        //alert("Successfully updated '" + dataElementId + "' to new value '" + val + "'");
+                    }
+                },
+                success: function () { }
+            });
+        }
+    </script>
+
+</body>
+</html>
diff --git a/sdks/csnet/BaSys40.Component.REST/Pages/Index.cshtml.cs b/sdks/csnet/BaSys40.Component.REST/Pages/Index.cshtml.cs
new file mode 100644
index 0000000..f63ba89
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Pages/Index.cshtml.cs
@@ -0,0 +1,20 @@
+using BaSys40.API.ServiceProvider;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+
+namespace BaSys40.Component.REST.Pages
+{
+    public class IndexModel : PageModel
+    {
+        public IAssetAdministrationShellServiceProvider ServiceProvider { get; }
+
+        public IndexModel(IAssetAdministrationShellServiceProvider provider)
+        {
+            ServiceProvider = provider;
+        }
+
+        public void OnGet()
+        {
+
+        }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Component.REST/Program.cs b/sdks/csnet/BaSys40.Component.REST/Program.cs
new file mode 100644
index 0000000..70f7fa1
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Program.cs
@@ -0,0 +1,40 @@
+using Microsoft.AspNetCore;
+using Microsoft.AspNetCore.Hosting;
+using NLog.Web;
+using Microsoft.Extensions.Logging;
+using System.IO;
+
+namespace BaSys40.Component.REST
+{
+    public class Program
+    {
+        public static ServerSettings Settings;
+        public static void Main(string[] args)
+        {
+            var logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
+            logger.Debug("Starting main method...");
+
+            Settings = ServerSettings.LoadSettings();
+
+            BuildWebHost(args).Run();
+        }
+
+        public static IWebHost BuildWebHost(string[] args)
+        {
+            var webHost = WebHost.CreateDefaultBuilder(args)
+                .UseStartup<Startup>()
+                .ConfigureLogging(logging =>
+                {
+                    logging.ClearProviders();
+                    logging.SetMinimumLevel(LogLevel.Warning);
+                })
+                .UseNLog()
+                .UseContentRoot(Directory.GetCurrentDirectory());
+
+            if (Settings?.Hosting?.Urls?.Count > 0)
+                webHost.UseUrls(Settings.Hosting.Urls.ToArray());
+
+            return webHost.Build();
+        }     
+    }
+}
diff --git a/sdks/csnet/BaSys40.Component.REST/Properties/PublishProfiles/BaSysComponent - Web Deploy.pubxml b/sdks/csnet/BaSys40.Component.REST/Properties/PublishProfiles/BaSysComponent - Web Deploy.pubxml
new file mode 100644
index 0000000..636f809
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Properties/PublishProfiles/BaSysComponent - Web Deploy.pubxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This file is used by the publish/package process of your Web project. You can customize the behavior of this process
+by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121. 
+-->
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <WebPublishMethod>MSDeploy</WebPublishMethod>
+    <ResourceId>/subscriptions/473d17a5-47ec-4d8c-b273-8308beb30f0f/resourcegroups/BaSys/providers/Microsoft.Web/sites/BaSysComponent</ResourceId>
+    <ResourceGroup>BaSys</ResourceGroup>
+    <PublishProvider>AzureWebSite</PublishProvider>
+    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
+    <LastUsedPlatform>Any CPU</LastUsedPlatform>
+    <SiteUrlToLaunchAfterPublish>http://basyscomponent.azurewebsites.net</SiteUrlToLaunchAfterPublish>
+    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
+    <ExcludeApp_Data>False</ExcludeApp_Data>
+    <ProjectGuid>57cad1eb-cf7a-4063-aff0-b9a9b870a42e</ProjectGuid>
+    <MSDeployServiceURL>basyscomponent.scm.azurewebsites.net:443</MSDeployServiceURL>
+    <DeployIisAppPath>BaSysComponent</DeployIisAppPath>
+    <RemoteSitePhysicalPath />
+    <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
+    <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
+    <EnableMSDeployBackup>True</EnableMSDeployBackup>
+    <UserName>$BaSysComponent</UserName>
+    <_SavePWD>True</_SavePWD>
+    <_DestinationType>AzureWebSite</_DestinationType>
+    <InstallAspNetCoreSiteExtension>False</InstallAspNetCoreSiteExtension>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Component.REST/Properties/PublishProfiles/FolderProfile.pubxml b/sdks/csnet/BaSys40.Component.REST/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 0000000..ee59b19
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This file is used by the publish/package process of your Web project. You can customize the behavior of this process
+by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121. 
+-->
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <WebPublishMethod>FileSystem</WebPublishMethod>
+    <PublishProvider>FileSystem</PublishProvider>
+    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
+    <LastUsedPlatform>Any CPU</LastUsedPlatform>
+    <SiteUrlToLaunchAfterPublish />
+    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
+    <ExcludeApp_Data>False</ExcludeApp_Data>
+    <ProjectGuid>655a0dc1-7b6b-43ac-afdd-701f6c5a20d8</ProjectGuid>
+    <publishUrl>bin\Release\PublishOutput</publishUrl>
+    <DeleteExistingFiles>False</DeleteExistingFiles>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Component.REST/Properties/launchSettings.json b/sdks/csnet/BaSys40.Component.REST/Properties/launchSettings.json
new file mode 100644
index 0000000..60762fe
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Properties/launchSettings.json
@@ -0,0 +1,27 @@
+{
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:60183/",
+      "sslPort": 0
+    }
+  },
+  "profiles": {
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchUrl": "aas",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "BaSys40.REST": {
+      "commandName": "Project",
+      "launchUrl": "aas",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      },
+      "applicationUrl": "http://localhost:60183/"
+    }
+  }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Component.REST/ServerSettings.cs b/sdks/csnet/BaSys40.Component.REST/ServerSettings.cs
new file mode 100644
index 0000000..79c386f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/ServerSettings.cs
@@ -0,0 +1,20 @@
+using BaSys40.Utils.Settings;
+using System;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+
+namespace BaSys40.Component.REST
+{
+    public class ServerSettings : Settings<ServerSettings>
+    {
+        [XmlElement]
+        public HostingConfiguration Hosting { get; set; }
+
+    }
+    [Serializable]
+    public class HostingConfiguration
+    {
+        [XmlArrayItem("Url")]
+        public List<string> Urls { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Component.REST/ServerSettings.xml b/sdks/csnet/BaSys40.Component.REST/ServerSettings.xml
new file mode 100644
index 0000000..b447e26
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/ServerSettings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ServerSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <Hosting>
+    <Urls>
+      <Url>http://+:5080</Url>
+    </Urls>
+  </Hosting>
+  <Miscellaneous/>
+</ServerSettings>
diff --git a/sdks/csnet/BaSys40.Component.REST/Startup.cs b/sdks/csnet/BaSys40.Component.REST/Startup.cs
new file mode 100644
index 0000000..a7220a1
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/Startup.cs
@@ -0,0 +1,133 @@
+using BaSys40.API.ServiceProvider;
+using BaSys40.Component.REST.Controllers;
+using BaSys40.Models.Extensions;
+using BaSys40.Utils.DIExtensions;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using NLog;
+using NLog.Web;
+using Swashbuckle.AspNetCore.Swagger;
+using System;
+using System.IO;
+
+namespace BaSys40.Component.REST
+{
+    public class Startup
+    {
+        private static Logger logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
+
+        private string submodelId;
+        private string aasId;
+
+        private IAssetAdministrationShellServiceProvider shellService;
+
+        public IConfiguration Configuration { get; }
+
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            services.AddMvc().AddControllersAsServices();
+
+            services.ConfigureStandardImplementation();
+            services.ConfigureStandardDI();
+
+            /* If more than one Asset Administration Shell is accessible via this HTTP-Server uncomment the following lines *//*
+            services.AddTransient(ctx =>
+            {
+                var smsp = ctx.GetRequiredService<IAssetAdministrationShellAggregatorServiceProvider>().GetAssetAdministrationShellServiceProvider(aasId);
+                return new AssetAdministrationShellServices(smsp);
+            });
+            */
+
+            /* Initialize IAssetAdministrationShellService Provider */
+            //shellService = new ...;
+
+            services.AddSingleton<IAssetAdministrationShellServiceProvider>(ctx =>
+            {
+                return shellService;
+            });
+            
+            
+            services.AddTransient(ctx =>
+            {
+                var smsp = ctx.GetRequiredService<IAssetAdministrationShellServiceProvider>().GetSubmodelServiceProvider(submodelId);
+                return new SubmodelServices(smsp);
+            });           
+            
+            
+            // Register the Swagger generator, defining one or more Swagger documents
+            services.AddSwaggerGen(c =>
+            {
+                c.SwaggerDoc("v1", new Info
+                {
+                    Version = "v1",
+                    Title = "BaSys 4.0 Asset Administration Shell REST-API",
+                    Description = "The full description of the generic BaSys 4.0 Asset Administration Shell REST-API",
+                    TermsOfService = "None",
+                    Contact = new Contact { Name = "Constantin Ziesche", Email = "constantin.ziesche@bosch.com", Url = "https://www.bosch.com/de/" },
+                    License = new License { Name = "Use under Eclipse Public License 2.0", Url = "https://www.eclipse.org/legal/epl-2.0/" }
+                });
+
+                // Set the comments path for the Swagger JSON and UI.
+                var basePath = AppContext.BaseDirectory;
+                var xmlPath = Path.Combine(basePath, "BaSys40.Component.REST.xml");
+                c.IncludeXmlComments(xmlPath);
+                c.SchemaFilter<SchemaFilter>();
+                //c.DocumentFilter<DocumentFilter>();             
+            });
+        }
+        
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime applicationLifetime)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+            app.UseStaticFiles();
+
+            applicationLifetime.ApplicationStopping.Register(OnShutdown);
+
+            // Enable middleware to serve generated Swagger as a JSON endpoint.
+            app.UseSwagger();
+
+            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
+            app.UseSwaggerUI(c =>
+            {
+                c.SwaggerEndpoint("/swagger/v1/swagger.json", "BaSys 4.0 Asset Administration Shell REST-API");
+            });
+
+            app.AddStandardRewriterOptions();
+
+            app.Use((context, next) =>
+            {
+                var pathElements = context.Request.Path.ToUriComponent().Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+
+                if (context.Request.Query?.Count > 0)
+                {
+                    if (context.Request.Query.ContainsKey("aasId"))
+                        aasId = context.Request.Query["aasId"].ToString();
+
+                    if (context.Request.Query.ContainsKey("submodelId"))
+                        submodelId = context.Request.Query["submodelId"].ToString();
+                }
+                return next();
+            });
+
+            app.UseMvc();
+        }
+
+        private void OnShutdown()
+        {
+            logger.Info("Shutdown completed!");
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Component.REST/SwaggerSettings.cs b/sdks/csnet/BaSys40.Component.REST/SwaggerSettings.cs
new file mode 100644
index 0000000..51dba7a
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/SwaggerSettings.cs
@@ -0,0 +1,73 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using Swashbuckle.AspNetCore.Swagger;
+using Swashbuckle.AspNetCore.SwaggerGen;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Component.REST
+{
+    internal class SchemaFilter : ISchemaFilter
+    {
+        public void Apply(Schema model, SchemaFilterContext context)
+        {
+            if (context.SystemType.IsInterface)
+            {
+                string newName = context.SystemType.Name.Substring(1, context.SystemType.Name.Length - 1);
+                model.Title = newName;
+            }
+        }
+    }
+
+    internal class DocumentFilter : IDocumentFilter
+    {
+        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
+        {
+            var models = typeof(IAssetAdministrationShell).Assembly;
+            var types = models.GetTypes().Where(t => Attribute.IsDefined(t, typeof(DataContractAttribute)) && !t.IsGenericType);
+            foreach (var type in types)
+            {
+                context.SchemaRegistry.GetOrRegister(type);
+            }
+
+            List<string> modelRemoveList = new List<string>();
+            foreach (var model in context.SchemaRegistry.Definitions)
+            {
+                if (model.Key.StartsWith("I") && models.GetTypes().Any(t => t.Name == model.Key && t.IsInterface))
+                    modelRemoveList.Add(model.Key);
+            }
+
+            foreach (var model in modelRemoveList)
+            {
+                //context.SchemaRegistry.Definitions.Remove(model);
+                foreach (var schema in context.SchemaRegistry.Definitions)
+                {
+                    ReplaceRefInSchema(schema.Value, model);
+                }
+            }
+
+        }
+
+        public void ReplaceRefInSchema(Schema schema, string modelName)
+        {
+            if (!string.IsNullOrEmpty(schema.Ref))
+            {
+                if (modelName == "IValue")
+                    schema.Ref = schema.Ref.Replace("IValue", "ElementValue");
+                else
+                    schema.Ref = schema.Ref.Replace(modelName, modelName.Substring(1));
+            }
+            if (schema.Properties != null)
+            {
+                foreach (var prop in schema.Properties)
+                {
+                    ReplaceRefInSchema(prop.Value, modelName);
+                }
+
+            }
+            if (schema.Items != null)
+                ReplaceRefInSchema(schema.Items, modelName);
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Component.REST/wwwroot/images/BaSys-Logo-transparent-1080x250.png b/sdks/csnet/BaSys40.Component.REST/wwwroot/images/BaSys-Logo-transparent-1080x250.png
new file mode 100644
index 0000000..866b6b3
--- /dev/null
+++ b/sdks/csnet/BaSys40.Component.REST/wwwroot/images/BaSys-Logo-transparent-1080x250.png
Binary files differ
diff --git a/sdks/csnet/BaSys40.Models/BaSys40.Models.csproj b/sdks/csnet/BaSys40.Models/BaSys40.Models.csproj
new file mode 100644
index 0000000..442543f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/BaSys40.Models.csproj
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
+    <ApplicationIcon />
+    <OutputType>Library</OutputType>
+    <StartupObject />
+    <Configurations>Debug;Release</Configurations>
+    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
+  </PropertyGroup>
+  
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+   <DebugType>Full</DebugType>
+  </PropertyGroup>
+  
+  
+  <ItemGroup>
+    <ProjectReference Include="..\BaSys40.Utils\BaSys40.Utils.csproj" />
+  </ItemGroup>
+  
+  <ItemGroup>
+    <Folder Include="Security\" />
+  </ItemGroup>
+  
+  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+    <Exec Command="copy &quot;$(ProjectDir)bin\Debug\BaSys40.Models.1.0.0.nupkg&quot; &quot;C:\Development\BaSys40\SDK\packages&quot; /Y" />
+  </Target>
+
+</Project>
diff --git a/sdks/csnet/BaSys40.Models/Connectivity/EndpointConverter.cs b/sdks/csnet/BaSys40.Models/Connectivity/EndpointConverter.cs
new file mode 100644
index 0000000..9aaf6c9
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Connectivity/EndpointConverter.cs
@@ -0,0 +1,44 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+
+namespace BaSys40.Models.Connectivity
+{
+    public class EndpointConverter : JsonConverter<IEndpoint>
+    {
+        public override bool CanWrite => false;
+        public override bool CanRead => true;
+
+        public override IEndpoint ReadJson(JsonReader reader, Type objectType, IEndpoint existingValue, bool hasExistingValue, JsonSerializer serializer)
+        {
+            JObject jObject;
+
+            try
+            {
+                jObject = JObject.Load(reader);
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+           
+            var endpointType = jObject.SelectToken("type")?.ToObject<string>();
+            var address = jObject.SelectToken("address")?.ToObject<string>();
+
+
+            IEndpoint endpoint = null;
+            if (!string.IsNullOrEmpty(endpointType) && !string.IsNullOrEmpty(address))
+            {
+                endpoint = EndpointFactory.CreateEndpoint(endpointType, address, null);
+                serializer.Populate(jObject.CreateReader(), endpoint);
+            }
+
+            return endpoint;            
+        }
+
+        public override void WriteJson(JsonWriter writer, IEndpoint value, JsonSerializer serializer)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Connectivity/EndpointFactory.cs b/sdks/csnet/BaSys40.Models/Connectivity/EndpointFactory.cs
new file mode 100644
index 0000000..1018f95
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Connectivity/EndpointFactory.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace BaSys40.Models.Connectivity
+{
+    public static partial class EndpointFactory
+    {
+        public static IEndpoint CreateEndpoint(string endpointType, string address, IEndpointSecurity security)
+        {
+            switch (endpointType.ToLower())
+            {
+                case EndpointType.HTTP: return new HttpEndpoint(address);
+                case EndpointType.MQTT:
+                    {
+                        Uri uri = new Uri(address);
+                        var brokerUri = uri.AbsoluteUri;
+                        var topic = uri.AbsolutePath;
+
+                        return new MqttEndpoint(brokerUri, topic);
+                    }
+                case EndpointType.OPC_UA: return new OpcUaEndpoint(address);
+                default:
+                    return null;
+            }
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Connectivity/EndpointType.cs b/sdks/csnet/BaSys40.Models/Connectivity/EndpointType.cs
new file mode 100644
index 0000000..ae96961
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Connectivity/EndpointType.cs
@@ -0,0 +1,13 @@
+namespace BaSys40.Models.Connectivity
+{
+    public static class EndpointType
+    {
+        public const string HTTP = "http";
+        public const string TCP = "tcp";
+        public const string MQTT = "mqtt";
+        public const string OPC_UA = "opc-ua";
+        public const string COAP = "coap";
+        public const string WEBSOCKET = "websocket";
+    }
+}
+
diff --git a/sdks/csnet/BaSys40.Models/Connectivity/HttpEndpoint.cs b/sdks/csnet/BaSys40.Models/Connectivity/HttpEndpoint.cs
new file mode 100644
index 0000000..1a00ada
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Connectivity/HttpEndpoint.cs
@@ -0,0 +1,28 @@
+using Newtonsoft.Json;
+using System;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Connectivity
+{
+    public class HttpEndpoint : IEndpoint
+    {
+        public string Address { get; }
+
+        [IgnoreDataMember]
+        public Uri Url { get; }
+
+        public string Type => EndpointType.HTTP;
+
+        public IEndpointSecurity Security { get; set;}
+
+        [JsonConstructor]
+        public HttpEndpoint(string address)
+        {
+            address = address ?? throw new ArgumentNullException("url");
+            Url = new Uri(address);
+            Address = Url.ToString();
+        }
+
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Connectivity/IAddressable.cs b/sdks/csnet/BaSys40.Models/Connectivity/IAddressable.cs
new file mode 100644
index 0000000..c099e29
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Connectivity/IAddressable.cs
@@ -0,0 +1,29 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Connectivity
+{
+    public interface IAddressable
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "endpoints")]
+        List<IEndpoint> Endpoints { get; }
+    }
+
+    [JsonConverter(typeof(EndpointConverter))]
+    public interface IEndpoint
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "address")]
+        string Address { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "type")]
+        string Type { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "security")]
+        IEndpointSecurity Security { get; }
+    }
+
+    public interface IEndpointSecurity
+    {
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Connectivity/IServiceDescriptor.cs b/sdks/csnet/BaSys40.Models/Connectivity/IServiceDescriptor.cs
new file mode 100644
index 0000000..9bb015c
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Connectivity/IServiceDescriptor.cs
@@ -0,0 +1,8 @@
+using BaSys40.Models.Core.Identification;
+
+namespace BaSys40.Models.Connectivity
+{
+    public interface IServiceDescriptor : IAddressable, IIdentifiable
+    {
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Connectivity/MqttEndpoint.cs b/sdks/csnet/BaSys40.Models/Connectivity/MqttEndpoint.cs
new file mode 100644
index 0000000..70f7e62
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Connectivity/MqttEndpoint.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace BaSys40.Models.Connectivity
+{
+    public class MqttEndpoint : IEndpoint
+    {
+        public string Address { get; }
+
+        public Uri BrokerUri { get; }
+
+        public string Topic { get; }
+
+        public string Type => EndpointType.MQTT;
+
+        public IEndpointSecurity Security { get; set; }
+
+        public MqttEndpoint(string brokerUri, string topic)
+        {
+            brokerUri = brokerUri ?? throw new ArgumentNullException("url");
+            BrokerUri = new Uri(brokerUri);
+            Topic = topic ?? "/";
+            Address = brokerUri + topic;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Connectivity/OpcUaEndpoint.cs b/sdks/csnet/BaSys40.Models/Connectivity/OpcUaEndpoint.cs
new file mode 100644
index 0000000..47d1e8f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Connectivity/OpcUaEndpoint.cs
@@ -0,0 +1,31 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace BaSys40.Models.Connectivity
+{
+    public class OpcUaEndpoint : IEndpoint
+    {
+        public string Address { get; }
+
+        [IgnoreDataMember]
+        public string BrowsePath { get; }
+        [IgnoreDataMember]
+        public string Authority { get; }
+        public string Type => EndpointType.OPC_UA;
+
+        public IEndpointSecurity Security { get; set; }
+
+        [JsonConstructor]
+        public OpcUaEndpoint(string address)
+        {
+            Address = address ?? throw new ArgumentNullException("address");
+            var uri = new Uri(address);
+            BrowsePath = uri.AbsolutePath;
+            Authority = uri.Authority;
+        }
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/AssetAdministrationShellDescriptor.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/AssetAdministrationShellDescriptor.cs
new file mode 100644
index 0000000..e72fb83
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/AssetAdministrationShellDescriptor.cs
@@ -0,0 +1,61 @@
+using BaSys40.Models.Connectivity;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell
+{
+    [DataContract]
+    public class AssetAdministrationShellDescriptor : IServiceDescriptor
+    {
+        public Identifier Identification { get; set; }       
+        public Dictionary<string, string> MetaData { get; set; }
+        public AdministrativeInformation Administration { get; set; }
+        public string IdShort { get; set; }
+        public string Category { get; set; }
+        public List<Description> Descriptions { get; set; }
+        public List<IEndpoint> Endpoints { get; }
+        [IgnoreDataMember]
+        public IReference Parent => null;
+
+        [DataMember(EmitDefaultValue = false, IsRequired = true, Name = "asset")]
+        public IAsset Asset { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "submodels")]
+        public List<SubmodelDescriptor> Submodels { get; set; }
+
+        public AssetAdministrationShellDescriptor(params IEndpoint[] endpoints)
+        {
+            Endpoints = endpoints?.ToList();
+        }
+
+        [JsonConstructor]
+        public AssetAdministrationShellDescriptor(List<IEndpoint> endpoints) 
+        {
+            Endpoints = endpoints;
+        }
+
+        public AssetAdministrationShellDescriptor(IAssetAdministrationShell aas, params IEndpoint[] endpoints) : this(endpoints)
+        {
+            this.Identification = aas.Identification;
+            this.MetaData = aas.MetaData;
+            this.Administration = aas.Administration;
+            this.IdShort = aas.IdShort;
+            this.Category = aas.Category;
+            this.Descriptions = aas.Descriptions;
+            this.Asset = aas.Asset;
+
+            if (aas.Submodels?.Count > 0)
+            {
+                this.Submodels = new List<SubmodelDescriptor>();
+                foreach (var submodel in aas.Submodels)
+                {
+                    this.Submodels.Add(new SubmodelDescriptor(submodel, endpoints));
+                }
+            }
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/EntityType.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/EntityType.cs
new file mode 100644
index 0000000..76b0d33
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/EntityType.cs
@@ -0,0 +1,12 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Enums
+{
+    [DataContract]
+    public enum EntityType : int
+    {
+        None = 0,
+        Primitive = 1,
+        Object = 2
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/Kind.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/Kind.cs
new file mode 100644
index 0000000..f7c74ff
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/Kind.cs
@@ -0,0 +1,11 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Enums
+{
+    [DataContract]
+    public enum Kind : int
+    {
+        Type = 0,
+        Instance = 1
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/SchemaType.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/SchemaType.cs
new file mode 100644
index 0000000..6cf3f42
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Enums/SchemaType.cs
@@ -0,0 +1,13 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Enums
+{
+    [DataContract]
+    public enum SchemaType : int
+    {
+        None = 0,
+        XSD = 1,
+        RDFS = 2,
+        JSchema = 3
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ConceptDictionary.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ConceptDictionary.cs
new file mode 100644
index 0000000..0028947
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ConceptDictionary.cs
@@ -0,0 +1,21 @@
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using System.Collections.Generic;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public class ConceptDictionary : IReferable
+    {
+        public string IdShort { get; set; }
+
+        public string Category { get; set; }
+
+        public List<Description> Descriptions { get; set; }
+
+        public IReference Parent { get; set; }
+
+        public Dictionary<string, string> MetaData { get; set; }
+
+        public List<IReference<IConceptDescription>> ConceptDescriptions { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IBlob.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IBlob.cs
new file mode 100644
index 0000000..61b7799
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IBlob.cs
@@ -0,0 +1,10 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes
+{
+    public interface IBlob : IDataElement<byte[]>
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "mimeType")]
+        string MimeType { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IDataElementCollection.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IDataElementCollection.cs
new file mode 100644
index 0000000..9052c04
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IDataElementCollection.cs
@@ -0,0 +1,7 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes
+{
+    public interface IDataElementCollection : IDataElement<ElementContainer<IDataElement>>
+    { }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IFile.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IFile.cs
new file mode 100644
index 0000000..6dc3f6b
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IFile.cs
@@ -0,0 +1,10 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes
+{
+    public interface IFile : IDataElement<string>
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "mimeType")]
+        string MimeType { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IProperty.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IProperty.cs
new file mode 100644
index 0000000..8aa5446
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IProperty.cs
@@ -0,0 +1,15 @@
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Extensions;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes
+{
+    public interface IProperty : IDataElement
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "valueId")]
+        IReference ValueId { get; set; }
+    }
+
+    public interface IProperty<T> : IProperty, IValue<T>
+    { }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IReferenceElement.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IReferenceElement.cs
new file mode 100644
index 0000000..7592b7b
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/DataElementSubtypes/IReferenceElement.cs
@@ -0,0 +1,8 @@
+using BaSys40.Models.Core.Extensions.References;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes
+{
+    public interface IReferenceElement<out T> : IDataElement<T> where T : IReference
+    { }
+}
+
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IArgument.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IArgument.cs
new file mode 100644
index 0000000..4e2b465
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IArgument.cs
@@ -0,0 +1,14 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.Constraints;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IArgument : IQualifiable, IValue
+    {
+        [DataMember]
+        int? Index { get; set; }
+        [DataMember]
+        string IdShort { get; set; }     
+    }   
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IAsset.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IAsset.cs
new file mode 100644
index 0000000..695c2f5
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IAsset.cs
@@ -0,0 +1,15 @@
+using BaSys40.Models.Core.Attributes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Semantics;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    [ExportAsReference(KeyElements.Asset, JsonSchemaIgnore = true)]
+    public interface IAsset : IIdentifiable, ITypeable, IHasSemantics, IModelElement, IHasDataSpecification
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "assetIdentificationModel")]
+        IReference<ISubmodel> AssetIdentificationModel { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IAssetAdministrationShell.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IAssetAdministrationShell.cs
new file mode 100644
index 0000000..047a914
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IAssetAdministrationShell.cs
@@ -0,0 +1,32 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Models.Core.Attributes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Core.Views;
+using BaSys40.Models.Export;
+using BaSys40.Models.Semantics;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+   
+    public interface IAssetAdministrationShell : IIdentifiable, IModelElement, IHasDataSpecification
+    {
+        [JsonProperty, DataMember(EmitDefaultValue = false, IsRequired = false, Name = "derivedFrom")]
+        IReference<IAssetAdministrationShell> DerivedFrom { get; }
+
+        [ExportAsReference(KeyElements.Asset), DataMember(EmitDefaultValue = false, IsRequired = false, Name = "asset")]
+        IAsset Asset { get; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "submodels")]
+        ElementContainer<ISubmodel> Submodels { get; set; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "views")]
+        ElementContainer<IView> Views { get; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "conceptDictionaries")]
+        List<ConceptDictionary> ConceptDictionaries { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IConceptDescription.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IConceptDescription.cs
new file mode 100644
index 0000000..c82b859
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IConceptDescription.cs
@@ -0,0 +1,14 @@
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Semantics;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IConceptDescription : IIdentifiable, IHasDataSpecification, IModelElement
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "isCaseOf")]
+        List<IReference> IsCaseOf { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IDataElement.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IDataElement.cs
new file mode 100644
index 0000000..fca6d47
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IDataElement.cs
@@ -0,0 +1,11 @@
+using BaSys40.Models.Core.Extensions.References;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IDataElement : ISubmodelElement, IValue
+    {
+    }
+    public interface IDataElement<out TValue> : IDataElement, IValue<TValue>
+    { }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IDataSpecificationContent.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IDataSpecificationContent.cs
new file mode 100644
index 0000000..f549576
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IDataSpecificationContent.cs
@@ -0,0 +1,6 @@
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IDataSpecificationContent
+    {
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IElementContainer.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IElementContainer.cs
new file mode 100644
index 0000000..95095e5
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IElementContainer.cs
@@ -0,0 +1,10 @@
+using BaSys40.Models.Core.Identification;
+using System.Collections.Generic;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IElementContainer<Identifier, Elements> : IList<Elements>
+    {
+        Elements this[Identifier id] { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IEmbeddedDataSpecification.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IEmbeddedDataSpecification.cs
new file mode 100644
index 0000000..2ccf072
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IEmbeddedDataSpecification.cs
@@ -0,0 +1,13 @@
+using BaSys40.Models.Core.Extensions.References;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IEmbeddedDataSpecification
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "hasDataSpecification")]
+        IReference HasDataSpecification { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "dataSpecificationContent")]
+        IDataSpecificationContent DataSpecificationContent { get; }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IEvent.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IEvent.cs
new file mode 100644
index 0000000..abd4d06
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IEvent.cs
@@ -0,0 +1,10 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IEvent : ISubmodelElement
+    {
+        [DataMember]
+        DataType DataType { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IOperation.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IOperation.cs
new file mode 100644
index 0000000..042c675
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IOperation.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IOperation : ISubmodelElement
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "in")]
+        List<IOperationVariable> In { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "out")]
+        List<IOperationVariable> Out { get; set; }
+    }
+
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IOperationVariable.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IOperationVariable.cs
new file mode 100644
index 0000000..9b3fa3e
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IOperationVariable.cs
@@ -0,0 +1,12 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IOperationVariable : ISubmodelElement
+    {
+        [DataMember]
+        int? Index { get; set; }
+        [DataMember]
+        DataType DataType { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IPublishableEvent.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IPublishableEvent.cs
new file mode 100644
index 0000000..7b7981b
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IPublishableEvent.cs
@@ -0,0 +1,21 @@
+using BaSys40.Models.Core.Identification;
+using System.Runtime.Serialization;
+using BaSys40.Models.Core.Extensions.References;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IPublishableEvent : IIdentifiable
+    {
+        [DataMember]
+        string Originator { get; }
+
+        [DataMember]
+        Reference<IEvent> EventDescriptionReference { get; }
+
+        [DataMember]
+        string TimeStamp { get; }
+
+        [DataMember]
+        string Message { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IRelationshipElement.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IRelationshipElement.cs
new file mode 100644
index 0000000..e9944bf
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IRelationshipElement.cs
@@ -0,0 +1,14 @@
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IRelationshipElement : ISubmodelElement
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "first")]
+        Reference<IReferable> First { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "second")]
+        Reference<IReferable> Second { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ISubModel.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ISubModel.cs
new file mode 100644
index 0000000..fe25c88
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ISubModel.cs
@@ -0,0 +1,24 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Models.Core.Attributes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Semantics;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    [ExportAsReference(KeyElements.Submodel, JsonSchemaIgnore = true)]
+    public interface ISubmodel : IIdentifiable, ITypeable, IHasSemantics, IModelElement, IHasDataSpecification
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "dataElements")]
+        ElementContainer<IDataElement> DataElements { get; set; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "operations")]
+        ElementContainer<IOperation> Operations { get; set; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "events")]
+        ElementContainer<IEvent> Events { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "submodelElements")]
+        ElementContainer<ISubmodelElement> SubmodelElements { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ISubModelElement.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ISubModelElement.cs
new file mode 100644
index 0000000..f77e501
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/ISubModelElement.cs
@@ -0,0 +1,9 @@
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Core.Constraints;
+using BaSys40.Models.Semantics;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface ISubmodelElement : IHasSemantics, IQualifiable, IReferable, ITypeable, IModelElement, IHasDataSpecification
+    { }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IValue.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IValue.cs
new file mode 100644
index 0000000..29f77ef
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Generics/IValue.cs
@@ -0,0 +1,19 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Generics
+{
+    public interface IValue
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "value")]
+        object Value { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "valueType")]
+        DataType ValueType { get; }
+        T ToObject<T>();
+    }
+
+    public interface IValue<out T> : IValue
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "value")]
+        new T Value { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Argument.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Argument.cs
new file mode 100644
index 0000000..b05f0b7
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Argument.cs
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Constraints;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class Argument : IArgument
+    {
+        public virtual object Value { get; set; }
+        public virtual DataType ValueType { get; set; }
+        public int? Index { get; set; }
+        public string IdShort { get; set; }
+        public List<IConstraint> Constraints { get; set; }
+        public IReference SemanticId { get; set; }
+
+        public Argument()
+        { }
+
+        public Argument(IOperationVariable param, object value)
+        {
+            this.ValueType = param.DataType;
+            this.IdShort = param.IdShort;
+            this.Index = param.Index;
+            this.Constraints = param.Constraints;
+            this.SemanticId = param.SemanticId;
+            this.Value = value;
+            this.Constraints = param.Constraints;
+        }
+
+        public T ToObject<T>()
+        {
+            return new DataElementValue(Value, ValueType).ToObject<T>();
+        }
+    }
+
+    [DataContract]
+    public class Argument<TInnerType> : Argument, IValue<TInnerType>
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "valueType")]
+        public override DataType ValueType => DataType.GetDataTypeFromSystemTypes(typeof(TInnerType));
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "value")]
+        public virtual new TInnerType Value
+        {
+            get
+            {
+                if (base.Value != null)
+                    return (TInnerType)base.Value;
+                else
+                    return default(TInnerType);
+            }
+            set => base.Value = value;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Asset.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Asset.cs
new file mode 100644
index 0000000..2809f3b
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Asset.cs
@@ -0,0 +1,27 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class Asset : IAsset
+    {
+        public string IdShort { get; set; }
+        public Identifier Identification { get; set; }
+        public Kind? Kind { get; set; }    
+        public List<Description> Descriptions { get; set; }
+        public IReference Parent { get; set; }
+        public Dictionary<string, string> MetaData { get; set; }
+        public IReference<ISubmodel> AssetIdentificationModel { get; set; }
+        public AdministrativeInformation Administration { get; set; }
+        public string Category { get; set; }
+        public IReference SemanticId { get; set; }
+        public List<IEmbeddedDataSpecification> EmbeddedDataSpecifications { get; }
+        public IConceptDescription ConceptDescription { get; set; }
+        public ModelType ModelType => ModelType.Asset;
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/AssetAdministrationShell.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/AssetAdministrationShell.cs
new file mode 100644
index 0000000..0234a1c
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/AssetAdministrationShell.cs
@@ -0,0 +1,33 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Attributes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Core.Views;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class AssetAdministrationShell : IAssetAdministrationShell
+    {
+        public string IdShort { get; set; }
+        public Identifier Identification { get; set; }
+        [ExportAsReference(KeyElements.Asset)]
+        public IAsset Asset { get; set; }
+        [ExportAsReference(KeyElements.Submodel)]
+        public ElementContainer<ISubmodel> Submodels { get; set; }
+        public IReference Parent { get; set; }
+        public List<Description> Descriptions { get; set; }
+        public Dictionary<string, string> MetaData { get; set; }        
+        public IReference<IAssetAdministrationShell> DerivedFrom { get; set; }     
+        public ElementContainer<IView> Views { get; set; }
+        public AdministrativeInformation Administration { get; set; }
+        public string Category { get; set; }
+        public ModelType ModelType => ModelType.AssetAdministationShell;
+        public List<IEmbeddedDataSpecification> EmbeddedDataSpecifications { get; }
+        public List<ConceptDictionary> ConceptDictionaries { get; set; }
+        public IConceptDescription ConceptDescription { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/ConceptDescription.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/ConceptDescription.cs
new file mode 100644
index 0000000..b52ab4f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/ConceptDescription.cs
@@ -0,0 +1,35 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Semantics;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    public class ConceptDescription : IConceptDescription
+    {
+        public List<IEmbeddedDataSpecification> EmbeddedDataSpecifications { get; set; }
+
+        public List<IReference> IsCaseOf { get; set; }
+
+        public Identifier Identification { get; set; }
+
+        public AdministrativeInformation Administration { get; set; }
+
+        public string IdShort { get; set; }
+
+        public string Category { get; set; }
+
+        public List<Description> Descriptions { get; set; }
+
+        public IReference Parent { get; set; }
+
+        public Dictionary<string, string> MetaData { get; set; }
+
+        public ModelType ModelType => ModelType.ConceptDescription;
+
+        IConceptDescription IHasDataSpecification.ConceptDescription => this;
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElement.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElement.cs
new file mode 100644
index 0000000..d8fd13c
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElement.cs
@@ -0,0 +1,52 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract, JsonConverter(typeof(DataElementValueConverter))]
+    public class DataElement : SubmodelElement, IDataElement
+    {
+        public virtual object Value { get; set; }
+        public virtual DataType ValueType { get; set; }
+        public override ModelType ModelType => ModelType.DataElement;
+
+        public DataElement(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications)
+        { }
+
+        public T ToObject<T>()
+        {
+            if (DataType.GetDataTypeFromSystemTypes(typeof(T)) == ValueType)
+                return (T)Value;
+            else
+                throw new InvalidCastException("Cannot convert " + DataType.GetDataTypeFromSystemTypes(typeof(T)).DataObjectType + " to " + ValueType.DataObjectType);
+        }
+    }
+    [DataContract]
+    public class DataElement<TValue> : DataElement, IDataElement<TValue>
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "value")]
+        public virtual new TValue Value
+        {
+            get
+            {
+                if (base.Value != null)
+                    return (TValue)base.Value;
+                else
+                    return default(TValue);
+            }
+            set => base.Value = value;
+        }
+
+        public DataElement() : this(null)  { }
+
+        [JsonConstructor]
+        public DataElement(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications)
+        { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementFactory.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementFactory.cs
new file mode 100644
index 0000000..3192890
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementFactory.cs
@@ -0,0 +1,26 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes;
+using System.Collections.Generic;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    public static class DataElementFactory
+    {
+        public static IDataElement CreateDataElement(IConceptDescription conceptDescription, List<IEmbeddedDataSpecification> embeddedDataSpecifications, DataObjectType modelType, DataType valueType = null)
+        {
+            if (modelType == ModelType.Property || modelType == DataObjectType.DateTime)
+                return new Property(valueType, conceptDescription, embeddedDataSpecifications.ToArray());
+            else if (modelType == ModelType.Blob)
+                return new Blob(conceptDescription, embeddedDataSpecifications.ToArray());
+            else if (modelType == ModelType.File)
+                return new File(conceptDescription, embeddedDataSpecifications.ToArray());
+            else if (modelType == ModelType.ReferenceElement)
+                return new ReferenceElement(conceptDescription, embeddedDataSpecifications.ToArray());
+            else if (modelType == ModelType.DataElementCollection)
+                return new DataElementCollection(conceptDescription, embeddedDataSpecifications.ToArray());
+            else
+                return null;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/Blob.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/Blob.cs
new file mode 100644
index 0000000..ab7ec38
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/Blob.cs
@@ -0,0 +1,19 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes
+{
+    [DataContract]
+    public class Blob : DataElement<byte[]>, IBlob
+    {
+        public override ModelType ModelType => ModelType.Blob;
+        public string MimeType { get; set; }
+        public Blob() : this(null) { }
+        [JsonConstructor]
+        public Blob(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications) { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/DataElementCollection.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/DataElementCollection.cs
new file mode 100644
index 0000000..a28c6cd
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/DataElementCollection.cs
@@ -0,0 +1,21 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes
+{
+    [DataContract]
+    public class DataElementCollection : DataElement<ElementContainer<IDataElement>>, IDataElementCollection
+    {
+        public override ModelType ModelType => ModelType.SubmodelElementCollection;
+        public override ElementContainer<IDataElement> Value { get => base.Value; set => base.Value = value; }
+
+        public DataElementCollection() : this(null) { }
+
+        [JsonConstructor]
+        public DataElementCollection(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications) { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/File.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/File.cs
new file mode 100644
index 0000000..550b4e3
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/File.cs
@@ -0,0 +1,19 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes
+{
+    [DataContract]
+    public class File : DataElement<string>, IFile
+    {
+        public override ModelType ModelType => ModelType.File;
+        public string MimeType { get; set; }
+        public File() : this(null) { }
+        [JsonConstructor]
+        public File(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications) { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/Property.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/Property.cs
new file mode 100644
index 0000000..d7baffc
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/Property.cs
@@ -0,0 +1,45 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes;
+using BaSys40.Models.Core.Extensions.References;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes
+{
+    [DataContract]
+    public class Property : DataElement, IProperty
+    {
+        public override ModelType ModelType => ModelType.Property;
+        public override object Value { get => base.Value; set => base.Value = value; }
+        public IReference ValueId { get; set; }
+
+        public Property(DataType valueType) : this(valueType, null, null)  { }
+
+        public Property(DataType valueType, IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications) : this(valueType, null, conceptDescription, embeddedDataSpecifications)
+        { }
+
+        [JsonConstructor]
+        public Property(DataType valueType, object value, IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications) : base(conceptDescription, embeddedDataSpecifications)
+        {
+            ValueType = valueType;
+            Value = value;
+        }
+    }
+
+    [DataContract]
+    public class Property<TInnerType> : DataElement<TInnerType>, IProperty<TInnerType>
+    {
+        public override ModelType ModelType => ModelType.Property;
+        public override TInnerType Value { get => base.Value; set => base.Value = value; }
+        public override DataType ValueType => DataType.GetDataTypeFromSystemTypes(typeof(TInnerType));
+        public IReference ValueId { get; set; }
+
+        public Property() : this(null)  { }
+
+        [JsonConstructor]
+        public Property(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications) { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/ReferenceElement.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/ReferenceElement.cs
new file mode 100644
index 0000000..245cf98
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementSubtypes/ReferenceElement.cs
@@ -0,0 +1,20 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics.DataElementSubtypes;
+using BaSys40.Models.Core.Extensions.References;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes
+{
+    [DataContract]
+    public class ReferenceElement : DataElement<IReference>, IReferenceElement<IReference>
+    {
+        public override ModelType ModelType => ModelType.ReferenceElement;
+
+        public ReferenceElement() : this(null) { }
+        [JsonConstructor]
+        public ReferenceElement(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications) { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementValue.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementValue.cs
new file mode 100644
index 0000000..bbf9d1c
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementValue.cs
@@ -0,0 +1,66 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class DataElementValue : IValue
+    {
+        public object Value { get; set; }
+        public DataType ValueType { get; protected set; }
+
+        [JsonConstructor]
+        public DataElementValue(object value, DataType dataType)
+        {
+            Value = value;
+            ValueType = dataType;
+        }
+
+        public T ToObject<T>()
+        {
+            if (Value is T)
+                return (T)Value;
+            else
+            {
+                try
+                {
+                    Value = Convert.ChangeType(Value, DataType.GetSystemTypeFromDataType(ValueType));
+                    return (T)Value;
+                }
+                catch (Exception e)
+                {
+                    try
+                    {
+                        var jVal = JValue.Parse(Value.ToString());
+                        var convertedVal = jVal.ToObject<T>();
+                        return convertedVal;
+                    }
+                    catch (Exception)
+                    {
+                        throw new InvalidCastException("Cannot convert " + DataType.GetDataTypeFromSystemTypes(typeof(T)).DataObjectType + " to " + ValueType.DataObjectType + "- Exception: " + e.Message);
+                    }
+                }
+            }
+        }
+    }
+    [DataContract]
+    public class DataElementValue<TValue> : DataElementValue, IValue<TValue>
+    {
+        public new TValue Value { get; set; }
+
+        public DataElementValue() : this(default(TValue), DataType.GetDataTypeFromSystemTypes(typeof(TValue)))
+        { }
+
+        public DataElementValue(TValue value) : this(value, DataType.GetDataTypeFromSystemTypes(typeof(TValue)))
+        { }
+
+        public DataElementValue(TValue value, DataType dataType) : base(value, dataType)
+        {
+            Value = value;
+            ValueType = dataType;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementValueConverter.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementValueConverter.cs
new file mode 100644
index 0000000..08c32b2
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataElementValueConverter.cs
@@ -0,0 +1,106 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Attributes;
+using BaSys40.Models.Core.Extensions.References;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    public class DataElementValueConverter : JsonConverter<IDataElement>
+    {
+        static Dictionary<string, Type> DataElementInformationTypes;
+        static DataElementValueConverter()
+        {
+            DataElementInformationTypes = new Dictionary<string, Type>();
+            var types = typeof(DataElementValueConverter).Assembly.GetTypes();
+            foreach (Type type in types)
+            {
+                var attrib = type.GetCustomAttribute(typeof(DataSpecificationAttribute), false);
+                if(attrib != null && attrib is DataSpecificationAttribute dataSpecificationAttribute)
+                {
+                    DataElementInformationTypes.Add(dataSpecificationAttribute.Reference.First.Value, type);
+                }
+            }
+
+        }
+
+        public override bool CanWrite => false;
+        public override bool CanRead => true;
+
+        public override IDataElement ReadJson(JsonReader reader, Type objectType, IDataElement existingValue, bool hasExistingValue, JsonSerializer serializer)
+        {
+            JObject jObject;
+
+            try
+            {
+                jObject = JObject.Load(reader);
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+
+            var modelTypeToken = jObject.SelectToken("modelType")?.ToObject<ModelType>();
+            var valueTypeToken = jObject.SelectToken("valueType")?.ToObject<DataType>();
+            var embeddedDataSpecificationsToken = jObject.SelectToken("embeddedDataSpecifications");
+            var conceptDescriptionToken = jObject.SelectToken("conceptDescription");
+
+            IDataElement dataElement;
+            List<IEmbeddedDataSpecification> embeddedDataSpecifications = null;
+            ConceptDescription conceptDescription = null;
+            var embeddedDataSpecificationsTokenChildToken = embeddedDataSpecificationsToken?.Children();
+            if (embeddedDataSpecificationsTokenChildToken != null) //
+            {
+                embeddedDataSpecifications = new List<IEmbeddedDataSpecification>();
+                foreach (var dataSpecificationToken in embeddedDataSpecificationsTokenChildToken)
+                {
+                    var dataSpecReference = dataSpecificationToken.SelectToken("hasDataSpecification")?.ToObject<Reference>();
+                    if (dataSpecReference != null && DataElementInformationTypes.TryGetValue(dataSpecReference.First.Value, out Type type))
+                    {
+                        var content = dataSpecificationToken.SelectToken("dataSpecificationContent")?.ToObject(type);
+                        if (content != null)
+                            embeddedDataSpecifications.Add((IEmbeddedDataSpecification)content);
+                    }
+                }
+                jObject.Remove("embeddedDataSpecifications");
+            }
+            if(conceptDescriptionToken != null)
+            {
+                var dataSpecifications = conceptDescriptionToken.SelectToken("embeddedDataSpecifications")?.Children();
+                if(dataSpecifications != null)
+                {
+                    conceptDescription.EmbeddedDataSpecifications = new List<IEmbeddedDataSpecification>();
+                    foreach (var dataSpecificationToken in dataSpecifications)
+                    {
+                        var dataSpecReference = dataSpecificationToken.SelectToken("hasDataSpecification")?.ToObject<Reference>();
+                        if (dataSpecReference != null && DataElementInformationTypes.TryGetValue(dataSpecReference.First.Value, out Type type))
+                        {
+                            var content = dataSpecificationToken.SelectToken("dataSpecificationContent")?.ToObject(type);
+                            if (content != null)
+                                conceptDescription.EmbeddedDataSpecifications.Add((IEmbeddedDataSpecification)content);
+                        }
+                    }
+                }
+                serializer.Populate(conceptDescriptionToken.CreateReader(), conceptDescription);
+            }
+
+            if (modelTypeToken != null)
+                dataElement = DataElementFactory.CreateDataElement(conceptDescription, embeddedDataSpecifications, modelTypeToken, valueTypeToken);
+            else
+                return null;
+            
+            serializer.Populate(jObject.CreateReader(), dataElement);
+
+            return dataElement;            
+        }
+
+        public override void WriteJson(JsonWriter writer, IDataElement value, JsonSerializer serializer)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataSpecifications/DataSpecification_IEC61360.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataSpecifications/DataSpecification_IEC61360.cs
new file mode 100644
index 0000000..3985a55
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataSpecifications/DataSpecification_IEC61360.cs
@@ -0,0 +1,60 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Attributes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataSpecifications
+{
+    [DataContract, DataSpecification("www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360")]
+    public class DataSpecification_IEC61360 : IEmbeddedDataSpecification
+    {
+        public IReference HasDataSpecification => new Reference(
+            new GlobalKey(KeyElements.GlobalReference, KeyType.URI, "www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360"));
+        public IDataSpecificationContent DataSpecificationContent { get; set; }
+    }
+
+    [DataContract]
+    public class DataSpecification_IEC61360_Content : IDataSpecificationContent
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name ="dataType")]
+        public string DataType { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "Definition")]
+        public LangString Definition { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "preferredName")]
+        public LangString PreferredName { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "shortName")]
+        public string ShortName { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "sourceOfDefinition")]
+        public LangString SourceOfDefinition { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "symbol")]
+        public string Symbol { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "code")]
+        public Code Code { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "unit")]
+        public string Unit { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "unitId")]
+        public IReference UnitId { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "valueFormat")]
+        public string ValueFormat { get; set; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "valueList")]
+        public List<object> ValueList { get; set; }
+    }
+
+    public enum Code
+    {
+
+    }
+
+    public class LangString
+    {
+        public string Language { get; set; }
+        public string Text { get; set; }
+        public LangString(string language, string text)
+        {
+            Language = language;
+            Text = text;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataSpecifications/EndpointSpecification.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataSpecifications/EndpointSpecification.cs
new file mode 100644
index 0000000..739d55c
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/DataSpecifications/EndpointSpecification.cs
@@ -0,0 +1,25 @@
+using BaSys40.Models.Connectivity;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Attributes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataSpecifications
+{
+    [DataContract, DataSpecification("www.basys.org/DataSpecifications/EndpointSpecification")]
+    public class EndpointSpecification : IEmbeddedDataSpecification
+    {
+        public IReference HasDataSpecification => new Reference(
+        new GlobalKey(KeyElements.GlobalReference, KeyType.URI, "www.basys.org/DataSpecifications/EndpointSpecification"));
+        public IDataSpecificationContent DataSpecificationContent { get; set; }
+    }
+
+    [DataContract]
+    public class EndpointSpecificationContent : IDataSpecificationContent
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "endpoints")]
+        public List<IEndpoint> Endpoints { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/ElementContainer.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/ElementContainer.cs
new file mode 100644
index 0000000..c6b14ab
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/ElementContainer.cs
@@ -0,0 +1,66 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Utils.ResultHandling;
+using System.Collections.Generic;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    public class ElementContainer<T> : List<T>, IElementContainer<string, T> where T : IReferable
+    {
+        public Dictionary<string, string> MetaData { get; set; }
+        public AdministrativeInformation Administration { get; set; }
+        public string IdShort { get; set; }
+        public string Category { get; set; }
+        public List<Description> Descriptions { get; set; }
+        public IReference Parent { get; set; }
+        public ModelType ModelElementType => ModelType.DataElementCollection;
+
+        public T this[string idShort] => this.Find(e => e.IdShort == idShort);
+
+        public virtual IResult<T> Create(T element)
+        {
+            Add(element);            
+            return new Result<T>(true, element);
+        }
+        public virtual IResult<ElementContainer<T>> RetrieveAll()
+        {
+            if (Count == 0)
+                return new Result<ElementContainer<T>>(true, new EmptyMessage());
+            else
+                return new Result<ElementContainer<T>>(true, this);
+        }
+
+
+        public virtual IResult<T> Retrieve(string id)
+        {
+            var element = this[id];
+            if (element != null)
+                return new Result<T>(true, element);
+            else
+                return new Result<T>(false, new NotFoundMessage());
+        }
+
+        public virtual IResult<T> Update(string id, T element)
+        {
+            var index = FindIndex(e => e.IdShort == id);
+            if (index != -1)
+            {
+                this[index] = element;
+                return new Result<T>(true, element);
+            }
+            return new Result<T>(false, new NotFoundMessage());
+        }
+
+        public virtual IResult Delete(string id)
+        {
+            var index = FindIndex(e => e.IdShort == id);
+            if (index != -1)
+            {
+                RemoveAt(index);
+                return new Result(true);
+            }
+            return new Result(false, new NotFoundMessage());
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Event.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Event.cs
new file mode 100644
index 0000000..4bdf2ca
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Event.cs
@@ -0,0 +1,22 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class Event : SubmodelElement, IEvent
+    {
+        public DataType DataType { get; set; }
+
+        public override ModelType ModelType => ModelType.Event;
+
+        public Event() : base()
+        { }
+        [JsonConstructor]
+        public Event(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications) 
+            : base(conceptDescription, embeddedDataSpecifications)
+        { }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Operation.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Operation.cs
new file mode 100644
index 0000000..6037f8c
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/Operation.cs
@@ -0,0 +1,24 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class Operation : SubmodelElement, IOperation
+    {
+        public List<IOperationVariable> In { get; set; }
+        public List<IOperationVariable> Out { get; set; }
+
+        public override ModelType ModelType => ModelType.Operation;
+
+        public Operation() : base()
+        { }
+
+        [JsonConstructor]
+        public Operation(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications)
+        { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/OperationVariable.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/OperationVariable.cs
new file mode 100644
index 0000000..2e81d5e
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/OperationVariable.cs
@@ -0,0 +1,27 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class OperationVariable : SubmodelElement, IOperationVariable
+    {
+        public int? Index { get; set; }
+        public virtual DataType DataType { get; set; }
+        public override ModelType ModelType => ModelType.OperationVariable;
+        public new Kind? Kind => Enums.Kind.Type;
+
+        public OperationVariable() : base()
+        { }
+        public OperationVariable(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications)
+        { }
+    }
+
+    [DataContract]
+    public class OperationVariable<TInnerType> : OperationVariable
+    {
+        public override DataType DataType => DataType.GetDataTypeFromSystemTypes(typeof(TInnerType));
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/RelationshipElement.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/RelationshipElement.cs
new file mode 100644
index 0000000..58a4b7f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/RelationshipElement.cs
@@ -0,0 +1,15 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    public class RelationshipElement : SubmodelElement, IRelationshipElement
+    {
+        public override ModelType ModelType => ModelType.RelationshipElement;
+
+        public Reference<IReferable> First { get; set; }
+
+        public Reference<IReferable> Second { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubModel.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubModel.cs
new file mode 100644
index 0000000..fb6ffd8
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubModel.cs
@@ -0,0 +1,31 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class Submodel : ISubmodel
+    {
+        public string IdShort { get; set; }
+        public Identifier Identification { get; set; }
+        public IReference Parent { get; set; }
+        public Kind? Kind { get; set; }
+        public IReference SemanticId { get; set; }
+        public List<Description> Descriptions { get; set; }
+        public ElementContainer<IDataElement> DataElements { get; set; }
+        public ElementContainer<IOperation> Operations { get; set; }
+        public ElementContainer<IEvent> Events { get; set; }
+        public ElementContainer<ISubmodelElement> SubmodelElements { get; set; }
+        public Dictionary<string, string> MetaData { get; set; }
+        public AdministrativeInformation Administration { get; set; }
+        public string Category { get; set; }
+        public ModelType ModelType => ModelType.Submodel;
+        public List<IEmbeddedDataSpecification> EmbeddedDataSpecifications { get; set; }
+        public IConceptDescription ConceptDescription { get; set; }
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubmodelElement.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubmodelElement.cs
new file mode 100644
index 0000000..b55c4d5
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubmodelElement.cs
@@ -0,0 +1,50 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Constraints;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public abstract class SubmodelElement : ISubmodelElement
+    {
+        public IReference SemanticId { get; set; }
+
+        public List<IConstraint> Constraints { get; set; }
+
+        public string IdShort { get; set; }
+
+        public string Category { get; set; }
+
+        public List<Description> Descriptions { get; set; }
+
+        public IReference Parent { get; set; }
+
+        public Dictionary<string, string> MetaData { get; set; }
+
+        public Kind? Kind { get; set; }
+
+        public abstract ModelType ModelType { get; }
+
+        public List<IEmbeddedDataSpecification> EmbeddedDataSpecifications { get; set; }
+        public IConceptDescription ConceptDescription { get; set; }
+
+        public SubmodelElement() : this(null)
+        { }
+
+        [JsonConstructor]
+        public SubmodelElement(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+        {
+            ConceptDescription = conceptDescription;    
+            EmbeddedDataSpecifications = embeddedDataSpecifications?.ToList();
+
+            if (ConceptDescription?.EmbeddedDataSpecifications?.Count > 0)
+                EmbeddedDataSpecifications.AddRange(ConceptDescription.EmbeddedDataSpecifications);
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubmodelElementCollection.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubmodelElementCollection.cs
new file mode 100644
index 0000000..a916288
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/Implementations/SubmodelElementCollection.cs
@@ -0,0 +1,28 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell.Implementations
+{
+    [DataContract]
+    public class SubmodelElementCollection : DataElement<ElementContainer<ISubmodelElement>>
+    {
+        public override ModelType ModelType => ModelType.SubmodelElementCollection;
+        public override ElementContainer<ISubmodelElement> Value { get => base.Value; set => base.Value = value; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "allowDuplicates")]
+        public bool AllowDuplicates { get; set; } = false;
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "ordered")]
+        public bool Ordered { get; set; } = false;
+
+        public SubmodelElementCollection() : this(null) { }
+
+        [JsonConstructor]
+        public SubmodelElementCollection(IConceptDescription conceptDescription, params IEmbeddedDataSpecification[] embeddedDataSpecifications)
+            : base(conceptDescription, embeddedDataSpecifications)
+        { }
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/SubModelDescriptor.cs b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/SubModelDescriptor.cs
new file mode 100644
index 0000000..931993a
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/AssetAdministrationShell/SubModelDescriptor.cs
@@ -0,0 +1,79 @@
+using BaSys40.Models.Connectivity;
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Semantics;
+using BaSys40.Utils.PathHandling;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.AssetAdministrationShell
+{
+    [DataContract]
+    public class SubmodelDescriptor : IServiceDescriptor, IHasSemantics, ITypeable
+    {
+        public Identifier Identification { get; set; }
+        public Dictionary<string, string> MetaData { get; set; }
+        public AdministrativeInformation Administration { get; set; }
+        public string IdShort { get; set; }
+        public string Category { get; set; }
+        public List<Description> Descriptions { get; set; }
+        public IReference SemanticId { get; set; }
+        public Kind? Kind { get; set; }
+        public List<IEndpoint> Endpoints { get; private set; }
+        [IgnoreDataMember]
+        public IReference Parent => null;
+
+        public SubmodelDescriptor(string idShort, params IEndpoint[] endpoints)
+        {
+            IdShort = idShort;
+            HandleEndpoints(endpoints);
+        }
+
+        [JsonConstructor]
+        public SubmodelDescriptor(string idShort, List<IEndpoint> endpoints)
+        {
+            IdShort = idShort;
+            if(endpoints != null)
+                HandleEndpoints(endpoints.ToArray());
+        }
+
+        public SubmodelDescriptor(ISubmodel submodel, params IEndpoint[] endpoints)
+        {
+            Identification = submodel.Identification;
+            MetaData = submodel.MetaData;
+            Administration = submodel.Administration;
+            IdShort = submodel.IdShort;
+            Category = submodel.Category;
+            Descriptions = submodel.Descriptions;
+            SemanticId = submodel.SemanticId;
+            Kind = submodel.Kind;
+
+            HandleEndpoints(endpoints);
+        }
+
+        private void HandleEndpoints(IEndpoint[] endpoints)
+        {
+            if (endpoints == null)
+                return; 
+
+            var newEndpoints = new List<IEndpoint>();
+            foreach (var endpoint in endpoints)
+            {
+                if (!endpoint.Address.Contains("submodels"))
+                {
+                    string address = Path.GetFormattedEndpoint(endpoint.Address, "submodels", IdShort);
+                    var newEndpoint = EndpointFactory.CreateEndpoint(endpoint.Type, address, endpoint.Security);
+                    newEndpoints.Add(newEndpoint);
+                }
+                else
+                    newEndpoints.Add(endpoint);
+            }
+            Endpoints = newEndpoints;
+        }
+
+        
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Attributes/DataSpecificationAttribute.cs b/sdks/csnet/BaSys40.Models/Core/Attributes/DataSpecificationAttribute.cs
new file mode 100644
index 0000000..4ca55a1
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Attributes/DataSpecificationAttribute.cs
@@ -0,0 +1,23 @@
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using System;
+
+namespace BaSys40.Models.Core.Attributes
+{
+    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
+    sealed class DataSpecificationAttribute : Attribute
+    {
+        readonly IReference reference;
+
+        public DataSpecificationAttribute(string dataSpecificationReference)
+        {
+            reference = new Reference(
+                new GlobalKey(KeyElements.GlobalReference, KeyType.URI, dataSpecificationReference));
+        }
+
+        public IReference Reference
+        {
+            get { return reference; }
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Attributes/ExportAsReferenceAttribute.cs b/sdks/csnet/BaSys40.Models/Core/Attributes/ExportAsReferenceAttribute.cs
new file mode 100644
index 0000000..9313695
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Attributes/ExportAsReferenceAttribute.cs
@@ -0,0 +1,22 @@
+using BaSys40.Models.Core.Extensions.References;
+using System;
+
+namespace BaSys40.Models.Core.Attributes
+{
+    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Interface, Inherited = true, AllowMultiple = true)]
+    public sealed class ExportAsReferenceAttribute : Attribute
+    {
+        readonly KeyElements keyElement;
+        public ExportAsReferenceAttribute(KeyElements keyElement)
+        {
+            this.keyElement = keyElement;
+        }
+
+        public KeyElements KeyElement
+        {
+            get { return keyElement; }
+        }
+
+        public bool JsonSchemaIgnore { get; set; } = false;
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/Constraint.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/Constraint.cs
new file mode 100644
index 0000000..c73bca0
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/Constraint.cs
@@ -0,0 +1,14 @@
+using BaSys40.Models.Core.Identification;
+using Newtonsoft.Json;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    [JsonConverter(typeof(ConstraintConverter))]
+    public interface IConstraint : IModelElement
+    { } 
+
+    public abstract class Constraint : IConstraint
+    {
+        public abstract ModelType ModelType { get; }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/ConstraintConverter.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/ConstraintConverter.cs
new file mode 100644
index 0000000..635e5d7
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/ConstraintConverter.cs
@@ -0,0 +1,51 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    public class ConstraintConverter : JsonConverter<IConstraint>
+    {
+        public override bool CanWrite => false;
+        public override bool CanRead => true;
+
+        public override IConstraint ReadJson(JsonReader reader, Type objectType, IConstraint existingValue, bool hasExistingValue, JsonSerializer serializer)
+        {
+            JObject jObject;
+
+            try
+            {
+                jObject = JObject.Load(reader);
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+
+            var modelTypeToken = jObject.SelectToken("modelType")?.ToObject<ModelType>();
+
+            IConstraint constraint;
+
+            if (modelTypeToken != null)
+            {
+                if (modelTypeToken == ModelType.Qualifier)
+                    constraint = new Qualifier();
+                else if (modelTypeToken == ModelType.Formula)
+                    constraint = new Formula();
+                else
+                    return null;
+            }
+            else
+                return null;
+
+            serializer.Populate(jObject.CreateReader(), constraint);
+
+            return constraint;            
+        }
+
+        public override void WriteJson(JsonWriter writer, IConstraint value, JsonSerializer serializer)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/ExpressionLogic.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/ExpressionLogic.cs
new file mode 100644
index 0000000..dcbc7f7
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/ExpressionLogic.cs
@@ -0,0 +1,16 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    [DataContract]
+    public enum ExpressionLogic : int
+    {
+        None = 0,
+        Equal = 1,
+        NotEqual = 2,
+        GreaterThan = 3,
+        GreaterEqual = 4,
+        Less = 5,
+        LessEqual = 6 
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/ExpressionSemantic.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/ExpressionSemantic.cs
new file mode 100644
index 0000000..4f39f59
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/ExpressionSemantic.cs
@@ -0,0 +1,15 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    [DataContract]
+    public enum ExpressionSemantic : int
+    {
+        None = 0,
+        Requirement = 1,
+        Assurance = 2,
+        Confirmation = 3,
+        Measurement = 4,
+        Setting = 5
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/Formula.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/Formula.cs
new file mode 100644
index 0000000..cd91ac7
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/Formula.cs
@@ -0,0 +1,14 @@
+using BaSys40.Models.Core.Extensions.References;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    public class Formula : IConstraint, IFormula
+    {
+        public List<IReference> DependsOn { get; set; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = true, Name = "modelType")]
+        public ModelType ModelType => ModelType.Formula;
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/IFormula.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/IFormula.cs
new file mode 100644
index 0000000..038a8f3
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/IFormula.cs
@@ -0,0 +1,12 @@
+using BaSys40.Models.Core.Extensions.References;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    public interface IFormula : IConstraint
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "dependsOn")]
+        List<IReference> DependsOn { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/IQualifiable.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/IQualifiable.cs
new file mode 100644
index 0000000..ff22bd9
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/IQualifiable.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    public interface IQualifiable
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "constraints")]
+        List<IConstraint> Constraints { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/IQualifier.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/IQualifier.cs
new file mode 100644
index 0000000..ca38f69
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/IQualifier.cs
@@ -0,0 +1,16 @@
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Semantics;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    public interface IQualifier : IConstraint, IHasSemantics
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "qualifierType")]
+        string QualifierType { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "qualifierValue")]
+        object QualifierValue { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "qualifierValueId")]
+        IReference QualifierValueId { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/Qualifier.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/Qualifier.cs
new file mode 100644
index 0000000..2879990
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/Qualifier.cs
@@ -0,0 +1,17 @@
+using BaSys40.Models.Core.Extensions.References;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    [DataContract]
+    public class Qualifier : IConstraint, IQualifier
+    {
+        public string QualifierType { get; set; }
+
+        public object QualifierValue { get; set; }
+
+        public IReference SemanticId { get; set; }
+        public ModelType ModelType => ModelType.Qualifier;
+        public IReference QualifierValueId { get; set; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Constraints/QualifierType.cs b/sdks/csnet/BaSys40.Models/Core/Constraints/QualifierType.cs
new file mode 100644
index 0000000..8517d6a
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Constraints/QualifierType.cs
@@ -0,0 +1,19 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Constraints
+{
+    [DataContract]
+    public static class QualifierType
+    {
+        public const string ExpressionLogic = "ExpressionLogic";
+        public const string ExpressionSemantic = "ExpressionSemantic";
+        public const string Enumeration = "Enumeration";
+        public const string Owner = "Owner";
+        public const string Min = "Min";
+        public const string Max = "Max";
+        public const string StrLen = "StrLen";
+        public const string MimeType = "MimeType";
+        public const string RegEx = "RegEx";
+        public const string Existence = "Existence";
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/DataObjectType.cs b/sdks/csnet/BaSys40.Models/Core/DataObjectType.cs
new file mode 100644
index 0000000..4481b55
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/DataObjectType.cs
@@ -0,0 +1,147 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core
+{
+    [DataContract]
+    public class DataObjectType : IEquatable<DataObjectType>
+    {
+        public static readonly DataObjectType None = new DataObjectType("none");
+
+        public static readonly DataObjectType AnyType = new DataObjectType("anyType");
+        public static readonly DataObjectType AnySimpleType = new DataObjectType("anySimpleType");
+
+        public static readonly DataObjectType UInt8 = new DataObjectType("unsignedByte");
+        public static readonly DataObjectType UInt16 = new DataObjectType("unsignedShort");
+        public static readonly DataObjectType UInt32 = new DataObjectType("unsignedInt");
+        public static readonly DataObjectType UInt64 = new DataObjectType("unsignedLong");
+
+        public static readonly DataObjectType Int8 = new DataObjectType("byte");
+        public static readonly DataObjectType Int16 = new DataObjectType("short");
+        public static readonly DataObjectType Int32 = new DataObjectType("int");
+        public static readonly DataObjectType Int64 = new DataObjectType("long");
+
+        public static readonly DataObjectType String = new DataObjectType("string");
+        public static readonly DataObjectType LangString = new DataObjectType("langString");
+
+        public static readonly DataObjectType Integer = new DataObjectType("integer");
+        public static readonly DataObjectType NonPositiveInteger = new DataObjectType("nonPositiveInteger");
+        public static readonly DataObjectType NonNegativeInteger = new DataObjectType("nonNegativeInteger");
+        public static readonly DataObjectType NegativeInteger = new DataObjectType("negativeInteger");
+        public static readonly DataObjectType PositiveInteger = new DataObjectType("positiveInteger");
+
+        public static readonly DataObjectType Decimal = new DataObjectType("decimal");
+        public static readonly DataObjectType Double = new DataObjectType("double");
+        public static readonly DataObjectType Float = new DataObjectType("float");
+        public static readonly DataObjectType Bool = new DataObjectType("boolean");
+
+        public static readonly DataObjectType Duration = new DataObjectType("duration");
+        public static readonly DataObjectType DayTimeDuration = new DataObjectType("dayTimeDuration");
+        public static readonly DataObjectType YearMonthDuration = new DataObjectType("yearMonthDuration");
+
+        public static readonly DataObjectType DateTime = new DataObjectType("dateTime");
+        public static readonly DataObjectType DateTimeStamp = new DataObjectType("dateTimeStamp");
+
+        public static readonly DataObjectType AnyURI = new DataObjectType("anyURI");
+        public static readonly DataObjectType Base64Binary = new DataObjectType("base64binary");
+        public static readonly DataObjectType HexBinary = new DataObjectType("hexBinary");
+
+        private static Dictionary<string, DataObjectType> DataObjectTypes;
+        static DataObjectType()
+        {
+            var fields = typeof(DataObjectType).GetFields(BindingFlags.Public | BindingFlags.Static);
+            DataObjectTypes = fields.ToDictionary(k => ((DataObjectType)k.GetValue(null)).Name, v => ((DataObjectType)v.GetValue(null)));
+        }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "name")]
+        public string Name { get; }
+
+       
+        [JsonConstructor]
+        protected DataObjectType(string name)
+        {
+            Name = name ?? throw new ArgumentNullException("name");
+        }
+
+        public static bool TryParse(string s, out DataObjectType dataObjectType)
+        {
+            if (DataObjectTypes.TryGetValue(s, out dataObjectType))
+                return true;
+            else
+                return false;
+        }
+
+        public override string ToString()
+        {
+            return Name;
+        }
+
+        public bool Equals(DataObjectType other)
+        {
+            if (ReferenceEquals(null, other))
+            {
+                return false;
+            }
+            if (ReferenceEquals(this, other))
+            {
+                return true;
+            }
+
+            return this.Name.Equals(other.Name);
+        }
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj))
+            {
+                return false;
+            }
+            if (ReferenceEquals(this, obj))
+            {
+                return true;
+            }
+
+            return obj.GetType() == GetType() && Equals((DataObjectType)obj);
+        }
+
+
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                var result = 0;
+                result = (result * 397) ^ Name.GetHashCode();
+                return result;
+            }
+        }
+
+        public static bool operator ==(DataObjectType x, DataObjectType y)
+        {
+
+            if (ReferenceEquals(x, y))
+            {
+                return true;
+            }
+
+            if (ReferenceEquals(x, null))
+            {
+                return false;
+            }
+            if (ReferenceEquals(y, null))
+            {
+                return false;
+            }
+
+            return x.Name == y.Name;
+        }
+        public static bool operator !=(DataObjectType x, DataObjectType y)
+        {
+            return !(x == y);
+        }
+    }
+
+    
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/DataType.cs b/sdks/csnet/BaSys40.Models/Core/DataType.cs
new file mode 100644
index 0000000..7891339
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/DataType.cs
@@ -0,0 +1,293 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Semantics;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core
+{
+
+    [DataContract]
+    public class DataType : IHasSemantics, IEquatable<DataType>
+    {
+        [IgnoreDataMember]
+        public bool? IsCollection { get; internal set; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "dataObjectType")]
+        public DataObjectType DataObjectType { get; internal set; }
+
+        [IgnoreDataMember]
+        public Type SystemType { get; internal set; }
+
+        public IReference SemanticId { get; internal set; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "schemaType")]
+        public SchemaType? SchemaType { get; internal set; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "schema")]
+        public string Schema { get; internal set; }
+
+
+        //[DataMember(EmitDefaultValue = false, IsRequired = false, Name = "valueRank")]
+        //public ValueRank? ValueRank { get; }
+
+        internal DataType() { }
+
+        public DataType(DataObjectType dataObjectType) : this(dataObjectType, false, null)
+        { }
+
+        [JsonConstructor]
+        public DataType(DataObjectType dataObjectType, bool? isCollection, IReference semanticId = null)
+        {
+            DataObjectType = dataObjectType;
+            SemanticId = semanticId;
+
+            SystemType = GetSystemTypeFromDataType(dataObjectType);
+
+            
+            if (isCollection.HasValue)
+                IsCollection = isCollection;
+            else
+                IsCollection = false;
+            
+        }
+        public DataType(IReference semanticId, SchemaType schemaType, string schema)
+            :this(DataObjectType.AnyType, false, semanticId)
+        {
+            SchemaType = schemaType;
+            Schema = schema;
+        }
+
+        
+        /*
+        public enum ValueRank : int
+        {
+            Scalar = -1,
+            OneDimensional = 1,
+            TwoDimensional = 2,
+            ScalarOrOneDimensional = 3
+        }
+        */
+        public static DataType GetDataTypeFromSystemTypes(Type type)
+        {
+            DataType dataType = new DataType();
+            Type innerType = null;
+
+            if (IsGenericList(type))
+            {
+                dataType.IsCollection = true;
+                innerType = type.GetGenericArguments()[0];
+            }
+            else if (IsArray(type))
+            {
+                dataType.IsCollection = true;
+                innerType = type.GetElementType();
+            }
+            else
+            {
+                dataType.IsCollection = false;
+                innerType = type;
+            }
+            dataType.SystemType = innerType;
+
+            switch (innerType.FullName)
+            {
+                case "System.Decimal": dataType.DataObjectType = DataObjectType.Decimal; break;
+                case "System.String": dataType.DataObjectType = DataObjectType.String; break;
+                case "System.SByte": dataType.DataObjectType = DataObjectType.Int8; break;
+                case "System.Int16": dataType.DataObjectType = DataObjectType.Int16; break;
+                case "System.Int32": dataType.DataObjectType = DataObjectType.Int32; break;
+                case "System.Int64": dataType.DataObjectType = DataObjectType.Int64; break;
+                case "System.Byte": dataType.DataObjectType = DataObjectType.UInt8; break;
+                case "System.UInt16": dataType.DataObjectType = DataObjectType.UInt16; break;
+                case "System.UInt32": dataType.DataObjectType = DataObjectType.UInt32; break;
+                case "System.UInt64": dataType.DataObjectType = DataObjectType.UInt64; break;
+                case "System.Boolean": dataType.DataObjectType = DataObjectType.Bool; break;
+                case "System.Single": dataType.DataObjectType = DataObjectType.Float; break;
+                case "System.Double": dataType.DataObjectType = DataObjectType.Double; break;
+                case "System.DateTime": dataType.DataObjectType = DataObjectType.DateTime; break;
+                case "System.Uri": dataType.DataObjectType = DataObjectType.AnyURI; break;
+                default:
+                    if (!IsSimpleType(innerType))
+                    {
+                        dataType.DataObjectType = DataObjectType.AnyType;
+                        return dataType;
+                    }
+                    else
+                        return null;
+            }
+            return dataType;
+        }
+
+        public static bool IsGenericList(Type type)
+        {
+            return (type.IsGenericType && (
+				type.GetGenericTypeDefinition() == typeof(List<>) || 
+				type.GetGenericTypeDefinition() == typeof(IEnumerable<>)));
+        }
+
+        public static bool IsArray(Type type)
+        {
+            return type.IsArray;
+        }
+
+        public static Type GetSystemTypeFromDataType(DataObjectType dataObjectType)
+        {
+            if (dataObjectType == DataObjectType.String)
+                return typeof(string);
+            if (dataObjectType == DataObjectType.LangString)
+                return typeof(string);
+            else if (dataObjectType == DataObjectType.Bool)
+                return typeof(bool);
+            else if (dataObjectType == DataObjectType.Float)
+                return typeof(float);
+            else if (dataObjectType == DataObjectType.Double)
+                return typeof(double);
+            else if (dataObjectType == DataObjectType.UInt8)
+                return typeof(byte);
+            else if (dataObjectType == DataObjectType.UInt16)
+                return typeof(UInt16);
+            else if (dataObjectType == DataObjectType.UInt32)
+                return typeof(UInt32);
+            else if (dataObjectType == DataObjectType.UInt64)
+                return typeof(UInt64);
+            else if (dataObjectType == DataObjectType.Int8)
+                return typeof(sbyte);
+            else if (dataObjectType == DataObjectType.Int16)
+                return typeof(Int16);
+            else if (dataObjectType == DataObjectType.Int32)
+                return typeof(Int32);
+            else if (dataObjectType == DataObjectType.Int64)
+                return typeof(Int64);
+            else if (dataObjectType == DataObjectType.Integer)
+                return typeof(decimal);
+            else if (dataObjectType == DataObjectType.NegativeInteger)
+                return typeof(decimal);
+            else if (dataObjectType == DataObjectType.PositiveInteger)
+                return typeof(decimal);
+            else if (dataObjectType == DataObjectType.NonNegativeInteger)
+                return typeof(decimal);
+            else if (dataObjectType == DataObjectType.NonPositiveInteger)
+                return typeof(decimal);
+            else if (dataObjectType == DataObjectType.AnyType)
+                return typeof(object);
+            else if (dataObjectType == DataObjectType.AnySimpleType)
+                return typeof(string);
+            else if (dataObjectType == DataObjectType.DateTime)
+                return typeof(DateTime);
+            else if (dataObjectType == DataObjectType.DateTimeStamp)
+                return typeof(DateTime);
+            else if (dataObjectType == DataObjectType.AnyURI)
+                return typeof(Uri);
+            else if (dataObjectType == DataObjectType.Base64Binary)
+                return typeof(byte[]);
+            else if (dataObjectType == DataObjectType.HexBinary)
+                return typeof(byte[]);
+            else if (dataObjectType == DataObjectType.Duration)
+                return typeof(TimeSpan);
+            else if (dataObjectType == DataObjectType.DayTimeDuration)
+                return typeof(TimeSpan);
+            else if (dataObjectType == DataObjectType.YearMonthDuration)
+                return typeof(TimeSpan);
+            else if (dataObjectType == ModelType.Property)
+                return typeof(Property);
+            else if (dataObjectType == ModelType.Blob)
+                return typeof(Blob);
+            else if (dataObjectType == ModelType.File)
+                return typeof(File);
+            else if (dataObjectType == ModelType.ReferenceElement)
+                return typeof(ReferenceElement);
+            else if (dataObjectType == ModelType.DataElementCollection)
+                return typeof(DataElementCollection);
+            else
+                return null;
+        }
+
+        public static Type GetSystemTypeFromDataType(DataType dataType)
+        {
+            return GetSystemTypeFromDataType(dataType.DataObjectType);
+        }
+        
+        public static bool IsSimpleType(Type type)
+        {
+            TypeInfo typeInfo = type.GetTypeInfo();
+            if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))
+                return IsSimpleType(typeInfo.GetGenericArguments()[0]);
+
+            return typeInfo.IsEnum || typeInfo.IsPrimitive || type.Equals(typeof(string)) || type.Equals(typeof(decimal));
+        }
+        #region IEquatable Interface Implementation
+        public bool Equals(DataType other)
+        {
+            if (ReferenceEquals(null, other))
+            {
+                return false;
+            }
+            if (ReferenceEquals(this, other))
+            {
+                return true;
+            }
+
+            return this.DataObjectType.Equals(other.DataObjectType)
+                   && this.IsCollection.Equals(other.IsCollection);
+        }
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj))
+            {
+                return false;
+            }
+            if (ReferenceEquals(this, obj))
+            {
+                return true;
+            }
+
+            return obj.GetType() == GetType() && Equals((DataType)obj);
+        }
+
+
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                var result = 0;
+                result = (result * 397) ^ DataObjectType.GetHashCode();
+                result = (result * 397) ^ (IsCollection.Value ? 1 : 0);
+                return result;
+            }
+        }
+
+        public static bool operator ==(DataType x, DataType y)
+        {
+
+            if (ReferenceEquals(x, y))
+            {
+                return true;
+            }
+
+            if (ReferenceEquals(x, null))
+            {
+                return false;
+            }
+            if (ReferenceEquals(y, null))
+            {
+                return false;
+            }
+
+            return x.DataObjectType == y.DataObjectType && x.IsCollection == y.IsCollection;
+        }
+        public static bool operator !=(DataType x, DataType y)
+        {
+            return !(x == y);
+        }
+        #endregion
+
+    }
+
+
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Extensions/References/GlobalKey.cs b/sdks/csnet/BaSys40.Models/Core/Extensions/References/GlobalKey.cs
new file mode 100644
index 0000000..d578502
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Extensions/References/GlobalKey.cs
@@ -0,0 +1,10 @@
+using BaSys40.Models.Core.Identification;
+
+namespace BaSys40.Models.Core.Extensions.References
+{
+    public class GlobalKey : Key
+    {
+        public GlobalKey(KeyElements type, KeyType idType, string value) : base(type, idType, value, false)
+        { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Extensions/References/IKey.cs b/sdks/csnet/BaSys40.Models/Core/Extensions/References/IKey.cs
new file mode 100644
index 0000000..f6e88a9
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Extensions/References/IKey.cs
@@ -0,0 +1,19 @@
+using BaSys40.Models.Core.Identification;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Extensions.References
+{
+    public interface IKey
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "type")]
+        KeyElements? Type { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "idType")]
+        KeyType? IdType { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "value")]
+        string Value { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "local")]
+        bool? Local { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "index")]
+        int? Index { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/Extensions/References/IReference.cs b/sdks/csnet/BaSys40.Models/Core/Extensions/References/IReference.cs
new file mode 100644
index 0000000..1d3ca24
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Extensions/References/IReference.cs
@@ -0,0 +1,18 @@
+using BaSys40.Models.Core.Identification;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Extensions.References
+{
+    public interface IReference
+    {
+        [IgnoreDataMember]
+        IKey First { get; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "keys")]
+        List<IKey> Keys { get;}
+    }
+
+    public interface IReference<out T> : IReference where T : IReferable
+    { }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Extensions/References/Key.cs b/sdks/csnet/BaSys40.Models/Core/Extensions/References/Key.cs
new file mode 100644
index 0000000..37bf7de
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Extensions/References/Key.cs
@@ -0,0 +1,135 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Core.Views;
+using Newtonsoft.Json;
+using System;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Extensions.References
+{
+    [DataContract]
+    public class Key : IKey, IEquatable<Key>
+    {
+        public KeyElements? Type { get; }
+        public KeyType? IdType { get; }
+        public string Value { get; }
+        public bool? Local { get; }
+        public int? Index { get; set; }
+
+        protected Key() { }
+
+        [JsonConstructor]
+        public Key(KeyElements type, KeyType idType, string value, bool local)
+        {
+            Type = type;
+            IdType = idType;
+            Value = value;
+            Local = local;
+        }
+
+        public static KeyElements GetReferableElement(Type type)
+        {
+            if (typeof(IAsset).IsAssignableFrom(type))
+                return KeyElements.Asset;
+            else if (typeof(IAssetAdministrationShell).IsAssignableFrom(type))
+                return KeyElements.AssetAdministrationShell;
+            else if (typeof(ISubmodel).IsAssignableFrom(type))
+                return KeyElements.Submodel;
+            else if (typeof(IView).IsAssignableFrom(type))
+                return KeyElements.View;
+            else if (typeof(IDataElement).IsAssignableFrom(type))
+                return KeyElements.Property;
+            else if (typeof(IOperation).IsAssignableFrom(type))
+                return KeyElements.Operation;
+            else if (typeof(IEvent).IsAssignableFrom(type))
+                return KeyElements.Event;
+            else if (typeof(IConceptDescription).IsAssignableFrom(type))
+                return KeyElements.ConceptDescription;
+            else
+                throw new InvalidOperationException("Cannot convert type " + type.FullName + "to referable element");
+        }
+
+        #region IEquatable
+        public bool Equals(Key other)
+        {
+            if (ReferenceEquals(null, other))
+            {
+                return false;
+            }
+            if (ReferenceEquals(this, other))
+            {
+                return true;
+            }
+
+            return this.IdType.Equals(other.IdType)
+                && this.Index.Equals(other.Index)
+                && this.Local.Equals(other.Local)
+                && this.Type.Equals(other.Type)
+                && this.Value.Equals(other.Type);
+        }
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj))
+            {
+                return false;
+            }
+            if (ReferenceEquals(this, obj))
+            {
+                return true;
+            }
+
+            return obj.GetType() == GetType() && Equals((Key)obj);
+        }
+
+
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                var result = 0;
+                result = (result * 397) ^ IdType.GetHashCode();
+                result = (result * 397) ^ Index.GetHashCode();
+                result = (result * 397) ^ Type.GetHashCode();
+                result = (result * 397) ^ (Local.Value ? 1 : 0);
+                return result;
+            }
+        }
+
+        public static bool operator ==(Key x, Key y)
+        {
+
+            if (ReferenceEquals(x, y))
+            {
+                return true;
+            }
+
+            if (ReferenceEquals(x, null))
+            {
+                return false;
+            }
+            if (ReferenceEquals(y, null))
+            {
+                return false;
+            }
+
+            return x.IdType == y.IdType
+                && x.Index == y.Index
+                && x.Local == y.Local
+                && x.Type == y.Type
+                && x.Value == y.Value;
+        }
+        public static bool operator !=(Key x, Key y)
+        {
+            return !(x == y);
+        }
+        #endregion
+    }
+
+    [DataContract]
+    public class Key<T> : Key
+    {
+        public Key(KeyType idType, string value, bool local) : base(GetReferableElement(typeof(T)), idType, value, local)
+        { }
+    }
+
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/Extensions/References/KeyElements.cs b/sdks/csnet/BaSys40.Models/Core/Extensions/References/KeyElements.cs
new file mode 100644
index 0000000..e309dc0
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Extensions/References/KeyElements.cs
@@ -0,0 +1,30 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Extensions.References
+{    
+    [DataContract]
+    public enum KeyElements : int
+    {
+        GlobalReference,
+
+        ConceptDictionary,
+        AccessPermissionRule,
+        DataElement,
+        View,
+        Property,
+        SubmodelElement,
+        File,
+        Blob,
+        ReferenceElement,
+        SubmodelElementCollection,
+        RelationshipElement,
+        Event,
+        Operation,
+        OperationParameter,
+
+        AssetAdministrationShell,
+        Submodel,
+        ConceptDescription,
+        Asset
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/Extensions/References/ModelKey.cs b/sdks/csnet/BaSys40.Models/Core/Extensions/References/ModelKey.cs
new file mode 100644
index 0000000..4b8cc2d
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Extensions/References/ModelKey.cs
@@ -0,0 +1,10 @@
+using BaSys40.Models.Core.Identification;
+
+namespace BaSys40.Models.Core.Extensions.References
+{
+    public class ModelKey : Key
+    {
+        public ModelKey(KeyElements type, KeyType idType, string value) : base(type, idType, value, true)
+        { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Extensions/References/Reference.cs b/sdks/csnet/BaSys40.Models/Core/Extensions/References/Reference.cs
new file mode 100644
index 0000000..3e36baf
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Extensions/References/Reference.cs
@@ -0,0 +1,81 @@
+using BaSys40.Models.Core.Identification;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Extensions.References
+{
+    [DataContract]
+    public class Reference : IReference
+    {
+
+        [IgnoreDataMember]
+        public IKey First
+        {
+            get
+            {
+                if (Keys?.Count > 0)
+                    return Keys.First();
+                return null;
+            }
+        }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "keys")]
+        public List<IKey> Keys { get; protected set; }
+
+        [JsonConstructor]
+        public Reference(params IKey[] keys)
+        {
+            if (keys == null)
+                throw new ArgumentNullException("keys");
+
+
+            for (int i = 0; i < keys.Count(); i++)
+                keys[i].Index = i;
+
+            if (Keys?.Count > 0)
+            {
+                foreach (var key in keys)
+                    if (!Keys.Contains(key))
+                        Keys.Add(key);
+            }
+            else
+                Keys = keys.ToList();
+        }
+    }
+
+    [DataContract]
+    public class Reference<T> : Reference, IReference<T> where T : IReferable
+    {
+        [JsonConstructor]
+        private Reference(params IKey[] keys) : base(keys)
+        { }
+
+        public Reference(T element)
+        {
+            if (element == null)
+                throw new ArgumentNullException("element");
+
+            var keys = new List<IKey>();
+
+            if (element is IIdentifiable identifiable)
+            {
+                keys.Add(new ModelKey(Key.GetReferableElement(identifiable.GetType()), identifiable.Identification.IdType.Value, identifiable.Identification.Id));
+            }
+            else if (element is IReferable referable)
+            {
+                if (referable.Parent != null && referable.Parent is IIdentifiable parentIdentifiable)
+                    keys.Add(new ModelKey(Key.GetReferableElement(parentIdentifiable.GetType()), parentIdentifiable.Identification.IdType.Value, parentIdentifiable.Identification.Id));
+
+                keys.Add(new ModelKey(Key.GetReferableElement(referable.GetType()), KeyType.IdShort, referable.IdShort));
+            }
+
+            for (int i = 0; i < keys.Count(); i++)
+                keys[i].Index = i;
+
+            Keys = keys.ToList();
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Extensions/Topology.cs b/sdks/csnet/BaSys40.Models/Core/Extensions/Topology.cs
new file mode 100644
index 0000000..8fcf619
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Extensions/Topology.cs
@@ -0,0 +1,81 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Extensions
+{
+    [DataContract]
+    public class Topology : Submodel
+    {
+        [IgnoreDataMember]
+        public List<TopologyElement> TopologyElements { get; private set; } 
+        [IgnoreDataMember]
+        public List<TopologyRelation> TopologyRelations { get; private set; }
+
+        public Topology()
+        { }
+
+        public void InitializeSubmodel()
+        {
+            Identification = Identification ?? new Identifier(Guid.NewGuid().ToString(), KeyType.Custom);
+            IdShort = IdShort ?? "Topology";
+            Descriptions = Descriptions ?? new List<Description>() { new Description("EN", "Topology Submodel") };
+            Kind = Kind ?? AssetAdministrationShell.Enums.Kind.Instance;
+            SemanticId = SemanticId ?? new Reference(new ModelKey(KeyElements.Submodel, KeyType.URI, "urn:basys:org.eclipse.basyx:submodels:Topology:1.0.0"));
+            DataElements = DataElements ?? new ElementContainer<IDataElement>()
+            {
+                new DataElementCollection(null)
+                {
+                    IdShort = "TopologyElements",
+                    Parent = new Reference(new ModelKey(KeyElements.Submodel, Identification.IdType.Value, Identification.Id)),
+                    Descriptions = new List<Description>() { new Description("EN", "Elements of Topology") },
+                }
+            };
+        }
+
+        public void AddTopologyElements(List<TopologyElement> topologyElements)
+        {
+            if (topologyElements != null)
+                foreach (var topologyElement in topologyElements)
+                {
+                    (this.DataElements["TopologyElements"] as DataElementCollection).Value.Add(
+                        new ReferenceElement(null)
+                        {
+                            Value = topologyElement.Reference
+                        });
+                }
+            TopologyElements = topologyElements;
+        }
+
+        [DataContract]
+        public class TopologyElement
+        {
+            [DataMember]
+            public Reference Reference { get; set; }
+        }
+
+        [DataContract]
+        public class TopologyRelation
+        {
+            [DataMember]
+            public TopologyElement Source { get; set; }
+            [DataMember]
+            public TopologyElement Target { get; set; }
+        }
+
+        public class BaSysRelationship : TopologyRelation
+        { }
+        public class ConnectedTo : BaSysRelationship
+        { }
+        public class RelativePositionFrom : BaSysRelationship
+        { }
+        public class ConsistsOf : BaSysRelationship
+        { }
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Identification/AdministrativeInformation.cs b/sdks/csnet/BaSys40.Models/Core/Identification/AdministrativeInformation.cs
new file mode 100644
index 0000000..4ae4163
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Identification/AdministrativeInformation.cs
@@ -0,0 +1,13 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Identification
+{
+    [DataContract]
+    public class AdministrativeInformation
+    {
+        [DataMember]
+        public string Version { get; set; }
+        [DataMember]
+        public string Revision { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/Identification/Description.cs b/sdks/csnet/BaSys40.Models/Core/Identification/Description.cs
new file mode 100644
index 0000000..d3a481f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Identification/Description.cs
@@ -0,0 +1,20 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Identification
+{
+    [DataContract]
+    public class Description
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "language")]
+        public string Language { get; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "text")]
+        public string Text { get; }
+
+        public Description(string language, string text)
+        {
+            Language = language;
+            Text = text;
+        }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Models/Core/Identification/IIdentifiable.cs b/sdks/csnet/BaSys40.Models/Core/Identification/IIdentifiable.cs
new file mode 100644
index 0000000..6675a76
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Identification/IIdentifiable.cs
@@ -0,0 +1,14 @@
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Identification
+{
+    public interface IIdentifiable : IReferable
+    {
+        [JsonProperty(Order = -1), DataMember(Order = 1, EmitDefaultValue = false, IsRequired = false, Name = "identification")]
+        Identifier Identification { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "administration")]
+        AdministrativeInformation Administration { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Identification/IModelElement.cs b/sdks/csnet/BaSys40.Models/Core/Identification/IModelElement.cs
new file mode 100644
index 0000000..76f08a9
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Identification/IModelElement.cs
@@ -0,0 +1,10 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Identification
+{
+    public interface IModelElement
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "modelType")]
+        ModelType ModelType { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Identification/IReferable.cs b/sdks/csnet/BaSys40.Models/Core/Identification/IReferable.cs
new file mode 100644
index 0000000..5843616
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Identification/IReferable.cs
@@ -0,0 +1,23 @@
+using BaSys40.Models.Core.Extensions.References;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Identification
+{
+    public interface IReferable
+    {
+        [JsonProperty(Order = -2), DataMember(Order = 0, EmitDefaultValue = false, IsRequired = false, Name = "idShort")]
+        string IdShort { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "category")]
+        string Category { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "descriptions")]
+        List<Description> Descriptions { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "parent")]
+        IReference Parent { get; }
+        [IgnoreDataMember]
+        Dictionary<string, string> MetaData { get; }
+       
+        //Reference GetReference(IdentifierType identifiertType); ToDo
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Identification/ITypeable.cs b/sdks/csnet/BaSys40.Models/Core/Identification/ITypeable.cs
new file mode 100644
index 0000000..f8bbe3d
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Identification/ITypeable.cs
@@ -0,0 +1,11 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Identification
+{
+    public interface ITypeable
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "kind")]
+        Kind? Kind { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Identification/Identifier.cs b/sdks/csnet/BaSys40.Models/Core/Identification/Identifier.cs
new file mode 100644
index 0000000..0254b3c
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Identification/Identifier.cs
@@ -0,0 +1,98 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Identification
+{
+    [DataContract]
+    public class Identifier
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "id")]
+        public string Id { get; }
+
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "idType")]
+        public KeyType? IdType { get; }
+
+        public Identifier(string id, KeyType idType)
+        {
+            Id = id;
+            IdType = idType;
+        }
+
+
+        public class UniformResourceIdentifier : Identifier
+        {
+            public string Organisation { get; internal set; }
+            public string SubUnit { get; internal set; }
+            public string DomainId { get; internal set; }
+            public string Version { get; internal set; }
+            public string Revision { get; internal set; }
+            public string ElementId { get; internal set; }
+            public string InstanceNumber { get; internal set; }
+
+            public UniformResourceIdentifier(string organisation, string subUnit, string domainId, string version, string revision, string elementId, string instanceNumber) 
+                : base(ToUrn(organisation, subUnit, domainId, version, revision, elementId, instanceNumber), KeyType.URI)
+            {
+                Organisation = organisation;
+                SubUnit = subUnit;
+                DomainId = domainId;
+                Version = version;
+                Revision = revision;
+                ElementId = elementId;
+                InstanceNumber = instanceNumber;
+            }
+
+            public string ToUri() => ToUri(Organisation, SubUnit, DomainId, Version, Revision, ElementId, InstanceNumber);
+            public string ToUrn() => ToUrn(Organisation, SubUnit, DomainId, Version, Revision, ElementId, InstanceNumber);
+
+            public static string ToUri(string organisation, string subUnit, string domainId, string version, string revision, string elementId, string instanceNumber)
+            {
+                string uri = "http://";
+
+                uri += organisation + "/";
+
+                if (!string.IsNullOrEmpty(subUnit))
+                    uri += subUnit + "/";
+                if (!string.IsNullOrEmpty(domainId))
+                    uri += domainId + "/";
+                if (!string.IsNullOrEmpty(version))
+                    uri += version + "/";
+                if (!string.IsNullOrEmpty(revision))
+                    uri += revision + "/";
+                if (!string.IsNullOrEmpty(elementId))
+                    uri += elementId + "/";
+
+                if (!string.IsNullOrEmpty(instanceNumber))
+                {
+                    uri = uri.Substring(0, uri.Length - 2);
+                    uri += "#" + instanceNumber;
+                }
+                return uri;
+            }
+            public static string ToUrn(string organisation, string subUnit, string domainId, string version, string revision, string elementId, string instanceNumber)
+            {
+                string urn = "urn:";
+
+                urn += organisation + ":";
+
+                if (!string.IsNullOrEmpty(subUnit))
+                    urn += subUnit + ":";
+                if (!string.IsNullOrEmpty(domainId))
+                    urn += domainId + ":";
+                if (!string.IsNullOrEmpty(version))
+                    urn += version + ":";
+                if (!string.IsNullOrEmpty(revision))
+                    urn += revision + ":";
+                if (!string.IsNullOrEmpty(elementId))
+                    urn += elementId + ":";
+
+                if (!string.IsNullOrEmpty(instanceNumber))
+                {
+                    urn = urn.Substring(0, urn.Length - 2);
+                    urn += "#" + instanceNumber;
+                }
+                return urn;
+            }
+        }
+
+    }
+
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Identification/KeyType.cs b/sdks/csnet/BaSys40.Models/Core/Identification/KeyType.cs
new file mode 100644
index 0000000..79f469f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Identification/KeyType.cs
@@ -0,0 +1,13 @@
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Identification
+{
+    [DataContract]
+    public enum KeyType : int
+    {
+        Custom = 0,
+        URI = 1,
+        IRDI = 2,
+        IdShort = 3
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/ModelType.cs b/sdks/csnet/BaSys40.Models/Core/ModelType.cs
new file mode 100644
index 0000000..5211d80
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/ModelType.cs
@@ -0,0 +1,35 @@
+using Newtonsoft.Json;
+
+namespace BaSys40.Models.Core
+{
+    public class ModelType : DataObjectType
+    {
+        public static readonly ModelType Asset = new ModelType("Asset");
+        public static readonly ModelType AssetAdministationShell = new ModelType("AssetAdministationShell");
+        public static readonly ModelType Submodel = new ModelType("Submodel");
+        public static readonly ModelType SubmodelElement = new ModelType("SubmodelElement");
+        public static readonly ModelType SubmodelElementCollection = new ModelType("SubmodelElementCollection");
+        public static readonly ModelType Operation = new ModelType("Operation");
+        public static readonly ModelType OperationVariable = new ModelType("OperationVariable");
+        public static readonly ModelType Event = new ModelType("Event");
+        public static readonly ModelType View = new ModelType("View");
+        public static readonly ModelType RelationshipElement = new ModelType("RelationshipElement");
+        public static readonly ModelType DataElement = new ModelType("DataElement");
+        public static readonly ModelType Property = new ModelType("Property");
+        public static readonly ModelType File = new ModelType("File");
+        public static readonly ModelType Blob = new ModelType("Blob");
+        public static readonly ModelType ReferenceElement = new ModelType("ReferenceElement");
+        public static readonly ModelType DataElementCollection = new ModelType("DataElementCollection");
+        
+
+        public static readonly ModelType Constraint = new ModelType("Constraint");
+        public static readonly ModelType Formula = new ModelType("Formula");
+        public static readonly ModelType Qualifier = new ModelType("Qualifier");
+
+        public static readonly ModelType ConceptDescription = new ModelType("ConceptDescription");
+
+        [JsonConstructor]
+        protected ModelType(string name) : base(name)
+        { }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Views/IView.cs b/sdks/csnet/BaSys40.Models/Core/Views/IView.cs
new file mode 100644
index 0000000..2197f9c
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Views/IView.cs
@@ -0,0 +1,14 @@
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Semantics;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Core.Views
+{
+    public interface IView : IHasSemantics, IReferable, IModelElement
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "containedElements")]
+        List<IReference> ContainedElements { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Core/Views/View.cs b/sdks/csnet/BaSys40.Models/Core/Views/View.cs
new file mode 100644
index 0000000..cc422be
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Core/Views/View.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+
+namespace BaSys40.Models.Core.Views
+{
+    [DataContract]
+    public class View : IView
+    {
+        public List<IReference> ContainedElements { get; set; }
+
+        public IReference SemanticId { get; set; }
+
+        public string IdShort { get; set; }
+
+        public string Category { get; set; }
+
+        public List<Description> Descriptions { get; set; }
+
+        public IReference Parent { get; set; }
+        public Dictionary<string, string> MetaData { get; set; }
+
+        public ModelType ModelType => ModelType.View;
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Export/AssetAdministrationShellEnvironment.cs b/sdks/csnet/BaSys40.Models/Export/AssetAdministrationShellEnvironment.cs
new file mode 100644
index 0000000..f635415
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Export/AssetAdministrationShellEnvironment.cs
@@ -0,0 +1,60 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Export
+{
+    [DataContract]
+    public class AssetAdministrationShellEnvironment
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = true, Name = "assetAdministrationShells", Order = 0)]
+        public List<IAssetAdministrationShell> AssetAdministrationShells { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = true, Name = "submodels", Order = 1)]
+        public List<ISubmodel> Submodels { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = true, Name = "assets", Order = 2)]
+        public List<IAsset> Assets { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = true, Name = "conceptDescriptions", Order = 3)]
+        public List<IConceptDescription> ConceptDescriptions { get; }
+
+        [JsonConstructor]
+        protected AssetAdministrationShellEnvironment()
+        {
+            AssetAdministrationShells = new List<IAssetAdministrationShell>();
+            Submodels = new List<ISubmodel>();
+            Assets = new List<IAsset>();
+            ConceptDescriptions = new List<IConceptDescription>();
+
+        }
+
+        public AssetAdministrationShellEnvironment(params IAssetAdministrationShell[] assetAdministrationShells)
+        {
+            AssetAdministrationShells = new List<IAssetAdministrationShell>();
+            Submodels = new List<ISubmodel>();
+            Assets = new List<IAsset>();
+            ConceptDescriptions = new List<IConceptDescription>();
+
+            foreach (var aas in assetAdministrationShells)
+            {
+                AssetAdministrationShells.Add(aas);
+                Assets.Add(aas.Asset);
+                if (aas.Submodels?.Count > 0)
+                {
+                    Submodels.AddRange(aas.Submodels);
+                    foreach (var submodel in aas.Submodels)
+                        if (submodel.SubmodelElements?.Count > 0)
+                            foreach (var submodelElement in submodel.SubmodelElements)
+                                if (submodelElement.ConceptDescription != null)
+                                {                                    
+                                    ConceptDescriptions.Add(submodelElement.ConceptDescription);
+                                    (submodelElement as SubmodelElement).ConceptDescription = null;
+                                    (submodelElement as SubmodelElement).EmbeddedDataSpecifications = null;
+                                }
+                }
+            }
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Export/AssetAdministrationShellEnvironmentConverter.cs b/sdks/csnet/BaSys40.Models/Export/AssetAdministrationShellEnvironmentConverter.cs
new file mode 100644
index 0000000..0074a22
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Export/AssetAdministrationShellEnvironmentConverter.cs
@@ -0,0 +1,85 @@
+using BaSys40.Models.Core;
+using BaSys40.Models.Core.AssetAdministrationShell.Enums;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.Attributes;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Identification;
+using BaSys40.Models.Export;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace BaSys40.Models.Export
+{
+    public class AssetAdministrationShellEnvironmentConverter : JsonConverter
+    {
+        //public override bool CanWrite => true;
+        //public override bool CanRead => false;
+
+        public override bool CanConvert(Type objectType)
+        {
+            if (typeof(IAssetAdministrationShell).IsAssignableFrom(objectType))
+                return true;
+            else
+                return false;
+        }
+
+        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+        {
+            JObject jObj = new JObject();
+            Type type = value.GetType();
+
+            foreach (PropertyInfo prop in type.GetProperties())
+            {
+                object propVal = prop.GetValue(value);
+                if (propVal != null)
+                {
+                    var attrib = prop.GetCustomAttribute(typeof(ExportAsReferenceAttribute), true);
+                    var propName = prop.Name.Substring(0, 1).ToLower() + prop.Name.Substring(1, prop.Name.Length - 1);
+                    if (attrib != null)
+                    {
+                        var exportAttrib = (ExportAsReferenceAttribute)attrib;
+                        if (propVal != null)
+                        {
+                            if (typeof(IIdentifiable).IsAssignableFrom(propVal.GetType()))
+                            {
+                                IIdentifiable identifiable = propVal as IIdentifiable;
+                                if (identifiable.Identification?.Id != null)
+                                {
+                                    IReference reference = new Reference(new ModelKey(exportAttrib.KeyElement, identifiable.Identification.IdType.Value, identifiable.Identification.Id));
+                                    jObj.Add(propName, JToken.FromObject(reference, serializer));
+                                }
+                                continue;
+                            }
+                            if(propVal is IEnumerable)
+                            {
+                                JArray jArray = new JArray();
+                                IEnumerable<IIdentifiable> identifiables = (IEnumerable<IIdentifiable>)propVal;
+                                foreach (var identifiable in identifiables)
+                                {
+                                    if (identifiable.Identification?.Id != null)
+                                    {
+                                        IReference reference = new Reference(new ModelKey(exportAttrib.KeyElement, identifiable.Identification.IdType.Value, identifiable.Identification.Id));
+                                        jArray.Add(JToken.FromObject(reference, serializer));
+                                    }
+                                }
+                                jObj.Add(propName, jArray);
+                                continue;
+                            }
+                        }
+                    }
+                    jObj.Add(propName, JToken.FromObject(propVal, serializer));
+                }
+            }
+            jObj.WriteTo(writer);
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Extensions/Exceptions/Exception.cs b/sdks/csnet/BaSys40.Models/Extensions/Exceptions/Exception.cs
new file mode 100644
index 0000000..2296976
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Extensions/Exceptions/Exception.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BaSys40.Models.Extensions.Exceptions
+{
+    /// <summary>
+    /// BaSys Base-Exception Class
+    /// </summary>
+    public class Exception
+    {
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Extensions/JsonStandardSettings.cs b/sdks/csnet/BaSys40.Models/Extensions/JsonStandardSettings.cs
new file mode 100644
index 0000000..1268101
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Extensions/JsonStandardSettings.cs
@@ -0,0 +1,51 @@
+using BaSys40.Utils.DIExtensions;
+using BaSys40.Utils.JsonHandling;
+using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using System;
+
+namespace BaSys40.Models.Extensions
+{
+    public class JsonStandardSettings : JsonSerializerSettings
+    {
+        public IServiceProvider ServicePovider { get; }
+        public IServiceCollection Services { get; }
+        public JsonStandardSettings() : base()
+        {
+            Services = new ServiceCollection();
+            Services.ConfigureStandardImplementation();
+
+            var serviceProviderFactory = new DefaultServiceProviderFactory();
+            ServicePovider = serviceProviderFactory.CreateServiceProvider(Services);
+
+            NullValueHandling = NullValueHandling.Include;
+            
+
+            Formatting = Formatting.Indented;
+            Converters.Add(new StringEnumConverter());
+            ContractResolver = new DIContractResolver(new DIExtension(Services), ServicePovider);
+        }
+
+        public JsonStandardSettings(IServiceCollection services) : base()
+        {
+            Services = services;
+
+            var serviceProviderFactory = new DefaultServiceProviderFactory();
+            ServicePovider = serviceProviderFactory.CreateServiceProvider(Services);
+
+            NullValueHandling = NullValueHandling.Include;
+
+            Formatting = Formatting.Indented;
+            Converters.Add(new StringEnumConverter());
+            ContractResolver = new DIContractResolver(new DIExtension(Services), ServicePovider);
+        }
+
+        public static IServiceCollection GetStandardServiceCollection()
+        {
+            IServiceCollection services = new ServiceCollection();
+            services.ConfigureStandardImplementation();
+            return services;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Extensions/StandardDIExtensions.cs b/sdks/csnet/BaSys40.Models/Extensions/StandardDIExtensions.cs
new file mode 100644
index 0000000..9e6bad9
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Extensions/StandardDIExtensions.cs
@@ -0,0 +1,32 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Models.Core.Constraints;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace BaSys40.Models.Extensions
+{
+    public static class StandardDIExtensions
+    {
+        public static IServiceCollection ConfigureStandardImplementation(this IServiceCollection services)
+        {
+            services.AddTransient<IAsset, Asset>();
+            services.AddTransient<IAssetAdministrationShell, AssetAdministrationShell>();
+            services.AddTransient<ISubmodel, Submodel>();
+
+            services.AddTransient<IDataElement, DataElement>();
+            services.AddTransient(typeof(IDataElement<>), typeof(DataElement<>));
+            services.AddTransient<IOperation, Operation>();
+            services.AddTransient<IEvent, Event>();
+
+            services.AddTransient<IOperationVariable, OperationVariable>();
+            services.AddTransient<IArgument, Argument>();
+            services.AddTransient<IValue, DataElementValue>();
+            services.AddTransient<IKey, Key>();
+
+            services.AddTransient<IReference, Reference>();
+
+            return services;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Semantics/IHasDataSpecification.cs b/sdks/csnet/BaSys40.Models/Semantics/IHasDataSpecification.cs
new file mode 100644
index 0000000..9ad85c5
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Semantics/IHasDataSpecification.cs
@@ -0,0 +1,14 @@
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Semantics
+{
+    public interface IHasDataSpecification
+    {
+        [IgnoreDataMember]
+        IConceptDescription ConceptDescription { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "embeddedDataSpecifications")]
+        List<IEmbeddedDataSpecification> EmbeddedDataSpecifications { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Models/Semantics/IHasSemantics.cs b/sdks/csnet/BaSys40.Models/Semantics/IHasSemantics.cs
new file mode 100644
index 0000000..8e50a09
--- /dev/null
+++ b/sdks/csnet/BaSys40.Models/Semantics/IHasSemantics.cs
@@ -0,0 +1,11 @@
+using BaSys40.Models.Core.Extensions.References;
+using System.Runtime.Serialization;
+
+namespace BaSys40.Models.Semantics
+{
+    public interface IHasSemantics
+    {
+        [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "semanticId")]
+        IReference SemanticId { get; }
+    }
+}
diff --git a/sdks/csnet/BaSys40.RI.AAS.SmartControl/BaSys40.RI.AAS.SmartControl.csproj b/sdks/csnet/BaSys40.RI.AAS.SmartControl/BaSys40.RI.AAS.SmartControl.csproj
index 49909aa..3842496 100644
--- a/sdks/csnet/BaSys40.RI.AAS.SmartControl/BaSys40.RI.AAS.SmartControl.csproj
+++ b/sdks/csnet/BaSys40.RI.AAS.SmartControl/BaSys40.RI.AAS.SmartControl.csproj
@@ -1,20 +1,34 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
+    <Configurations>Debug;Release</Configurations>
+    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
   </PropertyGroup>
 
   <ItemGroup>
+    <None Remove="SmartControlSettings.xml" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Include="SmartControlSettings.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </EmbeddedResource>
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="NLog.Web.AspNetCore" Version="4.8.0" />
+  </ItemGroup>
+
+  <ItemGroup>
     <ProjectReference Include="..\BaSys40.API\BaSys40.API.csproj" />
     <ProjectReference Include="..\BaSys40.Models\BaSys40.Models.csproj" />
     <ProjectReference Include="..\BaSys40.Technologies.oneM2M\BaSys40.Technologies.oneM2M.csproj" />
     <ProjectReference Include="..\BaSys40.Utils\BaSys40.Utils.csproj" />
   </ItemGroup>
 
-  <ItemGroup>
-    <None Update="SmartControlSettings.xml">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
-  </ItemGroup>
+  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+    <Exec Command="copy &quot;$(ProjectDir)bin\Debug\BaSys40.RI.AAS.SmartControl.1.0.0.nupkg&quot; &quot;C:\Development\BaSys40\SDK\packages&quot; /Y" />
+  </Target>
 
 </Project>
diff --git a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControl.cs b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControl.cs
index a4a72ba..0cef31b 100644
--- a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControl.cs
+++ b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControl.cs
@@ -2,7 +2,7 @@
 using oneM2MClient.Client;
 using oneM2MClient.Resources;
 using oneM2MClient.Protocols;
-using oneM2MClient.Utils;
+
 
 using System;
 using System.Linq;
@@ -14,17 +14,25 @@
 using BaSys40.Models.Core;
 using BaSys40.Models.Core.AssetAdministrationShell.Generics;
 using BaSys40.Utils.ResultHandling;
+using BaSys40.Utils.ModelHandling;
 
 using Newtonsoft.Json;
 using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
 using BaSys40.Models.Core.AssetAdministrationShell.Enums;
 using BaSys40.Models.Core.Identification;
 using System.Net;
+using BaSys40.Models.Core.AssetAdministrationShell.Implementations.DataElementSubtypes;
+using BaSys40.Models.Core.AssetAdministrationShell;
+using oneM2MClient.Utils;
+using BaSys40.Models.Core.Extensions.References;
+using BaSys40.Utils.Settings;
+using System.Web;
 
 namespace BaSys40.RI.AAS.SmartControl
 {
-    public partial class SmartControl : IAssetAdministrationShellManager, IAssetAdministrationShellRegistry
+    public partial class SmartControl : IAssetAdministrationShellManager
     {
+
         public static SmartControlSettings Settings { get; private set; }
 
         public static readonly IClient oneM2MClient;
@@ -33,6 +41,13 @@
         static SmartControl()
         {
             SettingsPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), SmartControlSettings.FileName);
+
+            Assembly sourceAssembly = Assembly.GetExecutingAssembly();
+            string nameSpace = typeof(SmartControl).Namespace.Split('.')[0];
+
+            if (!ResourceChecker.CheckResource(sourceAssembly, nameSpace, "SmartControlSettings.xml", true))
+                throw new FileNotFoundException("SmartControlSettings.xml is missing or has a wrong configuration!");
+
             Settings = SmartControlSettings.LoadSettings(SettingsPath);
             oneM2MClient = ClientFactory.CreateClient(Settings.oneM2MConfig.ProtocolBinding);
         }
@@ -71,9 +86,9 @@
                 return ConvertResult<IAssetAdministrationShell>(result);
         }
 
-        public IResult UpdateAssetAdministrationShell(string aasId, Dictionary<string, string> metaData)
+        public IResult UpdateAssetAdministrationShell(string aasId, IAssetAdministrationShell aas)
         {
-            var result = UpdateAAS(aasId, metaData);
+            var result = UpdateAAS(aasId, aas);
             return ConvertResult(result);
         }
 
@@ -83,80 +98,80 @@
             return ConvertResult(result);
         }
 
-        public IResult DeleteSubModel(string aasId, string subModelId)
+        public IResult DeleteSubmodel(string aasId, string submodelId)
         {
-            var components = new string[] { aasId, subModelId };
+            var components = new string[] { aasId, submodelId };
             var result = RemoveComponent(components);
 
             return ConvertResult(result);
         }
-        public IResult InvokeOperation(string aasId, string subModelId, string operationId, List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout)
+        public IResult InvokeOperation(string aasId, string submodelId, string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout)
         {
-            var result = CallOperation(aasId, subModelId, operationId, inputArguments, out outputArguments, timeout);
+            var result = CallOperation(aasId, submodelId, operationId, inputArguments, outputArguments, timeout);
             return ConvertResult(result);
         }
 
 
-        public IResult<ISubModel> CreateSubModel(string aasId, ISubModel subModel)
+        public IResult<ISubmodel> CreateSubmodel(string aasId, ISubmodel submodel)
         {
-            var result = AddSubModel(aasId, subModel);
-            if(subModel.Properties != null && subModel.Properties.Count > 0)
+            var result = AddSubmodel(aasId, submodel);
+            if(submodel.DataElements != null && submodel.DataElements.Count > 0)
             {
-                foreach (var property in subModel.Properties)
+                foreach (var property in submodel.DataElements)
                 {
-                    CreateProperty(aasId, subModel.Identification.Id, property);
+                    CreateDataElement(aasId, submodel.IdShort, property);
                 }
             }
-            if (subModel.Operations != null && subModel.Operations.Count > 0)
+            if (submodel.Operations != null && submodel.Operations.Count > 0)
             {
-                foreach (var operation in subModel.Operations)
+                foreach (var operation in submodel.Operations)
                 {
-                    CreateOperation(aasId, subModel.Identification.Id, operation);
+                    CreateOperation(aasId, submodel.IdShort, operation);
                 }
             }
-            if (subModel.Events != null && subModel.Events.Count > 0)
+            if (submodel.Events != null && submodel.Events.Count > 0)
             {
-                foreach (var eventable in subModel.Events)
+                foreach (var eventable in submodel.Events)
                 {
-                    CreateEvent(aasId, subModel.Identification.Id, eventable);
+                    CreateEvent(aasId, submodel.IdShort, eventable);
                 }
             }
             if (result.Success)
             {
-                return ConvertResult<ISubModel>(subModel, result);
+                return ConvertResult<ISubmodel>(submodel, result);
             }
             else
-                return ConvertResult<ISubModel>(result);
+                return ConvertResult<ISubmodel>(result);
         }
 
-        public IResult<IPropertyDescription> CreateProperty(string aasId, string subModelId, IPropertyDescription property)
+        public IResult<IDataElement> CreateDataElement(string aasId, string submodelId, IDataElement property)
         {
-            var result = AddProperty(aasId, subModelId, property);
+            var result = AddProperty(aasId, submodelId, property);
             if(result.Success)
             {
-                return ConvertResult<IPropertyDescription>(property, result);
+                return ConvertResult<IDataElement>(property, result);
             }
-            return ConvertResult<IPropertyDescription>(result);
+            return ConvertResult<IDataElement>(result);
         }
 
-        public IResult<IOperationDescription> CreateOperation(string aasId, string subModelId, IOperationDescription operation)
+        public IResult<IOperation> CreateOperation(string aasId, string submodelId, IOperation operation)
         {
-            var result = AddOperation(aasId, subModelId, (OperationDescription)operation);
+            var result = AddOperation(aasId, submodelId, operation);
             if (result.Success)
             {
-                return ConvertResult<IOperationDescription>(operation, result);
+                return ConvertResult<IOperation>(operation, result);
             }
-            return ConvertResult<IOperationDescription>(result);
+            return ConvertResult<IOperation>(result);
         }
 
-        public IResult<IEventDescription> CreateEvent(string aasId, string subModelId, IEventDescription eventable)
+        public IResult<IEvent> CreateEvent(string aasId, string submodelId, IEvent eventable)
         {
-            var result = AddEvent(aasId, subModelId, eventable);
+            var result = AddEvent(aasId, submodelId, eventable);
             if (result.Success)
             {
-                return ConvertResult<IEventDescription>(eventable, result);
+                return ConvertResult<IEvent>(eventable, result);
             }
-            return ConvertResult<IEventDescription>(eventable, result);
+            return ConvertResult<IEvent>(eventable, result);
         }
 
         public IResult<IAssetAdministrationShell> RetrieveAssetAdministrationShell(string aasId)
@@ -179,89 +194,98 @@
             return ConvertResult<List<IAssetAdministrationShell>>(result);
         }
 
-        public IResult<IElementContainer<ISubModel>> RetrieveSubModels(string aasId)
+        public IResult<ElementContainer<ISubmodel>> RetrieveSubmodels(string aasId)
         {
-            var result = ReadSubModels(aasId, out IElementContainer<ISubModel> subModels);
-            if (result.Success && subModels != null)
+            var result = ReadSubmodels(aasId, out ElementContainer<ISubmodel> submodels);
+            if (result.Success && submodels != null)
             {
-                return ConvertResult<IElementContainer<ISubModel>>(subModels, result);
+                return ConvertResult(submodels, result);
             }
-            return ConvertResult<IElementContainer<ISubModel>>(result);
+            return ConvertResult<ElementContainer<ISubmodel>>(result);
 
         }
 
-        public IResult<ISubModel> RetrieveSubModel(string aasId, string subModelId)
+        public IResult<ISubmodel> RetrieveSubmodel(string aasId, string submodelId)
         {
-            var result = ReadSubModel(aasId, subModelId, out SubModel subModel);
-            if (result.Success && subModel != null)
+            var result = ReadSubmodel(aasId, submodelId, out Submodel submodel);
+            if (result.Success && submodel != null)
             {
-                return ConvertResult<ISubModel>(subModel, result);
+                return ConvertResult<ISubmodel>(submodel, result);
             }
-            return ConvertResult<ISubModel>(result);
+            return ConvertResult<ISubmodel>(result);
         }
 
-        public IResult<IPropertyDescription> RetrieveProperty(string aasId, string subModelId, string propertyId)
+        public IResult<IDataElement> RetrieveDataElement(string aasId, string submodelId, string propertyId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(propertyId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(propertyId))
             {
-                var result = ReadProperty(aasId, subModelId, propertyId, out PropertyDescription prop);
+                var result = ReadProperty(aasId, submodelId, propertyId, out Property prop);
                 if (result.Success && prop != null)
                 {
-                    var valueResult = ReadPropertyValue(aasId, subModelId, propertyId, out object value);
-                    if (valueResult.Success && value != null)
-                    {
-                        prop.Value = new ElementValue<object>(value, DataObjectType.Object);
-                    }
-                    return ConvertResult<IPropertyDescription>(prop, result);
+                    return ConvertResult<IDataElement>(prop, result);
                 }
                 else
-                    return ConvertResult<IPropertyDescription>(result);
+                    return ConvertResult<IDataElement>(result);
             }
             return null;
         }
 
-        public IResult UpdateProperty(string aasId, string subModelId, string propertyId, IValue value)
+        public IResult UpdateDataElementValue(string aasId, string submodelId, string propertyId, IValue value)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(propertyId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(propertyId))
             {
-                var result = SetProperty(aasId, subModelId, propertyId, value);
+                var result = UpdatePropertyValue(aasId, submodelId, propertyId, value);
                 return ConvertResult(result);
             }
             return null;
-        }        
-
-        public IResult DeleteProperty(string aasId, string subModelId, string propertyId)
+        }    
+        
+        public IResult<IValue> RetrieveDataElementValue(string aasId, string submodelId, string propertyId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(propertyId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(propertyId))
             {
-                var result = RemoveProperty(aasId, subModelId, propertyId);
+                var valueResult = ReadPropertyValue(aasId, submodelId, propertyId, out IValue value);
+                if (valueResult.Success && value != null)
+                    return ConvertResult<IValue>(value, valueResult);
+                else
+                    return ConvertResult<IValue>(valueResult);
+            }
+            return null;
+        }
+
+
+        public IResult DeleteDataElement(string aasId, string submodelId, string propertyId)
+        {
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(propertyId))
+            {
+                var result = RemoveProperty(aasId, submodelId, propertyId);
                 return ConvertResult(result);
             }
             return null;
         }
 
-        public IResult<IOperationDescription> RetrieveOperation(string aasId, string subModelId, string operationId)
+        public IResult<IOperation> RetrieveOperation(string aasId, string submodelId, string operationId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(operationId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(operationId))
             {
-                var result = ReadOperation(aasId, subModelId, operationId, out OperationDescription op);
+                var result = ReadOperation(aasId, submodelId, operationId, out Operation op);
                 if (result.Success && op != null)
                 {
-                    return ConvertResult<IOperationDescription>(op, result);
+                    return ConvertResult<IOperation>(op, result);
                 }
                 else
-                    return ConvertResult<IOperationDescription>(result);
+                    return ConvertResult<IOperation>(result);
             }
             return null;
         }
 
 
 
-        public IResult DeleteOperation(string aasId, string subModelId, string operationId)
+        public IResult DeleteOperation(string aasId, string submodelId, string operationId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(operationId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(operationId))
             {
-                var result = RemoveOperation(aasId, subModelId, operationId);
+                var result = RemoveOperation(aasId, submodelId, operationId);
                 return ConvertResult(result);
             }
             return null;
@@ -269,130 +293,118 @@
 
         
 
-        public IResult<IEventDescription> RetrieveEvent(string aasId, string subModelId, string eventId)
+        public IResult<IEvent> RetrieveEvent(string aasId, string submodelId, string eventId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(eventId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(eventId))
             {
-                var result = ReadEvent(aasId, subModelId, eventId, out EventDescription ev);
+                var result = ReadEvent(aasId, submodelId, eventId, out Event ev);
                 if (result.Success && ev != null)
                 {
-                    return ConvertResult<IEventDescription>(ev, result);
+                    return ConvertResult<IEvent>(ev, result);
                 }
                 else
-                    return ConvertResult<IEventDescription>(result);
+                    return ConvertResult<IEvent>(result);
             }
             return null;
         }
 
-        public IResult DeleteEvent(string aasId, string subModelId, string eventId)
+        public IResult DeleteEvent(string aasId, string submodelId, string eventId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(eventId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(eventId))
             {
-                var result = RemoveEvent(aasId, subModelId, eventId);
+                var result = RemoveEvent(aasId, submodelId, eventId);
                 return ConvertResult(result);
             }
             return null;
         }
 
-        public IResult<IElementContainer<IPropertyDescription>> RetrieveProperties(string aasId, string subModelId)
+        public IResult<ElementContainer<IDataElement>> RetrieveDataElements(string aasId, string submodelId)
         {
-            var result = ReadSubModel(aasId, subModelId, out SubModel subModel);
-            if (result.Success && subModel?.Properties != null)
+            var result = ReadSubmodel(aasId, submodelId, out Submodel submodel);
+            if (result.Success && submodel?.DataElements != null)
             {
-                return ConvertResult<IElementContainer<IPropertyDescription>>(subModel.Properties, result);
+                return ConvertResult(submodel.DataElements, result);
             }
-            return ConvertResult<IElementContainer<IPropertyDescription>>(result);
+            return ConvertResult<ElementContainer<IDataElement>>(result);
         }
 
-        public IResult<IElementContainer<IOperationDescription>> RetrieveOperations(string aasId, string subModelId)
+        public IResult<ElementContainer<IOperation>> RetrieveOperations(string aasId, string submodelId)
         {
-            var result = ReadSubModel(aasId, subModelId, out SubModel subModel);
-            if (result.Success && subModel?.Operations != null)
+            var result = ReadSubmodel(aasId, submodelId, out Submodel submodel);
+            if (result.Success && submodel?.Operations != null)
             {
-                return ConvertResult<IElementContainer<IOperationDescription>>(subModel.Operations, result);
+                return ConvertResult(submodel.Operations, result);
             }
-            return ConvertResult<IElementContainer<IOperationDescription>>(result);
+            return ConvertResult<ElementContainer<IOperation>>(result);
         }
 
-        public IResult<IElementContainer<IEventDescription>> RetrieveEvents(string aasId, string subModelId)
+        public IResult<ElementContainer<IEvent>> RetrieveEvents(string aasId, string submodelId)
         {
-            var result = ReadSubModel(aasId, subModelId, out SubModel subModel);
-            if (result.Success && subModel?.Events != null)
+            var result = ReadSubmodel(aasId, submodelId, out Submodel submodel);
+            if (result.Success && submodel?.Events != null)
             {
-                return ConvertResult<IElementContainer<IEventDescription>>(subModel.Events, result);
+                return ConvertResult(submodel.Events, result);
             }
-            return ConvertResult<IElementContainer<IEventDescription>>(result);
+            return ConvertResult<ElementContainer<IEvent>>(result);
         }
 
         #endregion
 
         #region SmartControl oneM2M-Functions
 
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> CallOperation(string aasId, string subModelId, string operationId, List<IArgument> inputArguments, out List<IArgument> outputArguments, int timeout)
+        public static Result<Response> CallOperation(string aasId, string submodelId, string operationId, List<IArgument> inputArguments, List<IArgument> outputArguments, int timeout = DEFAULT_TIMEOUT)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, operationId, ContainerStrings.REQUEST);
-            string argContent = string.Empty;
-            if (inputArguments != null && inputArguments.Count > 0)
-            {
-                string arguments = string.Join(ELEMENT_SEPERATOR, inputArguments.Select(a => a.Value.Value).ToList().ConvertAll(d => d.ToString()));
-                argContent = ParameterStrings.PARAM_BRACKET_LEFT + arguments + ParameterStrings.PARAM_BRACKET_RIGHT;
-            }
-            else
-                argContent = ParameterStrings.PARAM_BRACKET_LEFT + ParameterStrings.PARAM_BRACKET_RIGHT;
+            if (timeout == 0)
+                timeout = DEFAULT_TIMEOUT;
 
-            string urlEncoded = WebUtility.UrlEncode(argContent);
-            var result = ContentInstance.Create(oneM2MClient, req, Guid.NewGuid().ToString(), urlEncoded);
+            ReadOperation(aasId, submodelId, operationId, out Operation operation);
 
-            req.SetPath(aasId, subModelId, operationId, ContainerStrings.RESPONSE);
-            List<string> outArgs = new List<string>();
-            Utils.ResultHandling.Utils.RetryUntilSuccessOrTimeout(() => GetResponseFromCall(req, outArgs), TimeSpan.FromMilliseconds(timeout), TimeSpan.FromMilliseconds(100));
-            outputArguments = SmartControlUtils.ConvertStringArguments(outArgs.ToArray());
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, operationId, ContainerStrings.REQUEST);
+            string argumentString = SmartControlUtils.ConvertStringArguments(inputArguments);
+            string resourceName = "cin_"+req.GetHashCode();
+            var result = ContentInstance.Create(oneM2MClient, req, resourceName, argumentString);
+
+            req.SetPath(aasId, submodelId, operationId, ContainerStrings.RESPONSE);
+            List<IArgument> outArgs = new List<IArgument>();
+            bool success = Utils.ResultHandling.Utils.RetryUntilSuccessOrTimeout(
+                () => GetResponseFromCall(req, resourceName, outArgs, operation.Out), TimeSpan.FromMilliseconds(timeout), TimeSpan.FromMilliseconds(100));
+            outputArguments?.AddRange(outArgs);
 
             return result;
         }
 
-        public static bool GetResponseFromCall(Request request, List<string> outputArguments)
+        private static bool GetResponseFromCall(Request request, string resourceName, List<IArgument> outputArguments, List<IOperationVariable> referenceArguments)
         {
             var resp = Helper.ReadLatestAddedResource(oneM2MClient, request, out resource resource);
             if (resource != null && resource is cin cinResource)
             {
-                if (cinResource.Con.Contains(ELEMENT_SEPERATOR))
+                if (cinResource.Rn == resourceName)
                 {
-                    string[] outArgs = cinResource.Con.Split(new char[] { ELEMENT_SEPERATOR[0] }, StringSplitOptions.RemoveEmptyEntries);
-                    for (int i = 0; i < outArgs.Length; i++)
-                    {
-                        outputArguments.Add(outArgs[i]);
-                    }
+                    List<IArgument> outArgs = SmartControlUtils.ConvertStringArguments(cinResource.Con, referenceArguments);
+                    if(outArgs != null)
+                        outputArguments.AddRange(outArgs);
+                    return true;
                 }
-                else
-                    outputArguments.Add(cinResource.Con);
-                return true;
             }
             return false;
         }
 
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> SetProperty(string aasId, string subModelId, string propertyId, object value)
+        public static Result<Response> UpdatePropertyValue(string aasId, string submodelId, string propertyId, IValue value)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, propertyId, ContainerStrings.DATA);
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, propertyId, ContainerStrings.DATA);
 
-            string content = null;
-            if (Convert.GetTypeCode(value) != TypeCode.Object)
-                content = Convert.ToString(value);
-            else
-                content = JsonConvert.SerializeObject(value);
-
-            var urlEncodedContent = WebUtility.UrlEncode(content);
-            ContentInstance data_cin = new ContentInstance(Guid.NewGuid().ToString(), urlEncodedContent);
+            string content = SmartControlUtils.ConvertPropertyValue(value);
+            ContentInstance data_cin = new ContentInstance(Guid.NewGuid().ToString(), content);
             var result = data_cin.Create(oneM2MClient, req);
             return result;
         }
 
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> UpdateAAS(string aasId, Dictionary<string,string> keyValues)
+        public static Result<Response> UpdateAAS(string aasId, IAssetAdministrationShell aas)
         {
             Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId);
             List<string> labels = null;
-            if (keyValues?.Count > 0)
-                labels = keyValues.Select(kvp => kvp.Key + SEPERATOR + kvp.Value)?.ToList();
+            if (aas.MetaData?.Count > 0)
+                labels = aas.MetaData.Select(kvp => kvp.Key + SEPERATOR + kvp.Value)?.ToList();
             var result = ApplicationEntity.Update(oneM2MClient, req, aasId, null, labels);
             return result;
         }
@@ -400,26 +412,32 @@
 
         #region Converters
 
-        public static SubModel ReadSubModelFrom(string assetId, ObjectTreeBuilder subModelTree)
+        public static Submodel ReadSubmodelFrom(string assetId, ObjectTreeBuilder submodelTree)
         {
-            var rootCnt = subModelTree?.GetValue<cnt>();
+            var rootCnt = submodelTree?.GetValue<cnt>();
             if (rootCnt != null)
             {
-                SubModel subModel = new SubModel()
+                Submodel submodel = new Submodel()
                 {
-                    DisplayName = rootCnt.Rn,
-                    SemanticReference = new Identifier(GetLabelValue(TYPE_IDENTIFIER, rootCnt.Lbl), Identificator.Internal),
-                    Identification = new Identifier(GetLabelValue(Labels.ID, rootCnt.Lbl), Identificator.Internal),
-                    Description = GetLabelValue(Labels.DESCRIPTION, rootCnt.Lbl),
+                    IdShort = rootCnt.Rn,
+                    SemanticId = new Reference(new GlobalKey(KeyElements.Submodel, KeyType.URI, GetLabelValue(TYPE_IDENTIFIER, rootCnt.Lbl))),
+                    Identification = new Identifier(GetLabelValue(Labels.ID, rootCnt.Lbl), KeyType.Custom),
+                    Descriptions = GetDescriptionsFromLabels(rootCnt.Lbl)
                 };
 
-                if (subModelTree.HasChildren())
-                {
-                    subModel.Operations = new ElementContainer<IOperationDescription>();
-                    subModel.Properties = new ElementContainer<IPropertyDescription>();
-                    subModel.Events = new ElementContainer<IEventDescription>();
+                var typeInstance = GetLabelValue(BASYS_TYPE_IDENTIFIER, rootCnt.Lbl);
+                if (typeInstance == ElementType.SUBMODEL_TYPE)
+                    submodel.Kind = Kind.Type;
+                else if (typeInstance == ElementInstance.SUBMODEL)
+                    submodel.Kind = Kind.Instance;
 
-                    foreach (var subElement in subModelTree.Children)
+                if (submodelTree.HasChildren())
+                {
+                    submodel.Operations = new ElementContainer<IOperation>();
+                    submodel.DataElements = new ElementContainer<IDataElement>();
+                    submodel.Events = new ElementContainer<IEvent>();
+
+                    foreach (var subElement in submodelTree.Children)
                     {
                         var subElementCnt = subElement.GetValue<cnt>();
                         if (subElementCnt != null)
@@ -428,47 +446,47 @@
                             {
                                 var op = ReadOperationFrom(subElement);
                                 if (op != null)
-                                    subModel.Operations.Add(op);
+                                    submodel.Operations.Add(op);
                             }
                             else if (subElementCnt.Lbl.FirstOrDefault(l => l.Contains(BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.PROPERTY)) != null)
                             {
                                 var prop = ReadPropertyFrom(subElement);
                                 if (prop != null)
-                                    subModel.Properties.Add(prop);
+                                    submodel.DataElements.Add(prop);
                             }
                             else if (subElementCnt.Lbl.FirstOrDefault(l => l.Contains(BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.EVENT)) != null)
                             {
                                 var prop = ReadEventFrom(subElement);
                                 if (prop != null)
-                                    subModel.Events.Add(prop);
+                                    submodel.Events.Add(prop);
                             }
                         }
                     }
                 }
-                return subModel;
+                return submodel;
             }
             return null;
         }
 
-        public static OperationDescription ReadOperationFrom(ObjectTreeBuilder operationTree)
+        public static Operation ReadOperationFrom(ObjectTreeBuilder operationTree)
         {
             var operationCnt = operationTree?.GetValue<cnt>();
-            OperationDescription operation = ConvertCntToOperation(operationCnt);
+            Operation operation = ConvertCntToOperation(operationCnt);
             if (operation != null)
             {
-                string listenerUriSubscriptionPath = string.Join(PATH_SEPERATOR, ContainerStrings.REQUEST, DEFAULT_SUBSCRIPTION_NAME);
-                if (operationTree.HasChildPath(listenerUriSubscriptionPath))
-                {
-                    var sub = operationTree.GetChild(listenerUriSubscriptionPath).GetValue<sub>();
-                    var uri = sub?.Nu?.FirstOrDefault();
-                    operation.Endpoint = uri ?? uri;
-                }
+                //string listenerUriSubscriptionPath = string.Join(PATH_SEPERATOR, ContainerStrings.REQUEST, DEFAULT_SUBSCRIPTION_NAME);
+                //if (operationTree.HasChildPath(listenerUriSubscriptionPath))
+                //{
+                //    var sub = operationTree.GetChild(listenerUriSubscriptionPath).GetValue<sub>();
+                //    var uri = sub?.Nu?.FirstOrDefault();
+                //    operation.OperationInformation.Endpoint = uri ?? uri;
+                //}
                 return operation;
             }
             return null;
         }
 
-        public static EventDescription ReadEventFrom(ObjectTreeBuilder eventTree)
+        public static Event ReadEventFrom(ObjectTreeBuilder eventTree)
         {
             var eventCnt = eventTree?.GetValue<cnt>();
             if (eventCnt != null)
@@ -477,41 +495,41 @@
                 string schemaPath = string.Join(PATH_SEPERATOR, ContainerStrings.SCHEMA, EventIdentifier.SCHEMA_CIN);
                 if (eventTree.HasChildPath(schemaPath))
                     schemaCin = eventTree.GetChild(schemaPath).GetValue<cin>();
-                EventDescription eventable = ConvertCntToEvent(eventCnt, schemaCin);
+                Event eventable = ConvertCntToEvent(eventCnt, schemaCin);
                 return eventable;
             }
             return null;
         }
 
-        public static PropertyDescription ReadPropertyFrom(ObjectTreeBuilder propertyTree)
+        public static Property ReadPropertyFrom(ObjectTreeBuilder propertyTree)
         {
             var propertyCnt = propertyTree?.GetValue<cnt>();
-            PropertyDescription property = ConvertCntToProperty(propertyCnt);
+            Property property = ConvertCntToProperty(propertyCnt);
             if (property != null)
             {
                 //string listenerUriSubscriptionPath = string.Join(PATH_SEPERATOR, ContainerStrings.GET, ContainerStrings.REQUEST, DEFAULT_SUBSCRIPTION_NAME);
-                string listenerUriSubscriptionPath = string.Join(PATH_SEPERATOR, ContainerStrings.DATA, DEFAULT_SUBSCRIPTION_NAME);
-                if (propertyTree.HasChildPath(listenerUriSubscriptionPath))
-                {
-                    var sub = propertyTree.GetChild(listenerUriSubscriptionPath).GetValue<sub>();
-                    var uri = sub?.Nu?.FirstOrDefault();
-                    property.Endpoint = uri ?? uri;
-                }
-                /*
-                string valuePath = string.Join(PATH_SEPERATOR, ContainerStrings.DATA);
-                if (propertyTree.HasChildPath(valuePath) && propertyTree.GetChild(valuePath).HasChildren())
-                {
-                    var latestValue = Helper.GetLatestResource(propertyTree.GetChild(valuePath));
-                    if(latestValue?.Con != null)
-                        property.Value = new ElementValue<string>(latestValue.Con);
-                }
-                */
+                //string listenerUriSubscriptionPath = string.Join(PATH_SEPERATOR, ContainerStrings.DATA, DEFAULT_SUBSCRIPTION_NAME);
+                //if (propertyTree.HasChildPath(listenerUriSubscriptionPath))
+                //{
+                //    var sub = propertyTree.GetChild(listenerUriSubscriptionPath).GetValue<sub>();
+                //    var uri = sub?.Nu?.FirstOrDefault();
+                //    (property.ElementInformation as ElementInformation).Endpoint = uri ?? uri;
+                //}
+               
+                //string valuePath = string.Join(PATH_SEPERATOR, ContainerStrings.DATA);
+                //if (propertyTree.HasChildPath(valuePath) && propertyTree.GetChild(valuePath).HasChildren())
+                //{
+                //    var latestValue = Helper.GetLatestResource(propertyTree.GetChild(valuePath));
+                //    if(latestValue?.Con != null)
+                //        property.Value = new ElementValue<string>(latestValue.Con);
+                //}
+                
                 return property;
             }
             return null;
         }
 
-        public static IResult ConvertResult(oneM2MClient.Utils.ResultHandling.Result<Response> requestResponse)
+        public static IResult ConvertResult(Result<Response> requestResponse)
         {
             IResult result = new Result(requestResponse.Success);
 
@@ -525,7 +543,7 @@
             return result;
         }
 
-        public static IResult<T> ConvertResult<T>(oneM2MClient.Utils.ResultHandling.Result<Response> requestResponse)
+        public static IResult<T> ConvertResult<T>(Result<Response> requestResponse)
         {
             IResult<T> result = new Result<T>(requestResponse.Success);
 
@@ -539,7 +557,7 @@
             return result;
         }
 
-        public static IResult<T> ConvertResult<T>(T entity, oneM2MClient.Utils.ResultHandling.Result<Response> requestResponse)
+        public static IResult<T> ConvertResult<T>(T entity, Result<Response> requestResponse)
         {
             IResult<T> result;
             if (entity != null)
@@ -557,76 +575,79 @@
             return result;
         }
 
-        private static PropertyDescription ConvertCntToProperty(cnt propertyCnt)
+        private static Property ConvertCntToProperty(cnt propertyCnt)
         {
             if (propertyCnt != null)
             {
                 var dataObjectType = GetDataTypeFromString(GetLabelValue(DATATYPE_IDENTIFIER, propertyCnt.Lbl));
-                Identifier dataTypeDefinition = null;
-                if (dataObjectType == DataObjectType.Object)
-                    dataTypeDefinition = new Identifier(GetLabelValue(DATATYPE_IDENTIFIER, propertyCnt.Lbl), Identificator.Internal);
+                Reference dataTypeDefinition = null;
+                if (dataObjectType == DataObjectType.AnyType)
+                    dataTypeDefinition = new Reference(new GlobalKey(KeyElements.GlobalReference, KeyType.URI, GetLabelValue(DATATYPE_IDENTIFIER, propertyCnt.Lbl)));
 
                 bool isCollection = false;
                 if (propertyCnt.Lbl.Contains(Labels.COLLECTION))
                     isCollection = true;
+                               
 
-                PropertyDescription prop = new PropertyDescription()
+                Property property = new Property(new DataType(dataObjectType, isCollection, dataTypeDefinition))
                 {
-                    Identification = new Identifier(GetLabelValue(Labels.ID, propertyCnt.Lbl), Identificator.Internal),
-                    Description = GetLabelValue(Labels.DESCRIPTION, propertyCnt.Lbl),
-                    DisplayName = propertyCnt.Rn,                    
-                    Readable = propertyCnt.Lbl.Contains(Labels.READABLE) ? true : false,
-                    Writable = propertyCnt.Lbl.Contains(Labels.WRITABLE) ? true : false,
-                    Eventable = propertyCnt.Lbl.Contains(Labels.EVENTABLE) ? true : false,
-                    DataType = new DataType(dataObjectType, isCollection, false, dataTypeDefinition)
+                    Descriptions = GetDescriptionsFromLabels(propertyCnt.Lbl),
+                    IdShort = GetLabelValue(Labels.ID, propertyCnt.Lbl)
                 };
 
                 var semanticReference = GetLabelValue(TYPE_IDENTIFIER, propertyCnt.Lbl);
                 if (semanticReference != null)
-                    prop.SemanticReference = new Identifier(semanticReference, Identificator.Internal);
+                    property.SemanticId = new Reference(new GlobalKey(KeyElements.Property, KeyType.URI, semanticReference));
 
-                return prop;
+                return property;
             }
             return null;
         }
 
-        private static OperationDescription ConvertCntToOperation(cnt subElementCnt)
+        public static List<Description> GetDescriptionsFromLabels(List<string> labels)
+        {
+            var descriptionText = GetLabelValue(Labels.DESCRIPTION, labels);
+            if (!string.IsNullOrEmpty(descriptionText))
+                return new List<Description>() { new Description("EN", descriptionText) };
+            return null;
+        }
+
+        private static Operation ConvertCntToOperation(cnt subElementCnt)
         {
             if (subElementCnt != null)
             {
                 var dataObjectType = GetDataTypeFromString(GetLabelValue(RETURN_DATATYPE_IDENTIFIER, subElementCnt.Lbl));
-                Identifier dataTypeDefinition = null;
-                if (dataObjectType == DataObjectType.Object)
-                    dataTypeDefinition = new Identifier(GetLabelValue(RETURN_DATATYPE_IDENTIFIER, subElementCnt.Lbl), Identificator.Internal);
+                Reference dataTypeDefinition = null;
+                if (dataObjectType == DataObjectType.AnyType)
+                    dataTypeDefinition = new Reference(new GlobalKey(KeyElements.GlobalReference, KeyType.URI, GetLabelValue(RETURN_DATATYPE_IDENTIFIER, subElementCnt.Lbl)));
 
-                OperationDescription op = new OperationDescription()
+                Operation op = new Operation()
                 {
-                    Identification = new Identifier(GetLabelValue(Labels.ID, subElementCnt.Lbl), Identificator.Internal),
-                    Description = GetLabelValue(Labels.DESCRIPTION, subElementCnt.Lbl),
-                    DisplayName = subElementCnt.Rn,
+                    Descriptions = GetDescriptionsFromLabels(subElementCnt.Lbl),
+                    IdShort = GetLabelValue(Labels.ID, subElementCnt.Lbl),
                 };
-                
+
                 if (Int32.TryParse(GetLabelValue(ParameterStrings.GetParameterLength(), subElementCnt.Lbl), out int paramLength) && paramLength > 0)
                 {
-                    op.InputParameters = new List<IParameter>(paramLength);
+                    op.In = new List<IOperationVariable>(paramLength);
                     for (int i = 0; i < paramLength; i++)
                     {
-                        Parameter param = new Parameter()
+                        OperationVariable param = new OperationVariable()
                         {
-                            ParameterName = GetLabelValue(ParameterStrings.GetParameterName(i), subElementCnt.Lbl),
-                            DataType = new DataType(GetDataTypeFromString(GetLabelValue(ParameterStrings.GetParameterDataType(i), subElementCnt.Lbl)), false, false),
+                            IdShort = GetLabelValue(ParameterStrings.GetParameterName(i), subElementCnt.Lbl),
+                            DataType = new DataType(GetDataTypeFromString(GetLabelValue(ParameterStrings.GetParameterDataType(i), subElementCnt.Lbl)), false),
                             Index = i
                         };
-                        op.InputParameters.Add(param);
+                        op.In.Add(param);
                     }
                 }
 
-                op.OutputParameters = new List<IParameter>()
+                op.Out = new List<IOperationVariable>()
                 {
-                    new Parameter()
+                    new OperationVariable()
                     {
                         Index = 0,
-                        DataType = new DataType(dataObjectType, false, false, dataTypeDefinition)                        
+                        DataType = new DataType(dataObjectType, false, dataTypeDefinition)                        
                     }
                 };
                 return op;
@@ -634,26 +655,24 @@
             return null;
         }
 
-        private static EventDescription ConvertCntToEvent(cnt subElementCnt, cin schema)
+        private static Event ConvertCntToEvent(cnt subElementCnt, cin schema)
         {
             if (subElementCnt != null)
             {
-                EventDescription op = new EventDescription()
+                Event ev = new Event()
                 {
-                    Identification = new Identifier(GetLabelValue(Labels.ID, subElementCnt.Lbl), Identificator.Internal),
-                    Description = GetLabelValue(Labels.DESCRIPTION, subElementCnt.Lbl),
-                    DisplayName = subElementCnt.Rn,
-                    EntityType = (EntityType)Enum.Parse(typeof(EntityType), GetLabelValue(EventIdentifier.ENTITY_TYPE, subElementCnt.Lbl)),
-                    EventCategory = GetLabelValue(EventIdentifier.EVENT_CATEGORY, subElementCnt.Lbl),
-                    EventName = GetLabelValue(EventIdentifier.EVENT_NAME, subElementCnt.Lbl),
+                    Descriptions = GetDescriptionsFromLabels(subElementCnt.Lbl),
+                    IdShort = GetLabelValue(Labels.ID, subElementCnt.Lbl),                   
+                    Category = GetLabelValue(EventIdentifier.EVENT_CATEGORY, subElementCnt.Lbl),
                 };
 
                 if(schema != null)
                 {
-                    op.SchemaType = (SchemaType)Enum.Parse(typeof(SchemaType), GetLabelValue(EventIdentifier.SCHEMA_TYPE, schema.Lbl));
-                    op.Schema = schema.Con;
+                    SchemaType schemaType = (SchemaType)Enum.Parse(typeof(SchemaType), GetLabelValue(EventIdentifier.SCHEMA_TYPE, schema.Lbl));
+                    string schemaString = schema.Con;
+                    ev.DataType = new DataType(null, schemaType, schemaString);
                 }
-                return op;
+                return ev;
             }
             return null;
         }
@@ -664,15 +683,18 @@
             {
                 var aas = new AssetAdministrationShell()
                 {
-                    Identification = new Identifier(GetLabelValue(Labels.ID, aasAe.Lbl), Identificator.Internal),
-                    DisplayName = GetLabelValue(Labels.DISPLAY_NAME, aasAe.Lbl),
-                    SemanticReference = new Identifier(GetLabelValue(AssetLabels.ASSET_TYPE_DEFINITION, aasAe.Lbl), Identificator.Internal),
-                    Assets = new ElementContainer<IAsset>() {
-                        new Asset() {
-                            Identification = new Identifier(GetLabelValue(AssetLabels.ASSET_ID, aasAe.Lbl), Identificator.Internal),
-                            AssetKind = GetLabelValue(AssetLabels.ASSET_KIND, aasAe.Lbl).Contains(((int)Kind.Type).ToString()) ? Kind.Type : Kind.Instance
-                    } },
-                    Description = GetLabelValue(Labels.DESCRIPTION, aasAe.Lbl)
+                    Identification = new Identifier(GetLabelValue(Labels.UUID, aasAe.Lbl), KeyType.Custom),
+                    IdShort = GetLabelValue(Labels.ID, aasAe.Lbl),
+                    Asset =
+                        new Asset()
+                        {
+                            Identification = new Identifier(GetLabelValue(AssetLabels.ASSET_UUID, aasAe.Lbl), KeyType.Custom),
+                            IdShort = GetLabelValue(AssetLabels.ASSET_ID, aasAe.Lbl),
+                            Kind = GetLabelValue(AssetLabels.ASSET_KIND, aasAe.Lbl).Contains(((int)Kind.Type).ToString()) ? Kind.Type : Kind.Instance,
+                            SemanticId = new Reference(new GlobalKey(KeyElements.Asset, KeyType.URI, GetLabelValue(AssetLabels.ASSET_TYPE_DEFINITION, aasAe.Lbl)))
+                        },
+                    Descriptions = GetDescriptionsFromLabels(aasAe.Lbl),
+
                 };
                 return aas;
             }
@@ -681,90 +703,155 @@
 
         #endregion  
 
-        #region Add-Operations
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> AddAAS(IAssetAdministrationShell aas)
+        public IAssetAdministrationShell ConvertAASDescriptorToAAS(AssetAdministrationShellDescriptor aasDesc)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName);
-            string typeOrInstance = (aas.Assets[0].AssetKind == Kind.Type) ? ElementType.AAS_TYPE : ElementInstance.AAS;
-            var labels = new List<string>
+            if (aasDesc == null)
+                return null;
+
+            var aas = new AssetAdministrationShell()
             {
-                BASYS_TYPE_IDENTIFIER + SEPERATOR + typeOrInstance,                
-                Labels.ID + SEPERATOR + aas.Identification.Id,
-                Labels.DISPLAY_NAME + SEPERATOR + aas.DisplayName,
-                AssetLabels.ASSET_TYPE_DEFINITION + SEPERATOR + aas.SemanticReference.Id,
-                AssetLabels.ASSET_KIND + SEPERATOR + (int)aas.Assets[0].AssetKind.Value,
-                AssetLabels.ASSET_ID + SEPERATOR + aas.Assets[0].Identification.Id
+                Asset = aasDesc.Asset,
+                Identification = aasDesc.Identification,
+                IdShort = aasDesc.IdShort,
+                MetaData = aasDesc.MetaData,
+                Administration = aasDesc.Administration,
+                Category = aasDesc.Category,
+                Descriptions = aasDesc.Descriptions
             };
 
-            if (!string.IsNullOrEmpty(aas.Description))
-                labels.Add(Labels.DESCRIPTION + SEPERATOR + aas.Description);
+            if (aasDesc.Submodels?.Count > 0)
+            {
+                aas.Submodels = new ElementContainer<ISubmodel>();
+                foreach (var submodel in aasDesc.Submodels)
+                {
+                    var convertedSubmodel = ConvertSubmodelDescriptorToSubmodel(submodel);
+                    if (convertedSubmodel != null)
+                        aas.Submodels.Add(convertedSubmodel);
+                }
+            }
+            return aas;
+        }
 
-            ApplicationEntity ae = new ApplicationEntity(aas.DisplayName, aas.Identification.Id, true, aas.Identification.Id, null, labels);
+        public ISubmodel ConvertSubmodelDescriptorToSubmodel(SubmodelDescriptor submodelDesc)
+        {
+            if (submodelDesc == null)
+                return null;
+
+            var submodel = new Submodel()
+            {
+                Identification = submodelDesc.Identification,
+                MetaData = submodelDesc.MetaData,
+                Administration = submodelDesc.Administration,
+                IdShort = submodelDesc.IdShort,
+                Category = submodelDesc.Category,
+                Descriptions = submodelDesc.Descriptions,
+                SemanticId = submodelDesc.SemanticId,
+                Kind = submodelDesc.Kind
+            };
+
+            return submodel;
+        }
+
+        #region Add-Operations
+        public static Result<Response> AddAAS(IAssetAdministrationShell aas)
+        {
+            if (aas == null || aas.Identification == null || aas.IdShort == null || aas.Asset == null || aas.Asset.Identification == null || aas.Asset.IdShort == null)
+                return new Result<Response>(new ArgumentNullException());
+
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName);
+
+            List<string> labels = new List<string>();
+
+            if (aas.Asset.Kind.HasValue)
+            {
+                if (aas.Asset.Kind.Value == Kind.Type)
+                {
+                    labels.Add(AssetLabels.ASSET_KIND + SEPERATOR + TYPE);
+                    labels.Add(BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementType.AAS_TYPE);
+                }
+                else
+                {
+                    labels.Add(AssetLabels.ASSET_KIND + SEPERATOR + INSTANCE);
+                    labels.Add(BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.AAS);
+                }
+            }
+            else
+            {
+                labels.Add(AssetLabels.ASSET_KIND + SEPERATOR + INSTANCE);
+                labels.Add(BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.AAS);
+            }
+
+            labels.Add(Labels.ID + SEPERATOR + aas.IdShort);
+            labels.Add(Labels.UUID + SEPERATOR + aas.Identification.Id);
+            labels.Add(Labels.DISPLAY_NAME + SEPERATOR + aas.IdShort);
+
+            labels.Add(AssetLabels.ASSET_ID + SEPERATOR + aas.Asset.IdShort);
+            labels.Add(AssetLabels.ASSET_UUID + SEPERATOR + aas.Asset.Identification.Id);
+
+            if (aas.Asset.SemanticId?.Keys?.Count > 0)
+                labels.Add(AssetLabels.ASSET_TYPE_DEFINITION + SEPERATOR + aas.Asset.SemanticId.Keys.First().Value);
+
+            if (aas.Descriptions?.Count > 0)
+                labels.Add(Labels.DESCRIPTION + SEPERATOR + aas.Descriptions.First().Text);
+
+            ApplicationEntity ae = new ApplicationEntity(aas.IdShort, aas.Identification.Id, true, aas.IdShort, null, labels);
             var result = ae.Create(oneM2MClient, req);
             return result;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> AddProperty(string aasId, string subModelId, IPropertyDescription property)
+        public static Result<Response> AddProperty(string aasId, string submodelId, IDataElement property)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId);
-            string dty = string.Empty;
-            if (property.DataType.DataObjectType.Value == DataObjectType.Object && !string.IsNullOrEmpty(property.DataType.SemanticReference.Id))
-                dty = property.DataType.SemanticReference.Id;
-            else
-                dty = property.DataType.DataObjectType.Value.ToString().ToLower();
-
-
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId);
             var labels = new List<string>
             {
                 BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.PROPERTY,
-                DATATYPE_IDENTIFIER + SEPERATOR + dty,
             };
 
-            if (property.Readable.HasValue && property.Readable.Value)
+            string dty = string.Empty;
+            if (property.ModelType == ModelType.DataElementCollection || property.ModelType == ModelType.SubmodelElementCollection)
+            {
+                labels.Add(Labels.COLLECTION);
+                labels.Add(DATATYPE_IDENTIFIER + SEPERATOR + "string");
+            }
+            else
+            {
+                if (property.ValueType.DataObjectType == DataObjectType.AnyType && property.ValueType.SemanticId?.Keys?.Count > 0)
+                    dty = property.ValueType.SemanticId.Keys.First().Value;
+                else
+                    dty = SmartControlUtils.ConvertDataTypeNames(property.ValueType);
+                labels.Add(DATATYPE_IDENTIFIER + SEPERATOR + dty);
+            }
+
+            //if (property.DataElementInformation.Readable.HasValue && property.DataElementInformation.Readable.Value)
                 labels.Add(Labels.READABLE);
-            if (property.Writable.HasValue && property.Writable.Value)
+            //if (property.DataElementInformation.Writable.HasValue && property.DataElementInformation.Writable.Value)
                 labels.Add(Labels.WRITABLE);
-            if (property.Eventable.HasValue && property.Eventable.Value)
+            //if (property.DataElementInformation.Eventable.HasValue && property.DataElementInformation.Eventable.Value)
                 labels.Add(Labels.EVENTABLE);
 
-            if (property.DataType.IsCollection)
-                labels.Add(Labels.COLLECTION);
+            if (property.SemanticId?.Keys?.Count > 0)
+                labels.Add(TYPE_IDENTIFIER + SEPERATOR + property.SemanticId.Keys.First().Value);
 
-            if (property.SemanticReference != null)
-                labels.Add(TYPE_IDENTIFIER + SEPERATOR + property.SemanticReference.Id);
+            if (!string.IsNullOrEmpty(property.IdShort))
+                labels.Add(Labels.ID + SEPERATOR + property.IdShort);
+            if (property.Descriptions?.Count > 0)
+                labels.Add(Labels.DESCRIPTION + SEPERATOR + property.Descriptions.First().Text);
 
-            if (!string.IsNullOrEmpty(property.Identification.Id))
-                labels.Add(Labels.ID + SEPERATOR + property.Identification.Id);
-            if (!string.IsNullOrEmpty(property.Description))
-                labels.Add(Labels.DESCRIPTION + SEPERATOR + property.Description);
-
-            Container cont = new Container(property.Identification.Id, null, labels, 8);
+            Container cont = new Container(property.IdShort, null, labels, 8);
             cont.Create(oneM2MClient, req);
 
-            req.AddPath(property.Identification.Id);
+            req.AddPath(property.IdShort);
             Container.Create(oneM2MClient, req, ContainerStrings.DATA, null, null, 8);
-            req.AddPath(ContainerStrings.DATA);
-            var result = CreateSubscription(req, property.Endpoint);
 
-            /*
-            if (property.Readable.HasValue && property.Readable.Value)
-            {
-                Container.Create(oneM2MClient, req, ContainerStrings.GET, null, null, 8);
-                CreateRequestConstruct(new string[] { aasId, subModelId, property.Identification.Id, ContainerStrings.GET }, property.Endpoint);
-            }
-            if (property.Writable.HasValue && property.Writable.Value)
-            {
-                Container.Create(oneM2MClient, req, ContainerStrings.SET, null, null, 8);
-                CreateRequestConstruct(new string[] { aasId, subModelId, property.Identification.Id, ContainerStrings.SET }, property.Endpoint);
-            }
-            */
-            /*
-            if (value != null && result.Success)
-                SetProperty(aasId, subModelId, propertyId, value);
-            */
+            if (property.Value != null)
+                UpdatePropertyValue(aasId, submodelId, property.IdShort, new DataElementValue(property.Value, property.ValueType));
+
+            req.AddPath(ContainerStrings.DATA);
+            var result = CreateSubscription(req, Settings.CallbackEndpointUrl);
+
             return result;
         }
 
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> CreateSubscription(Request req, string subscriptionUri)
+        public static Result<Response> CreateSubscription(Request req, string subscriptionUri)
         {
             req.From(subscriptionUri);
             Subscription sub = new Subscription(DEFAULT_SUBSCRIPTION_NAME, new List<string> { subscriptionUri }, new List<notificationEventType> { notificationEventType.CreateofDirectChildResource });
@@ -773,26 +860,26 @@
             return result;
         }
 
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> AddEvent(string aasId, string subModelId, IEventDescription eventDescription)
+        public static Result<Response> AddEvent(string aasId, string submodelId, IEvent eventDescription)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId);
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId);
 
             var labels = new List<string>
             {
                 BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.EVENT,              
-                EventIdentifier.ENTITY_TYPE + SEPERATOR +  Enum.GetName(typeof(EntityType), eventDescription.EntityType.Value),
-                EventIdentifier.EVENT_NAME + SEPERATOR + eventDescription.EventName,
-                EventIdentifier.EVENT_CATEGORY  + SEPERATOR + eventDescription.EventCategory
+                EventIdentifier.EVENT_CATEGORY  + SEPERATOR + eventDescription.Category,
+                DATATYPE_IDENTIFIER + SEPERATOR + "void"
             };
+            //if (!string.IsNullOrEmpty(eventDescription.Identification.Id))
+               //labels.Add(Labels.UUID + SEPERATOR + eventDescription.Identification.Id);
+            if (!string.IsNullOrEmpty(eventDescription.IdShort))
+                labels.Add(Labels.ID + SEPERATOR + eventDescription.IdShort);
+            if (eventDescription.Descriptions?.Count > 0)
+                labels.Add(Labels.DESCRIPTION + SEPERATOR + eventDescription.Descriptions.First().Text);
 
-            if (!string.IsNullOrEmpty(eventDescription.Identification.Id))
-                labels.Add(Labels.ID + SEPERATOR + eventDescription.Identification.Id);
-            if (!string.IsNullOrEmpty(eventDescription.Description))
-                labels.Add(Labels.DESCRIPTION + SEPERATOR + eventDescription.Description);
+            Container.Create(oneM2MClient, req, eventDescription.IdShort, null, labels, 1);
 
-            Container.Create(oneM2MClient, req, eventDescription.Identification.Id, null, labels, 1);
-
-            req.AddPath(eventDescription.Identification.Id);
+            req.AddPath(eventDescription.IdShort);
 
             var result = Container.Create(oneM2MClient, req, ContainerStrings.DATA, null, null, 8);
 
@@ -803,84 +890,96 @@
             result = sub.Create(oneM2MClient, req);
             
 
-            if (!string.IsNullOrEmpty(eventDescription.Schema) && eventDescription.SchemaType.HasValue)
+            if (eventDescription.DataType != null && !string.IsNullOrEmpty(eventDescription.DataType.Schema) && eventDescription.DataType.SchemaType.HasValue)
             {
                 req.From(DEFAULT_FROM);
                 Container.Create(oneM2MClient, req, ContainerStrings.SCHEMA, null, null, 1);
-                req.SetPath(aasId, subModelId, eventDescription.Identification.Id, ContainerStrings.SCHEMA);
+                req.SetPath(aasId, submodelId, eventDescription.IdShort, ContainerStrings.SCHEMA);
 
                 var schemaLabels = new List<string>();
-                schemaLabels.Add(EventIdentifier.SCHEMA_TYPE + SEPERATOR + Enum.GetName(typeof(SchemaType), eventDescription.SchemaType.Value));
-                ContentInstance.Create(oneM2MClient, req, EventIdentifier.SCHEMA_CIN, eventDescription.Schema, null, schemaLabels);
+                schemaLabels.Add(EventIdentifier.SCHEMA_TYPE + SEPERATOR + Enum.GetName(typeof(SchemaType), eventDescription.DataType.SchemaType.Value));
+                ContentInstance.Create(oneM2MClient, req, EventIdentifier.SCHEMA_CIN, eventDescription.DataType.Schema, null, schemaLabels);
             }
             
             return result;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> AddOperation(string aasId, string subModelId, IOperationDescription<IParameter> operation)
+        public static Result<Response> AddOperation(string aasId, string submodelId, IOperation operation)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId);
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId);
 
             var labels = new List<string>
             {
-                BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.OPERATION,
-                RETURN_DATATYPE_IDENTIFIER + SEPERATOR + operation.OutputParameters[0].DataType.DataObjectType.Value.ToString(),
+                BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.OPERATION
             };
 
-            if (operation.InputParameters != null)
+            if (operation.In != null)
             {
-                labels.Add(ParameterStrings.GetParameterLength() + SEPERATOR + operation.InputParameters.Count);
+                labels.Add(ParameterStrings.GetParameterLength() + SEPERATOR + operation.In.Count);
 
-                for (int i = 0; i < operation.InputParameters.Count; i++)
+                for (int i = 0; i < operation.In.Count; i++)
                 {
-                    labels.Add(ParameterStrings.GetParameterName(i) + SEPERATOR + operation.InputParameters[i].ParameterName);
-                    labels.Add(ParameterStrings.GetParameterDataType(i) + SEPERATOR + operation.InputParameters[i].DataType.DataObjectType.Value.ToString().ToLower());
+                    labels.Add(ParameterStrings.GetParameterName(i) + SEPERATOR + operation.In[i].IdShort);
+                    labels.Add(ParameterStrings.GetParameterDataType(i) + SEPERATOR + SmartControlUtils.ConvertDataTypeNames(operation.In[i].DataType));
                 }
             }
             else
                 labels.Add(ParameterStrings.GetParameterLength() + SEPERATOR + 0);
 
-            if (operation.OutputParameters != null)
-                labels.Add(RETURN_DATATYPE_IDENTIFIER + SEPERATOR + operation.OutputParameters[0].DataType.DataObjectType.Value.ToString().ToLower());
+            if (operation.Out?.Count == 1)
+                labels.Add(RETURN_DATATYPE_IDENTIFIER + SEPERATOR + SmartControlUtils.ConvertDataTypeNames(operation.Out[0].DataType));
             else
                 labels.Add(RETURN_DATATYPE_IDENTIFIER + SEPERATOR + "void");
 
 
-            if (!string.IsNullOrEmpty(operation.Identification.Id))
-                labels.Add(Labels.ID + SEPERATOR + operation.Identification.Id);
-            if (!string.IsNullOrEmpty(operation.Description))
-                labels.Add(Labels.DESCRIPTION + SEPERATOR + operation.Description);
+            if (!string.IsNullOrEmpty(operation.IdShort))
+                labels.Add(Labels.ID + SEPERATOR + operation.IdShort);
+            if (operation.Descriptions?.Count > 0)
+                labels.Add(Labels.DESCRIPTION + SEPERATOR + operation.Descriptions.First().Text);
 
-            Container cont = new Container(operation.Identification.Id, null, labels);
+            Container cont = new Container(operation.IdShort, null, labels);
             var result = cont.Create(oneM2MClient, req);
 
-            CreateRequestConstruct(new string[] { aasId, subModelId, operation.Identification.Id }, operation.Endpoint);
+            CreateRequestConstruct(new string[] { aasId, submodelId, operation.IdShort }, Settings.CallbackEndpointUrl);
 
             return result;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> AddSubModel(string aasId, ISubModel subModel)
+        public static Result<Response> AddSubmodel(string aasId, ISubmodel submodel)
         {
             Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId);
 
             var labels = new List<string>
             {
-                BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.SUBMODEL,
-                AssetLabels.ASSET_KIND + SEPERATOR + subModel.SubModelKind.Value,
-                TYPE_IDENTIFIER + SEPERATOR + subModel.SemanticReference.Id
+                BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.SUBMODEL               
             };
 
-            if (!string.IsNullOrEmpty(subModel.Identification.Id))
-                labels.Add(Labels.ID + SEPERATOR + subModel.Identification.Id);
-            if (!string.IsNullOrEmpty(subModel.Description))
-                labels.Add(Labels.DESCRIPTION + SEPERATOR + subModel.Description);
+            if (submodel.SemanticId?.Keys?.Count > 0)
+                labels.Add(TYPE_IDENTIFIER + SEPERATOR + submodel.SemanticId.Keys.First().Value);
+            else
+                labels.Add(TYPE_IDENTIFIER + SEPERATOR + submodel.IdShort);
 
-            Container cont = new Container(subModel.Identification.Id, null, labels);
+            if (submodel.Kind.HasValue)
+            {
+                if (submodel.Kind.Value == Kind.Instance)
+                    labels.Add(AssetLabels.ASSET_KIND + SEPERATOR + INSTANCE);
+                else
+                    labels.Add(AssetLabels.ASSET_KIND + SEPERATOR + TYPE);
+            }
+
+            if (!string.IsNullOrEmpty(submodel.Identification.Id))
+                labels.Add(Labels.UUID + SEPERATOR + submodel.Identification.Id);
+            if (!string.IsNullOrEmpty(submodel.IdShort))
+                labels.Add(Labels.ID + SEPERATOR + submodel.IdShort);
+            if (submodel.Descriptions?.Count > 0)
+                labels.Add(Labels.DESCRIPTION + SEPERATOR + submodel.Descriptions.First().Text);
+
+            Container cont = new Container(submodel.IdShort, null, labels);
             var result = cont.Create(oneM2MClient, req);
             return result;
         }
         #endregion
 
         #region Read-Operations
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> ReadAllAAS(out List<IAssetAdministrationShell> aasList)
+        public static Result<Response> ReadAllAAS(out List<IAssetAdministrationShell> aasList)
         {
             Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName);
             var response = Helper.ReadResourcesByLabels(oneM2MClient, req, new List<string> { BASYS_TYPE_IDENTIFIER + SEPERATOR + ElementInstance.AAS }, out List<resource> resources);
@@ -894,14 +993,14 @@
                         var aas = ConvertAeResourceToAAS(aasAe);
                         if (aas != null)
                         {
-                            ReadSubModels(aas.Identification.Id, out IElementContainer<ISubModel> subModels);
-                            if (subModels?.Count > 0)
+                            ReadSubmodels(aas.IdShort, out ElementContainer<ISubmodel> submodels);
+                            if (submodels?.Count > 0)
                             {
-                                aas.SubModels = new ElementContainer<ISubModel>();
-                                foreach (var subModel in subModels)
+                                aas.Submodels = new ElementContainer<ISubmodel>();
+                                foreach (var submodel in submodels)
                                 {
-                                    string serviceUri = string.Join(PATH_SEPERATOR, PATH_SEPERATOR, aas.Identification.Id, ElementInstance.SUBMODELS, subModel.DisplayName).Replace("//", "/");
-                                    aas.SubModels.Add(new SubModel() { Endpoint = serviceUri });
+                                    //string serviceUri = string.Join(PATH_SEPERATOR, PATH_SEPERATOR, aas.IdShort, ElementInstance.SUBMODELS, submodel.IdShort).Replace("//", "/");
+                                    aas.Submodels.Add(submodel);
                                 }
                             }
                             aasList.Add(aas);
@@ -913,7 +1012,7 @@
             aasList = null;
             return response;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> ReadAAS(string aasId, out IAssetAdministrationShell aas)
+        public static Result<Response> ReadAAS(string aasId, out IAssetAdministrationShell aas)
         {
             if (!string.IsNullOrEmpty(aasId))
             {
@@ -923,16 +1022,16 @@
                     && resources.FirstOrDefault(r => r.Ty.Value == (int)resourceType.AE) != null)
                 {
                     aas = ConvertAeResourceToAAS((ae)resources.FirstOrDefault());
-                    ReadSubModels(aasId, out IElementContainer<ISubModel> subModels);
+                    ReadSubmodels(aasId, out ElementContainer<ISubmodel> submodels);
                     if (aas != null)
                     {
-                        if (subModels != null)
+                        if (submodels != null)
                         {
-                            aas.SubModels = new ElementContainer<ISubModel>();
-                            foreach (var subModel in subModels)
+                            aas.Submodels = new ElementContainer<ISubmodel>();
+                            foreach (var submodel in submodels)
                             {
-                                string serviceUri = string.Join(PATH_SEPERATOR, PATH_SEPERATOR, aasId, ElementInstance.SUBMODELS, subModel.DisplayName).Replace("//", "/");
-                                aas.SubModels.Add(new SubModel() { Endpoint = serviceUri });
+                                //string serviceUri = string.Join(PATH_SEPERATOR, PATH_SEPERATOR, aasId, ElementInstance.SUBMODELS, submodel.IdShort).Replace("//", "/");
+                                aas.Submodels.Add(submodel);
                             }
                         }
                         return response;
@@ -944,20 +1043,20 @@
             aas = null;
             return null;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> ReadSubModel(string aasId, string subModelId, out SubModel subModel)
+        public static Result<Response> ReadSubmodel(string aasId, string submodelId, out Submodel submodel)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId))
             {
-                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId);
-                var result = Helper.ReadResourceTree(oneM2MClient, req, out ObjectTreeBuilder subModelTree);
-                subModel = ReadSubModelFrom(aasId, subModelTree);
+                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId);
+                var result = Helper.ReadResourceTree(oneM2MClient, req, out ObjectTreeBuilder submodelTree);
+                submodel = ReadSubmodelFrom(aasId, submodelTree);
 
                 return result;
             }
-            subModel = null;
+            submodel = null;
             return null;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> ReadSubModels(string aasId, out IElementContainer<ISubModel> subModels)
+        public static Result<Response> ReadSubmodels(string aasId, out ElementContainer<ISubmodel> submodels)
         {
             if (!string.IsNullOrEmpty(aasId))
             {
@@ -965,55 +1064,56 @@
                 var result = Helper.ReadResourceTree(oneM2MClient, req, out ObjectTreeBuilder resTree);
                 if (result.Success && resTree != null && resTree.HasChildren())
                 {
-                    subModels = new ElementContainer<ISubModel>();
+                    submodels = new ElementContainer<ISubmodel>();
                     foreach (ObjectTreeBuilder child in resTree.Children)
                     {
-                        var subModel = ReadSubModelFrom(aasId, child);
-                        subModels.Add(subModel);
+                        var submodel = ReadSubmodelFrom(aasId, child);
+                        submodels.Add(submodel);
                     }
-                    if (subModels.Count == 0)
-                        subModels = null;
+                    if (submodels.Count == 0)
+                        submodels = null;
 
                     return result;
                 }
-                subModels = null;
+                submodels = null;
                 return result;
             }
-            subModels = null;
+            submodels = null;
             return null;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> ReadProperty(string aasId, string subModelId, string propertyId, out PropertyDescription property)
+        public static Result<Response> ReadProperty(string aasId, string submodelId, string propertyId, out Property property)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(propertyId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(propertyId))
             {
-                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, propertyId);
+                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, propertyId);
                 var result = Container.Retrieve(oneM2MClient, req);
                 property = null;
                 if (result.Success && result.Entity.TryGetResource(out cnt prop))
                 {
                     property = ConvertCntToProperty(prop);
-                    if (property != null)
-                    {
-                        req.AddPath(ContainerStrings.DATA, DEFAULT_SUBSCRIPTION_NAME);
-                        //req.AddPath(ContainerStrings.GET, ContainerStrings.REQUEST, DEFAULT_SUBSCRIPTION_NAME);
-                        var listenerUriReq = Subscription.Retrieve(oneM2MClient, req);
-                        if (listenerUriReq.Success && listenerUriReq.Entity.TryGetResource(out sub subUri))
-                            property.Endpoint = string.Join(ELEMENT_SEPERATOR, subUri.Nu);
-                    }
+                    //if (property != null)
+                    //{
+                    //    req.AddPath(ContainerStrings.DATA, DEFAULT_SUBSCRIPTION_NAME);
+                    //    //req.AddPath(ContainerStrings.GET, ContainerStrings.REQUEST, DEFAULT_SUBSCRIPTION_NAME);
+                    //    var listenerUriReq = Subscription.Retrieve(oneM2MClient, req);
+                    //    if (listenerUriReq.Success && listenerUriReq.Entity.TryGetResource(out sub subUri))
+                    //        (property.ElementInformation as ElementInformation).Endpoint = string.Join(ELEMENT_SEPERATOR, subUri.Nu);
+                    //}
                 }
                 return result;
             }
             property = null;
             return null;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> ReadPropertyValue(string aasId, string subModelId, string propertyId, out object value)
+        public static Result<Response> ReadPropertyValue(string aasId, string submodelId, string propertyId, out IValue value)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(propertyId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(propertyId))
             {
-                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, propertyId, ContainerStrings.DATA);
+                ReadProperty(aasId, submodelId, propertyId, out Property property);
+                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, propertyId, ContainerStrings.DATA);
                 var resp = Helper.ReadLatestAddedResource(oneM2MClient, req, out resource data);
                 if (resp.Success && data != null && data is cin dataCin)
-                    value = dataCin.Con;
+                    value = SmartControlUtils.ConvertPropertyValue(dataCin.Con, property.ValueType);
                 else
                     value = null;
                 return resp;
@@ -1021,34 +1121,34 @@
             value = null;
             return null;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> ReadOperation(string aasId, string subModelId, string operationId, out OperationDescription operation)
+        public static Result<Response> ReadOperation(string aasId, string submodelId, string operationId, out Operation operation)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(operationId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(operationId))
             {
-                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, operationId);
+                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, operationId);
                 var result = Container.Retrieve(oneM2MClient, req);
                 operation = null;
                 if (result.Success && result.Entity.TryGetResource(out cnt op))
                 {
                     operation = ConvertCntToOperation(op);
-                    if (operation != null)
-                    {
-                        req.AddPath(ContainerStrings.REQUEST, DEFAULT_SUBSCRIPTION_NAME);
-                        var listenerUriReq = Subscription.Retrieve(oneM2MClient, req);
-                        if (listenerUriReq.Success && listenerUriReq.Entity.TryGetResource(out sub subUri))
-                            operation.Endpoint = string.Join(ELEMENT_SEPERATOR, subUri.Nu);
-                    }
+                    //if (operation != null)
+                    //{
+                    //    req.AddPath(ContainerStrings.REQUEST, DEFAULT_SUBSCRIPTION_NAME);
+                    //    var listenerUriReq = Subscription.Retrieve(oneM2MClient, req);
+                    //    if (listenerUriReq.Success && listenerUriReq.Entity.TryGetResource(out sub subUri))
+                    //        operation.OperationInformation.Endpoint = string.Join(ELEMENT_SEPERATOR, subUri.Nu);
+                    //}
                 }
                 return result;
             }
             operation = null;
             return null;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> ReadEvent(string aasId, string subModelId, string eventId, out EventDescription eventable)
+        public static Result<Response> ReadEvent(string aasId, string submodelId, string eventId, out Event eventable)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(eventId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(eventId))
             {
-                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, eventId);
+                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, eventId);
                 var result = Container.Retrieve(oneM2MClient, req);
                 eventable = null;
                 if (result.Success && result.Entity.TryGetResource(out cnt ev))
@@ -1075,37 +1175,37 @@
         #endregion
 
         #region Remove-Operations
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> RemoveComponent(string[] components)
+        public static Result<Response> RemoveComponent(string[] components)
         {
             Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, components);
             var result = ApplicationEntity.Delete(oneM2MClient, req);
             return result;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> RemoveOperation(string aasId, string subModelId, string operationId)
+        public static Result<Response> RemoveOperation(string aasId, string submodelId, string operationId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(operationId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(operationId))
             {
-                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, operationId);
+                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, operationId);
                 var result = Container.Delete(oneM2MClient, req);
                 return result;
             }
             return null;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> RemoveEvent(string aasId, string subModelId, string eventId)
+        public static Result<Response> RemoveEvent(string aasId, string submodelId, string eventId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(eventId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(eventId))
             {
-                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, eventId);
+                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, eventId);
                 var result = Container.Delete(oneM2MClient, req);
                 return result;
             }
             return null;
         }
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> RemoveProperty(string aasId, string subModelId, string propertyId)
+        public static Result<Response> RemoveProperty(string aasId, string submodelId, string propertyId)
         {
-            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(subModelId) && !string.IsNullOrEmpty(propertyId))
+            if (!string.IsNullOrEmpty(aasId) && !string.IsNullOrEmpty(submodelId) && !string.IsNullOrEmpty(propertyId))
             {
-                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, propertyId);
+                Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, propertyId);
                 var result = Container.Delete(oneM2MClient, req);
                 return result;
             }
@@ -1115,18 +1215,18 @@
 
         #region Event-Operations
 
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> Publish(string aasId, string subModelId, string eventId, IPublishableEvent publishableEvent)
+        public static Result<Response> Publish(string aasId, string submodelId, string eventId, IPublishableEvent publishableEvent)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, eventId, ContainerStrings.DATA);
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, eventId, ContainerStrings.DATA);
 
-            var evResult = ContentInstance.Create(oneM2MClient, req, publishableEvent.Identification.Id, JsonConvert.SerializeObject(publishableEvent));
+            var evResult = ContentInstance.Create(oneM2MClient, req, publishableEvent.IdShort, JsonConvert.SerializeObject(publishableEvent));
 
             return evResult;
         }
 
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> Subscribe(string aasId, string subModelId, string eventId, string subscriberId, string subscriberEndpoint)
+        public static Result<Response> Subscribe(string aasId, string submodelId, string eventId, string subscriberId, string subscriberEndpoint)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, eventId, ContainerStrings.DATA);
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, eventId, ContainerStrings.DATA);
 
             req.From(subscriberEndpoint);
             Subscription sub = new Subscription(EventIdentifier.SUBSCRIBER_SUB + subscriberId, new List<string> { subscriberEndpoint }, new List<notificationEventType> { notificationEventType.CreateofDirectChildResource });
@@ -1136,16 +1236,15 @@
             return result;
         }
 
-        public static oneM2MClient.Utils.ResultHandling.Result<Response> Unsubscribe(string aasId, string subModelId, string eventId, string subscriberId)
+        public static Result<Response> Unsubscribe(string aasId, string submodelId, string eventId, string subscriberId)
         {
-            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, subModelId, eventId, ContainerStrings.DATA, EventIdentifier.SUBSCRIBER_SUB + subscriberId);
+            Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, aasId, submodelId, eventId, ContainerStrings.DATA, EventIdentifier.SUBSCRIBER_SUB + subscriberId);
             var result = Subscription.Delete(oneM2MClient, req);
             return result;
         }
         #endregion
 
         #endregion
-
         #region Utility-Functions
         public static string GetLabelValue(string label, List<string> labels, string seperator = SEPERATOR)
         {
@@ -1157,7 +1256,7 @@
             }
             return null;
         }
-        private static oneM2MClient.Utils.ResultHandling.Result<Response> CreateRequestConstruct(string[] path, string subscriptionListenerUri)
+        private static Result<Response> CreateRequestConstruct(string[] path, string subscriptionListenerUri)
         {
             Request req = RequestFactory.CreateRequest(oneM2MClient, Settings.oneM2MConfig.ClientId, Settings.oneM2MConfig.Endpoint, Settings.oneM2MConfig.CSEName, path);
 
@@ -1176,13 +1275,15 @@
         {
             if (!string.IsNullOrEmpty(dty))
             {
-                if (Enum.TryParse(dty.UppercaseFirst(), out DataObjectType dataType))
+                if (DataObjectType.TryParse(dty, out DataObjectType dataType))
                     return dataType;
                 else
-                    return DataObjectType.Object;
+                    return DataObjectType.AnyType;
             }
             return DataObjectType.None;
         }
+
+      
         #endregion
     }
 }
diff --git a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlExtensions.cs b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlExtensions.cs
new file mode 100644
index 0000000..16bd8c4
--- /dev/null
+++ b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlExtensions.cs
@@ -0,0 +1,124 @@
+using BaSys40.API.AssetAdministrationShell;
+using BaSys40.API.AssetAdministrationShell.Connectables;
+using BaSys40.API.Platform;
+using BaSys40.API.ServiceProvider;
+using BaSys40.Models.Core.AssetAdministrationShell.Generics;
+using Microsoft.Extensions.DependencyInjection;
+using NLog;
+using NLog.Web;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+
+namespace BaSys40.RI.AAS.SmartControl.Extensions
+{
+    public static class SmartControlExtensions
+    {
+        private static SmartControlSettings Settings;
+        private static Logger logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
+        private static IAssetAdministrationShellServiceProvider assetAdministrationShellServiceProvider;
+        private static SmartControlHandler smartControlHandler;
+
+        static SmartControlExtensions()
+        {
+            string settingsPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), SmartControlSettings.FileName);
+            Settings = SmartControlSettings.LoadSettings(settingsPath);
+        }
+        public static IServiceCollection ConfigureSmartControl(this IServiceCollection services, IAssetAdministrationShellServiceProvider aasServiceProvider, SmartControlSettings settings = null)
+        {
+            Settings = settings ?? Settings;
+            assetAdministrationShellServiceProvider = aasServiceProvider;
+            smartControlHandler = new SmartControlHandler(Settings.CallbackEndpointUrl);
+
+            var aas_Deleted = SmartControl.Instance.DeleteAssetAdministrationShell(aasServiceProvider.AssetAdministrationShell.IdShort);
+            logger.Info($"AAS {aasServiceProvider.AssetAdministrationShell.IdShort} deleted - Success: " + aas_Deleted.Success);
+            var aas_Created = SmartControl.Instance.CreateAssetAdministrationShell(aasServiceProvider.AssetAdministrationShell);
+            logger.Info($"AAS {aasServiceProvider.AssetAdministrationShell.IdShort} created - Success: " + aas_Created.Success);
+
+            var connectedAAS = new ConnectedAssetAdministrationShell(SmartControl.Instance);
+            connectedAAS.BindTo(aasServiceProvider.AssetAdministrationShell);
+
+            foreach (var submodel in aasServiceProvider.AssetAdministrationShell.Submodels)
+            {
+                var success = connectedAAS.CreateSubmodel(submodel);
+                logger.Info($"Submodel {submodel.IdShort} created - Success: " + success);
+                var connectedSubmodel = new ConnectedSubmodel(SmartControl.Instance, aasServiceProvider.AssetAdministrationShell);
+                connectedSubmodel.BindTo(submodel);
+                connectedAAS.RegisterSubmodelServiceProvider(submodel.IdShort, connectedSubmodel);
+
+                foreach (var op in connectedSubmodel.RetrieveOperations().Entity)
+                {
+                    var connectedOp = new ConnectedOperation(SmartControl.Instance, aasServiceProvider.AssetAdministrationShell, submodel, op);
+                    smartControlHandler.RegisterMethodCalledEventHandler(connectedSubmodel, connectedOp, GenericMethodHandler);
+                }
+
+                foreach (var de in connectedSubmodel.RetrieveDataElements().Entity)
+                {
+                    var connectedDataElement = new ConnectedDataElement(SmartControl.Instance, aasServiceProvider.AssetAdministrationShell, submodel, de);
+                    smartControlHandler.RegisterGetPropertyValueHandler(connectedSubmodel, connectedDataElement, GenericGetValueHandler);
+                    smartControlHandler.RegisterSetPropertyValueHandler(connectedSubmodel, connectedDataElement, GenericSetValueHandler);
+
+                    assetAdministrationShellServiceProvider.GetSubmodelServiceProvider(submodel.IdShort).SubscribeUpdates(de.IdShort, value =>
+                    {
+                        SmartControl.Instance.UpdateDataElementValue(aasServiceProvider.AssetAdministrationShell.IdShort, submodel.IdShort, de.IdShort, value);
+                    });
+                }
+            }
+
+            services.AddSingleton<IAssetAdministrationShellAggregator, SmartControl>(sp => { return SmartControl.Instance; });
+            services.AddSingleton<IAssetAdministrationShellServiceProvider, ConnectedAssetAdministrationShell>(sp => { return connectedAAS; });
+
+            return services;
+        }
+
+        private static void GenericSetValueHandler(IConnectableDataElement dataElement, IValue value)
+        {
+            var handler = assetAdministrationShellServiceProvider.GetSubmodelServiceProvider(dataElement.Submodel.IdShort)
+                .RetrieveDataElementHandler(dataElement.DataElement.IdShort);
+
+            handler?.SetHandler?.Invoke(dataElement.DataElement, value);
+        }
+
+        private static IValue GenericGetValueHandler(IConnectableDataElement dataElement)
+        {
+            var handler = assetAdministrationShellServiceProvider.GetSubmodelServiceProvider(dataElement.Submodel.IdShort)
+                 .RetrieveDataElementHandler(dataElement.DataElement.IdShort);
+
+            return handler?.GetHandler?.Invoke(dataElement.DataElement);
+        }
+
+        private static OperationResult GenericMethodHandler(IConnectableOperation operation, List<IArgument> inputArguments, List<IArgument> outputArguments)
+        {
+            var del = assetAdministrationShellServiceProvider.GetSubmodelServiceProvider(operation.Submodel.IdShort)
+                 .RetrieveMethodDelegate(operation.Operation.IdShort);
+
+            if (del is MethodCalledHandler mch)
+                return mch.Invoke(operation.Operation, inputArguments, outputArguments);
+            else
+            {
+                if (inputArguments == null || inputArguments.Count == 0)
+                    del.DynamicInvoke();
+                else
+                {
+                    object[] args = new object[inputArguments.Count];
+                    for (int i = 0; i < args.Length; i++)
+                    {
+                        args[i] = inputArguments[i].Value;
+                    }
+                    del.DynamicInvoke(args);
+                }
+            }
+
+            return new OperationResult(true);
+        }
+
+        public static void Shutdown()
+        {
+            if(!string.IsNullOrEmpty(assetAdministrationShellServiceProvider?.AssetAdministrationShell?.IdShort))
+                SmartControl.Instance.DeleteAssetAdministrationShell(assetAdministrationShellServiceProvider.AssetAdministrationShell.IdShort);
+
+            smartControlHandler.Dispose();
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlHandler.cs b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlHandler.cs
index d4e4ac0..dfd4ee8 100644
--- a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlHandler.cs
+++ b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlHandler.cs
@@ -13,76 +13,97 @@
 using System.Linq;
 using System.Net;
 using BaSys40.API.Platform;
-using Newtonsoft.Json.Linq;
+using NLog;
 
 namespace BaSys40.RI.AAS.SmartControl
 {
-    public class SmartControlHandler : IAssetAdministrationShellHandler
+    public class SmartControlHandler : IAssetAdministrationShellHandler, IDisposable
     {
         private readonly SimpleLocalHttpServer server;
         private static Dictionary<string, IConnectableOperation> connectedOperations = new Dictionary<string, IConnectableOperation>();
-        private static Dictionary<string, IConnectableProperty> connectedProperties = new Dictionary<string, IConnectableProperty>();
+        private static Dictionary<string, IConnectableDataElement> connectedProperties = new Dictionary<string, IConnectableDataElement>();
         private static Dictionary<string, IConnectableEvent> connectedEvents = new Dictionary<string, IConnectableEvent>();
-        public SmartControlHandler(int localHttpPort = 8544)
+
+        private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
+
+        public SmartControlHandler(string endpoint)
         {
-            server = new SimpleLocalHttpServer(localHttpPort);
-            server.Start(HandleNotification);
+            server = new SimpleLocalHttpServer(endpoint);
+            server.Start(HandleNotification, HandleResponse);
         }
-        public void RegisterGetPropertyValueHandler(IConnectableSubModel connectableSubModel, IConnectableProperty connectableProperty, GetPropertyValueHandler getPropertyValueHandler)
+
+        public SmartControlHandler(int localHttpPort) : this("http://127.0.0.1:" + localHttpPort)
+        { }
+
+        public SmartControlHandler() : this(SmartControl.Settings.CallbackEndpointUrl)
+        { }
+
+        public void RegisterGetPropertyValueHandler(IConnectableSubmodel connectableSubmodel, IConnectableDataElement connectableProperty, GetDataElementValueEventHandler getPropertyValueHandler)
         {
-            var cPropId = string.Join("/", connectableSubModel.SubModel.Identification.Id, connectableProperty.Property.Identification.Id);
+            var cPropId = string.Join("/", connectableSubmodel.Submodel.IdShort, connectableProperty.DataElement.IdShort);
             if (connectedProperties.ContainsKey(cPropId))
             {
-                connectedProperties[cPropId].GetPropertyValueHandler += getPropertyValueHandler;
+                connectedProperties[cPropId].GetDataElementValueHandler += getPropertyValueHandler;
             }
             else
             {
-                connectableProperty.GetPropertyValueHandler += getPropertyValueHandler;
+                connectableProperty.GetDataElementValueHandler += getPropertyValueHandler;
                 connectedProperties.Add(cPropId, connectableProperty);
             }
         }
 
-        public void RegisterSetPropertyValueHandler(IConnectableSubModel connectableSubModel, IConnectableProperty connectableProperty, SetPropertyValueHandler SetPropertyValueHandler)
+        public void RegisterSetPropertyValueHandler(IConnectableSubmodel connectableSubmodel, IConnectableDataElement connectableProperty, SetDataElementValueEventHandler SetPropertyValueHandler)
         {
-            var cPropId = string.Join("/", connectableSubModel.SubModel.Identification.Id, connectableProperty.Property.Identification.Id);
+            var cPropId = string.Join("/", connectableSubmodel.Submodel.IdShort, connectableProperty.DataElement.IdShort);
             if (connectedProperties.ContainsKey(cPropId))
             {
-                connectedProperties[cPropId].SetPropertyValueHandler += SetPropertyValueHandler;
+                connectedProperties[cPropId].SetDataElementValueHandler += SetPropertyValueHandler;
             }
             else
             {
-                connectableProperty.SetPropertyValueHandler += SetPropertyValueHandler;
+                connectableProperty.SetDataElementValueHandler += SetPropertyValueHandler;
                 connectedProperties.Add(cPropId, connectableProperty);
             }
         }
-        public void RegisterMethodCalledEventHandler(IConnectableSubModel connectableSubModel, IConnectableOperation connectableOperation, MethodCalledEventHandler handler)
+        public void RegisterMethodCalledEventHandler(IConnectableSubmodel connectableSubmodel, IConnectableOperation connectableOperation, MethodCalledEventHandler handler)
         {
             connectableOperation.OnCallMethod += handler;
-            var cOpId = string.Join("/", connectableSubModel.SubModel.Identification.Id, connectableOperation.Operation.Identification.Id);
+            var cOpId = string.Join("/", connectableSubmodel.Submodel.IdShort, connectableOperation.Operation.IdShort);
             if (!connectedOperations.ContainsKey(cOpId))
                 connectedOperations.Add(cOpId, connectableOperation);
             else
                 connectedOperations[cOpId] = connectableOperation;
         }
         
-        public void RegisterEventHandler(IConnectableSubModel connectableSubModel, IConnectableEvent connectableEvent, BaSys40.API.AssetAdministrationShell.EventHandler handler)
+        public void RegisterEventHandler(IConnectableSubmodel connectableSubmodel, IConnectableEvent connectableEvent, BaSys40.API.AssetAdministrationShell.EventHandler handler)
         {
             connectableEvent.EventHandler += handler;
-            var cEvId = string.Join("/", connectableSubModel.SubModel.Identification.Id, connectableEvent.Event.Identification.Id);
+            var cEvId = string.Join("/", connectableSubmodel.Submodel.IdShort, connectableEvent.Event.IdShort);
             if (!connectedEvents.ContainsKey(cEvId))
                 connectedEvents.Add(cEvId, connectableEvent);
             else
                 connectedEvents[cEvId] = connectableEvent;
         }
-        
+
+        private void HandleResponse(HttpListenerResponse obj)
+        {
+            obj.StatusCode = (int)HttpStatusCode.OK;
+            obj.Close();
+        }
+
         private void HandleNotification(HttpListenerRequest obj)
         {
+            logger.Debug("Enter HandleNotification(...), Incoming request: {0},{1}", obj.HttpMethod, obj.Url);
+            
             Notification notification = Notification.ReadFrom(obj);
             if (notification != null)
             {
+                logger.Debug("Parsed notification, subscription reference: {0}, notification event?: {1}", notification.SubscriptionReference, notification.NotificationEvent);
+
                 Request request = RequestFactory.CreateRequest(SmartControl.oneM2MClient, SmartControl.Settings.oneM2MConfig.ClientId, SmartControl.Settings.oneM2MConfig.Endpoint, notification.NotificationEvent.Representation.Ri.Replace("/in-cse/", string.Empty));
                 var result = Helper.DiscoverResource(SmartControl.oneM2MClient, request, out List<string> resourceUrils);
-                if (result.Success && resourceUrils.Count > 0)
+                if (result.Success && resourceUrils != null && resourceUrils.Count > 0)
+                {
                     if (notification.TryGetResource(out ContentInstance requestCall))
                     {
                         string[] resourceTree = null;
@@ -102,70 +123,28 @@
                         }
                         if (resourceTree.Contains(SmartControl.ContainerStrings.DATA))
                         {
-                            if (connectedProperties.TryGetValue(resourceUril, out IConnectableProperty cProp))
+                            if (connectedProperties.TryGetValue(resourceUril, out IConnectableDataElement cProp))
                             {
-                                var val = new ElementValue<string>(requestCall.Content, DataObjectType.String);
-                                cProp.SetLocalValue(val);
-                            }
-                        }
-                        else if (resourceTree.Contains(SmartControl.ContainerStrings.GET))
-                        {
-                            if (connectedProperties.TryGetValue(resourceUril, out IConnectableProperty cProp))
-                            {
-                                var value = cProp.GetLocalValue();
-
-                                request = RequestFactory.CreateRequest(SmartControl.oneM2MClient, SmartControl.Settings.oneM2MConfig.ClientId, SmartControl.Settings.oneM2MConfig.Endpoint, SmartControl.Settings.oneM2MConfig.CSEName,
-                                        resourceTree[1], resourceTree[2], resourceTree[3], SmartControl.ContainerStrings.GET, SmartControl.ContainerStrings.RESPONSE);
-                                ContentInstance.Create(SmartControl.oneM2MClient, request, requestCall.ResourceName, value.ToString());
-
-                                request = RequestFactory.CreateRequest(SmartControl.oneM2MClient, SmartControl.Settings.oneM2MConfig.ClientId, SmartControl.Settings.oneM2MConfig.Endpoint, SmartControl.Settings.oneM2MConfig.CSEName,
-                                        resourceTree[1], resourceTree[2], resourceTree[3], SmartControl.ContainerStrings.DATA);
-                                ContentInstance.Create(SmartControl.oneM2MClient, request, Guid.NewGuid().ToString(), value.ToString());
-                            }
-                        }
-                        else if (resourceTree.Contains(SmartControl.ContainerStrings.SET))
-                        {
-                            if (connectedProperties.TryGetValue(resourceUril, out IConnectableProperty cProp))
-                            {
-                                var val = new ElementValue<string>(requestCall.Content, DataObjectType.String);
-                                cProp.SetLocalValue(val);
-
-                                request = RequestFactory.CreateRequest(SmartControl.oneM2MClient, SmartControl.Settings.oneM2MConfig.ClientId, SmartControl.Settings.oneM2MConfig.Endpoint, SmartControl.Settings.oneM2MConfig.CSEName,
-                                        resourceTree[1], resourceTree[2], resourceTree[3], SmartControl.ContainerStrings.SET, SmartControl.ContainerStrings.RESPONSE);
-                                ContentInstance.Create(SmartControl.oneM2MClient, request, requestCall.ResourceName, requestCall.Content);
+                                var value = SmartControlUtils.ConvertPropertyValue(requestCall.Content, cProp.DataElement.ValueType);
+                                cProp.SetLocalValue(value);
                             }
                         }
                         else
                         {
                             if (connectedOperations.TryGetValue(resourceUril, out IConnectableOperation cOp))
                             {
-                                string urlDecoded = WebUtility.UrlDecode(requestCall.Content);
-                                JArray ja = JArray.Parse(urlDecoded);
-                                string[] args = ja.ToObject<string[]>();
-                                List<IArgument> inputArguments = SmartControlUtils.ConvertStringArguments(args);
+                                List<IArgument> inputArguments = SmartControlUtils.ConvertStringArguments(requestCall.Content, cOp.Operation.In);
                                 List<IArgument> outputArguments = new List<IArgument>();
-                                var invokeResult = cOp.InvokeLocal(inputArguments, out outputArguments, 2000);
+                                var invokeResult = cOp.InvokeLocal(inputArguments, outputArguments, 10000);
                                 if (invokeResult.Success)
                                 {
-                                    string contentString = string.Empty;
-                                    if (outputArguments.Count > 0)
-                                    {
-                                        string[] outArgs = SmartControlUtils.ConvertStringArguments(outputArguments);
-                                        contentString = "[" + string.Join(SmartControl.ELEMENT_SEPERATOR, outArgs) + "]";
-                                    }
-                                    else
-                                        contentString = "[]";
+                                    string argumentString = SmartControlUtils.ConvertStringArguments(outputArguments);
 
-                                    //string urlEncoded = WebUtility.UrlEncode(contentString);
                                     request = RequestFactory.CreateRequest(SmartControl.oneM2MClient, SmartControl.Settings.oneM2MConfig.ClientId, SmartControl.Settings.oneM2MConfig.Endpoint, SmartControl.Settings.oneM2MConfig.CSEName,
                                         resourceTree[1], resourceTree[2], resourceTree[3], resourceTree[4], SmartControl.ContainerStrings.RESPONSE);
-                                    ContentInstance.Create(SmartControl.oneM2MClient, request, requestCall.ResourceName, contentString);
-
-                                    request = RequestFactory.CreateRequest(SmartControl.oneM2MClient, SmartControl.Settings.oneM2MConfig.ClientId, SmartControl.Settings.oneM2MConfig.Endpoint, SmartControl.Settings.oneM2MConfig.CSEName,
-                                        resourceTree[1], resourceTree[2], resourceTree[3], resourceTree[4], SmartControl.ContainerStrings.REQUEST, requestCall.ResourceName);
-                                    ContentInstance.Delete(SmartControl.oneM2MClient, request);
+                                    var labels = new List<string>() { SmartControl.RELATION + SmartControl.SEPERATOR + notification.NotificationEvent.Representation.Ri };
+                                    ContentInstance.Create(SmartControl.oneM2MClient, request, requestCall.ResourceName, argumentString, null, labels);
                                 }
-
                             }
                             else if (connectedEvents.TryGetValue(resourceUril, out IConnectableEvent cEv))
                             {
@@ -173,7 +152,30 @@
                             }
                         }
                     }
+                }
             }
         }
+
+        #region IDisposable Support
+        private bool disposedValue = false; // To detect redundant calls
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+                    server.Stop();
+                }
+                disposedValue = true;
+            }
+        }
+
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+        #endregion
     }
 }
diff --git a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlIdentifier.cs b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlIdentifier.cs
index cc5ca46..6a92809 100644
--- a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlIdentifier.cs
+++ b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlIdentifier.cs
@@ -11,16 +11,24 @@
         public const string DATATYPE_IDENTIFIER = "dty";
         public const string RETURN_DATATYPE_IDENTIFIER = "rdty";
 
+        public const int DEFAULT_TIMEOUT = 10000;
+
         public const string DEFAULT_FROM = "admin:admin";
         public const string DEFAULT_SUBSCRIPTION_NAME = "default_subscription";
         public const string DEFAULT_SUBSCRIPTION_URI = "http://127.0.0.1:8544";
 
+        public const string INSTANCE = "inst";
+        public const string TYPE = "ty";
+
+        public const string RELATION = "rel";
+
 
         public static class AssetLabels
         {
             public const string ASSET_TYPE_DEFINITION = "atd";
             public const string ASSET_ID = "aid";
             public const string ASSET_KIND = "ak";
+            public const string ASSET_UUID = "auuid";
         }
 
         public static class ElementType
@@ -46,8 +54,6 @@
         {
             public const string ORIGINATOR = "orig";
             public const string SCHEMA_TYPE = "sc-ty";
-            public const string ENTITY_TYPE = "ent-ty";
-            public const string EVENT_NAME = "name";
             public const string EVENT_CATEGORY = "cat";
             public const string SCHEMA_CIN = "cin_schema";
             public const string SUBSCRIBER_SUB = "sub_subscriber";
@@ -67,12 +73,13 @@
         public static class Labels
         {
             public const string READABLE = "rd";
-            public const string WRITABLE = "wd";
-            public const string EVENTABLE = "evt";
+            public const string WRITABLE = "wr";
+            public const string EVENTABLE = "ev";
             public const string ID = "id";
             public const string DESCRIPTION = "desc";
             public const string DISPLAY_NAME = "dn";
             public const string COLLECTION = "col:map";
+            public const string UUID = "uuid";
         }
 
         public static class ParameterStrings
diff --git a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlSettings.cs b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlSettings.cs
index 37a7df8..2097a6c 100644
--- a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlSettings.cs
+++ b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlSettings.cs
@@ -8,6 +8,8 @@
     {
         public oneM2MConfiguration oneM2MConfig { get; set; } = new oneM2MConfiguration();
 
+        public string CallbackEndpointUrl { get; set; }
+
         [Serializable]
         public class oneM2MConfiguration
         {
diff --git a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlSettings.xml b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlSettings.xml
index e18a00c..d1a4aee 100644
--- a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlSettings.xml
+++ b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlSettings.xml
@@ -1,17 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
 <SmartControlSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-	<OperationMode>None</OperationMode>
+  <CallbackEndpointUrl>http://127.0.0.1:5455</CallbackEndpointUrl>
+  <!-- http://192.168.46.165:8544 -->
+  <OperationMode>None</OperationMode>
   <ClientConfig/>
-	<ServerConfig>
+  <ServerConfig>
     <ServerId>SmartControlServer</ServerId>
-		<Endpoint>http://127.0.0.1:5455</Endpoint>
-	</ServerConfig>
+    <Endpoint>http://127.0.0.1:5455</Endpoint>
+  </ServerConfig>
   <PathConfig/>
-	<oneM2MConfig>
+  <oneM2MConfig>
     <ProtocolBinding>Http</ProtocolBinding>
     <ClientId>admin:admin</ClientId>
     <Endpoint>http://127.0.0.1:8282</Endpoint>
     <CSEName>in-name</CSEName>
-	</oneM2MConfig>
+  </oneM2MConfig>
   <Miscellaneous/>
 </SmartControlSettings>
diff --git a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlUtils.cs b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlUtils.cs
index 08277ea..c73abf7 100644
--- a/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlUtils.cs
+++ b/sdks/csnet/BaSys40.RI.AAS.SmartControl/SmartControlUtils.cs
@@ -1,128 +1,181 @@
 using BaSys40.Models.Core;
 using BaSys40.Models.Core.AssetAdministrationShell.Generics;
 using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
-using BaSys40.Models.Core.Identification;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Net;
 using System.Reflection;
+using System.Web;
 
 namespace BaSys40.RI.AAS.SmartControl
 {
     public static class SmartControlUtils
     {
-
-        public static PropertyDescription GetPropertyDescription(PropertyInfo property)
+        public static Operation GetOperationDescription(MethodInfo method)
         {
-            PropertyDescription propertyDescription = new PropertyDescription();
-            propertyDescription.Identification = new Identifier(property.Name, Identificator.Internal);
-            propertyDescription.DisplayName = property.Name;
-            propertyDescription.Writable = property.CanWrite;
-            propertyDescription.Readable = property.CanRead;
-            propertyDescription.DataType = new DataType(GetDataObjectType(property.PropertyType), IsEnumerableType(property.PropertyType), IsCollectionType(property.PropertyType));
-
-            return propertyDescription;
-        }
-        public static OperationDescription GetOperationDescription(MethodInfo method)
-        {
-            OperationDescription operation = new OperationDescription();
-            operation.Identification = new Identifier(method.Name, Identificator.Internal);
-            operation.DisplayName = method.Name;
+            Operation operation = new Operation();
+            //operation.Identification = new Identifier(method.Name, Identificator.Internal);
+            operation.IdShort = method.Name;
             var parameters = method.GetParameters();
-            operation.InputParameters = new List<IParameter>(parameters.Length);
+            operation.In = new List<IOperationVariable>(parameters.Length);
             for (int i = 0; i < parameters.Length; i++)
             {
-                operation.InputParameters.Add(
-                    new Parameter()
+                operation.In.Add(
+                    new OperationVariable()
                     {
-                        DataType = new DataType(GetDataObjectType(parameters[i].ParameterType), IsEnumerableType(parameters[i].ParameterType), IsCollectionType(parameters[i].ParameterType)),
-                        ParameterName = parameters[i].Name
+                        DataType = DataType.GetDataTypeFromSystemTypes(parameters[i].ParameterType),
+                        IdShort = parameters[i].Name
                     }
                 );
             }
 
-            operation.OutputParameters = new List<IParameter>()
+            operation.Out = new List<IOperationVariable>()
             {
-                new Parameter()
+                new OperationVariable()
                 {
                     Index = 0,
-                    DataType = new DataType(GetDataObjectType(method.ReturnType), IsEnumerableType(method.ReturnType), IsCollectionType(method.ReturnType))
+                    DataType = DataType.GetDataTypeFromSystemTypes(method.ReturnType)
                 }
             };
 
             return operation;
         }
-        static bool IsEnumerableType(Type type)
+      
+        public static List<IArgument> ConvertStringArguments(string argumentString, List<IOperationVariable> referenceArguments)
         {
-            return (type.GetInterface(nameof(IList)) != null);
-        }
-
-        static bool IsCollectionType(Type type)
-        {
-            return (type.GetInterface(nameof(IDictionary)) != null);
-        }
-
-        static bool IsSimple(Type type)
-        {
-            var typeInfo = type.GetTypeInfo();
-            if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))
-                return IsSimple(typeInfo.GetGenericArguments()[0]);
-
-            return typeInfo.IsPrimitive
-              || typeInfo.IsEnum
-              || type.Equals(typeof(string))
-              || type.Equals(typeof(decimal));
-        }
-
-        private static DataObjectType GetDataObjectType(Type type)
-        {
-            switch (type.FullName)
+            string urlDecoded = Uri.UnescapeDataString(argumentString);
+            object[] args;
+            try
             {
-                case "System.Void": return DataObjectType.Void;
-                case "System.String": return DataObjectType.String;
-                case "System.SByte": return DataObjectType.Int8;
-                case "System.Int16": return DataObjectType.Int16;
-                case "System.Int32": return DataObjectType.Int32;
-                case "System.Int64": return DataObjectType.Int64;
-                case "System.Byte": return DataObjectType.UInt8;
-                case "System.UInt16": return DataObjectType.UInt16;
-                case "System.UInt32": return DataObjectType.UInt32;
-                case "System.UInt64": return DataObjectType.UInt64;
-                case "System.Boolean": return DataObjectType.Bool;
-                case "System.Single": return DataObjectType.Float;
-                case "System.Double": return DataObjectType.Double;
-                default:
-                    if (!IsSimple(type))
-                        return DataObjectType.Object;
+                JArray ja = JArray.Parse(urlDecoded);
+                args = ja.ToObject<object[]>();
+            }
+            catch
+            {
+                JToken val = JValue.Parse(urlDecoded);
+                object oVal = val.ToObject<object>();
+                args = new object[] {oVal };
+            }
+
+            if (args.Length > 0)
+            {
+                List<IArgument> arguments = new List<IArgument>();
+                for (int i = 0; i < args.Length; i++)
+                {
+                    arguments.Add(
+                        new Argument()
+                        {
+                            Index = i,
+                            IdShort = referenceArguments[i].IdShort,
+                            ValueType = referenceArguments[i].DataType,
+                            Value = args[i]
+                        });
+                }
+                return arguments;
+            }
+            return null;
+        }
+
+        public static string ConvertStringArguments(List<IArgument> arguments)
+        {
+            string argumentString = string.Empty;
+            if (arguments?.Count == 1)
+            {
+                if (arguments[0].ValueType.DataObjectType == DataObjectType.String)
+                    argumentString += '"' + HttpUtility.JavaScriptStringEncode((string)arguments[0].Value) + '"';
+                else if (arguments[0].ValueType.DataObjectType == DataObjectType.Float || arguments[0].ValueType.DataObjectType == DataObjectType.Double)
+                    argumentString += ((float)arguments[0].Value).ToString(System.Globalization.CultureInfo.GetCultureInfo("en-US").NumberFormat);
+                else
+                    argumentString += arguments[0].Value.ToString();
+            }
+            else if (arguments?.Count > 1)
+            {
+                argumentString += SmartControl.ParameterStrings.PARAM_BRACKET_LEFT;
+                for (int i = 0; i < arguments.Count; i++)
+                {
+                    if (arguments[i].ValueType.DataObjectType == DataObjectType.String)
+                        argumentString += '"' + HttpUtility.JavaScriptStringEncode((string)arguments[i].Value) + '"';
+                    else if (arguments[i].ValueType.DataObjectType == DataObjectType.Float || arguments[i].ValueType.DataObjectType == DataObjectType.Double)
+                        argumentString += ((float)arguments[i].Value).ToString(System.Globalization.CultureInfo.GetCultureInfo("en-US").NumberFormat);
                     else
-                        return DataObjectType.None;
+                        argumentString += arguments[i].Value.ToString();
+
+                    if (i != arguments.Count - 1)
+                        argumentString += SmartControl.ELEMENT_SEPERATOR;
+                }
+                argumentString += SmartControl.ParameterStrings.PARAM_BRACKET_RIGHT;
+            }
+            else
+                argumentString = SmartControl.ParameterStrings.PARAM_BRACKET_LEFT + SmartControl.ParameterStrings.PARAM_BRACKET_RIGHT;
+
+            string urlEncoded = Uri.EscapeDataString(argumentString);
+            return urlEncoded;
+        }
+
+        public static string ConvertPropertyValue(IValue value)
+        {
+            string content = string.Empty;
+            if (value?.ValueType?.DataObjectType == DataObjectType.String)
+                content = '"' + HttpUtility.JavaScriptStringEncode((string)value.Value) + '"';
+            else if (value?.ValueType?.DataObjectType == DataObjectType.AnyType)
+                content = '"' + HttpUtility.JavaScriptStringEncode(JsonConvert.SerializeObject(value.Value)) + '"';
+            else if (value?.ValueType?.DataObjectType == DataObjectType.Float || value?.ValueType?.DataObjectType == DataObjectType.Double)
+                content = ((float)value.Value).ToString(System.Globalization.CultureInfo.GetCultureInfo("en-US").NumberFormat);
+            else if (value?.ValueType?.DataObjectType == DataObjectType.Bool)
+                content = value?.Value?.ToString().ToLower();
+            else
+                content = value?.Value?.ToString();
+
+            if(!string.IsNullOrEmpty(content))
+                return Uri.EscapeDataString(content);
+            else
+                return string.Empty;
+        }
+
+        public static IValue ConvertPropertyValue(string propertyValue, DataType dataType)
+        {
+            string urlDecoded = Uri.UnescapeDataString(propertyValue);
+
+            var value = urlDecoded.ToObject(dataType);
+
+            var dataElementValue = new DataElementValue(value, dataType);
+            return dataElementValue;
+        }
+
+        public static object ToObject(this string value, DataType dataType)
+        {
+            try
+            {
+                var jVal = JValue.Parse(value);
+                var convertedVal = jVal.ToObject(DataType.GetSystemTypeFromDataType(dataType));
+                return convertedVal;
+            }
+            catch (Exception e)
+            {
+                throw new InvalidCastException("Cannot convert to " + dataType.DataObjectType + " - Exception: " + e.Message);
             }
         }
 
-        public static List<IArgument> ConvertStringArguments(string[] args)
+        public static string ConvertDataTypeNames(DataType dataType)
         {
-            List<IArgument> inputArguments = new List<IArgument>(args.Length);
-            for (int i = 0; i < args.Length; i++)
+            string dataTypeName = dataType.DataObjectType.Name.ToLower();
+            switch (dataTypeName)
             {
-                inputArguments.Add(
-                    new Argument()
-                    {
-                        Index = i,
-                        DataType = new DataType(DataObjectType.String, false, false),
-                        Value = new ElementValue<string>(args[i])
-                    });
+                case "integer":
+                case "int": return "int";
+                case "bool":
+                case "boolean": return "bool";
+                case "none": return "void";
+                case "decimal":
+                case "double":
+                case "float": return "float";
+                default:
+                    return ("string");
             }
-            return inputArguments;
-        }
-
-        public static string[] ConvertStringArguments(List<IArgument> arguments)
-        {
-            string[] args = new string[arguments.Count];
-            for (int i = 0; i < args.Length; i++)
-            {
-                args[i] = arguments[i].Value.Value.ToString();
-            }
-            return args;
         }
     }
 }
+
diff --git a/sdks/csnet/BaSys40.Registry.Client/BaSys40.Registry.Client.csproj b/sdks/csnet/BaSys40.Registry.Client/BaSys40.Registry.Client.csproj
index fe70ea1..ebf86a2 100644
--- a/sdks/csnet/BaSys40.Registry.Client/BaSys40.Registry.Client.csproj
+++ b/sdks/csnet/BaSys40.Registry.Client/BaSys40.Registry.Client.csproj
@@ -1,11 +1,18 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
+    <Configurations>Debug;Release</Configurations>
+    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugType>full</DebugType>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="NLog" Version="4.5.6" />
+    <PackageReference Include="NLog" Version="4.5.11" />
   </ItemGroup>
 
   <ItemGroup>
@@ -18,5 +25,9 @@
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
   </ItemGroup>
+  
+  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+    <Exec Command="copy &quot;$(ProjectDir)bin\Debug\BaSys40.Registry.Client.1.0.0.nupkg&quot; &quot;C:\Development\BaSys40\SDK\packages&quot; /Y" />
+  </Target>
 
 </Project>
diff --git a/sdks/csnet/BaSys40.Registry.Client/RegistryClient.cs b/sdks/csnet/BaSys40.Registry.Client/RegistryClient.cs
index e4cd4f0..5c64bf4 100644
--- a/sdks/csnet/BaSys40.Registry.Client/RegistryClient.cs
+++ b/sdks/csnet/BaSys40.Registry.Client/RegistryClient.cs
@@ -1,53 +1,60 @@
-using BaSys40.API.Platform;
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using BaSys40.Utils.Client;
+
+using BaSys40.API.Platform;
+using BaSys40.Models.Core.AssetAdministrationShell;
+using BaSys40.Models.Extensions;
+using BaSys40.Utils.Client.Http;
 using BaSys40.Utils.ResultHandling;
-using Newtonsoft.Json;
+using Microsoft.Extensions.DependencyInjection;
 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Net;
 using System.Net.Http;
 using System.Reflection;
-using static BaSys40.Registry.Client.RegistryClientSettings;
 
 namespace BaSys40.Registry.Client
 {
     public class RegistryClient : SimpleHttpClient, IAssetAdministrationShellRegistry
     {
         public static RegistryClientSettings Settings { get; private set; }
-        public static readonly string SettingsPath;
+        public static string SettingsPath { get; private set; }
 
         private static RegistryClient registryClient;
 
-        private RegistryConfiguration registryConfig;
-
-        private const string RegistryPath = "registry";
-        private const string SubModelPath = "subModels";
+        private const string RegistryPath = "api/v1/registry";
+        private const string SubmodelPath = "submodels";
         private const string PathSeperator = "/";
 
         private const int Timeout = 5000;
 
+        private IServiceCollection services;
+        private IServiceProvider serviceProvider;
+
         static RegistryClient()
         {
             SettingsPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), RegistryClientSettings.FileName);
             Settings = RegistryClientSettings.LoadSettings(SettingsPath);
 
-            if (Settings.ProxyConfig.UseProxy.HasValue && Settings.ProxyConfig.UseProxy.Value && !string.IsNullOrEmpty(Settings.ProxyConfig.ProxyAddress))
+            LoadSettings(Settings);
+        }
+
+        public static void LoadSettings(RegistryClientSettings settings)
+        {
+            if (settings.ProxyConfig.UseProxy.HasValue && settings.ProxyConfig.UseProxy.Value && !string.IsNullOrEmpty(settings.ProxyConfig.ProxyAddress))
             {
                 HttpClientHandler.UseProxy = true;
-                if (!string.IsNullOrEmpty(Settings.ProxyConfig.UserName) && !string.IsNullOrEmpty(Settings.ProxyConfig.Password))
+                if (!string.IsNullOrEmpty(settings.ProxyConfig.UserName) && !string.IsNullOrEmpty(settings.ProxyConfig.Password))
                 {
                     NetworkCredential credential;
-                    if (!string.IsNullOrEmpty(Settings.ProxyConfig.Domain))
-                        credential = new NetworkCredential(Settings.ProxyConfig.UserName, Settings.ProxyConfig.Password, Settings.ProxyConfig.Domain);
+                    if (!string.IsNullOrEmpty(settings.ProxyConfig.Domain))
+                        credential = new NetworkCredential(settings.ProxyConfig.UserName, settings.ProxyConfig.Password, settings.ProxyConfig.Domain);
                     else
-                        credential = new NetworkCredential(Settings.ProxyConfig.UserName, Settings.ProxyConfig.Password);
+                        credential = new NetworkCredential(settings.ProxyConfig.UserName, settings.ProxyConfig.Password);
 
-                    HttpClientHandler.Proxy = new WebProxy(Settings.ProxyConfig.ProxyAddress, false, null, credential);
+                    HttpClientHandler.Proxy = new WebProxy(settings.ProxyConfig.ProxyAddress, false, null, credential);
                 }
                 else
-                    HttpClientHandler.Proxy = new WebProxy(Settings.ProxyConfig.ProxyAddress);
+                    HttpClientHandler.Proxy = new WebProxy(settings.ProxyConfig.ProxyAddress);
             }
             else
                 HttpClientHandler.UseProxy = false;
@@ -63,86 +70,100 @@
             }
         }
 
-        public RegistryClient(RegistryConfiguration registryConfig = null)
+        public RegistryClient(RegistryClientSettings registryClientSettings = null)
         {
-            if (registryConfig != null)
-                this.registryConfig = registryConfig;
-            else
-                this.registryConfig = Settings.RegistryConfig;
+            if (registryClientSettings != null)
+            {
+                Settings = registryClientSettings;
+                LoadSettings(Settings);
+            }
+
+            JsonSerializerSettings = new JsonStandardSettings();
         }
 
         public Uri GetUri(params string[] pathElements)
         {
-            string path = registryConfig.RegistryUrl + registryConfig.BasePath;
+            string path = string.Empty;
+            if (!Settings.RegistryConfig.RegistryUrl.EndsWith("/") && !RegistryPath.StartsWith("/"))
+                path = Settings.RegistryConfig.RegistryUrl + PathSeperator + RegistryPath;
+            else
+                path = Settings.RegistryConfig.RegistryUrl + RegistryPath;
+
             if (pathElements?.Length > 0)
                 foreach (var pathElement in pathElements)
                 {
-                    path += pathElement + PathSeperator;
+                    if (!pathElement.EndsWith("/") && !pathElement.StartsWith("/"))
+                        path = path + PathSeperator + pathElement;
+                    else
+                        path = path + pathElement;
+
+                    //if (!path.EndsWith("/"))
+                    //    path = path + PathSeperator;
                 }
             return new Uri(path);
         }
 
-        public IResult<IAssetAdministrationShell> CreateAssetAdministrationShell(IAssetAdministrationShell aas)
+        public IResult<AssetAdministrationShellDescriptor> CreateAssetAdministrationShell(AssetAdministrationShellDescriptor aas)
         {
-            var request = base.CreateRequest(GetUri(), HttpMethod.Post, aas);
+            var request = base.CreateJsonContentRequest(GetUri(), HttpMethod.Post, aas);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse<IAssetAdministrationShell>(response.Entity);
+            return base.EvaluateResponse<AssetAdministrationShellDescriptor>(response, response.Entity);
         }
 
-        public IResult<IAssetAdministrationShell> RetrieveAssetAdministrationShell(string aasId)
+        public IResult<AssetAdministrationShellDescriptor> RetrieveAssetAdministrationShell(string aasId)
         {
             var request = base.CreateRequest(GetUri(aasId), HttpMethod.Get);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse<IAssetAdministrationShell>(response.Entity);
+            return base.EvaluateResponse<AssetAdministrationShellDescriptor>(response, response.Entity);
         }
 
-        public IResult<List<IAssetAdministrationShell>> RetrieveAssetAdministrationShells()
+        public IResult<List<AssetAdministrationShellDescriptor>> RetrieveAssetAdministrationShells()
         {
             var request = base.CreateRequest(GetUri(), HttpMethod.Get);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse<List<IAssetAdministrationShell>>(response.Entity);
+            return base.EvaluateResponse<List<AssetAdministrationShellDescriptor>>(response, response.Entity);
         }
 
         public IResult UpdateAssetAdministrationShell(string aasId, Dictionary<string, string> metaData)
         {
             var request = base.CreateRequest(GetUri(aasId), HttpMethod.Put);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse(response.Entity);
+            return base.EvaluateResponse(response, response.Entity);
         }
 
         public IResult DeleteAssetAdministrationShell(string aasId)
         {
             var request = base.CreateRequest(GetUri(aasId), HttpMethod.Delete);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse<List<IAssetAdministrationShell>>(response.Entity);
+            return base.EvaluateResponse(response, response.Entity);
         }
 
-        public IResult<ISubModel> CreateSubModel(string aasId, ISubModel submodel)
+        public IResult<SubmodelDescriptor> CreateSubmodel(string aasId, SubmodelDescriptor submodel)
         {
-            var request = base.CreateRequest(GetUri(aasId, SubModelPath), HttpMethod.Post, submodel);
+            var request = base.CreateJsonContentRequest(GetUri(aasId, SubmodelPath), HttpMethod.Post, submodel);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse<ISubModel>(response.Entity);
+            return base.EvaluateResponse<SubmodelDescriptor>(response, response.Entity);
         }
 
-        public IResult<IElementContainer<ISubModel>> RetrieveSubModels(string aasId)
+        public IResult<List<SubmodelDescriptor>> RetrieveSubmodels(string aasId)
         {
-            var request = base.CreateRequest(GetUri(aasId, SubModelPath), HttpMethod.Get);
+            var request = base.CreateRequest(GetUri(aasId, SubmodelPath), HttpMethod.Get);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse<IElementContainer<ISubModel>>(response.Entity);
+            return base.EvaluateResponse<List<SubmodelDescriptor>>(response, response.Entity);
         }
 
-        public IResult<ISubModel> RetrieveSubModel(string aasId, string subModelId)
+        public IResult<SubmodelDescriptor> RetrieveSubmodel(string aasId, string submodelId)
         {
-            var request = base.CreateRequest(GetUri(aasId, SubModelPath, subModelId), HttpMethod.Get);
+            var request = base.CreateRequest(GetUri(aasId, SubmodelPath, submodelId), HttpMethod.Get);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse<ISubModel>(response.Entity);
+            return base.EvaluateResponse<SubmodelDescriptor>(response, response.Entity);
         }
 
-        public IResult DeleteSubModel(string aasId, string subModelId)
+        public IResult DeleteSubmodel(string aasId, string submodelId)
         {
-            var request = base.CreateRequest(GetUri(aasId, SubModelPath, subModelId), HttpMethod.Delete);
+            var request = base.CreateRequest(GetUri(aasId, SubmodelPath, submodelId), HttpMethod.Delete);
             var response = base.SendRequest(request, Timeout);
-            return base.EvaluateResponse(response.Entity);
+            return base.EvaluateResponse(response, response.Entity);
         }
     }
 }
diff --git a/sdks/csnet/BaSys40.Registry.Client/RegistryClientSettings.cs b/sdks/csnet/BaSys40.Registry.Client/RegistryClientSettings.cs
index 4f3181b..aa172f9 100644
--- a/sdks/csnet/BaSys40.Registry.Client/RegistryClientSettings.cs
+++ b/sdks/csnet/BaSys40.Registry.Client/RegistryClientSettings.cs
@@ -17,11 +17,7 @@
         public class RegistryConfiguration 
         {
             [XmlElement]
-            public string RegistryUrl { get; set; }
-            [XmlElement]
-            public string TenantId { get; set; }
-            [XmlElement]
-            public string BasePath { get; set; }      
+            public string RegistryUrl { get; set; } 
         }
         [Serializable]
         public class CatalogConfiguration
diff --git a/sdks/csnet/BaSys40.Registry.Client/RegistryClientSettings.xml b/sdks/csnet/BaSys40.Registry.Client/RegistryClientSettings.xml
index d121e01..2596f76 100644
--- a/sdks/csnet/BaSys40.Registry.Client/RegistryClientSettings.xml
+++ b/sdks/csnet/BaSys40.Registry.Client/RegistryClientSettings.xml
@@ -1,11 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RegistryClientSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 	<RegistryConfig>
-    <RegistryUrl>http://127.0.0.1:5080/</RegistryUrl>
-    <BasePath>registry/</BasePath>
+    <RegistryUrl>http://basysregistry.azurewebsites.net/</RegistryUrl>
   </RegistryConfig>
   <ProxyConfig>
-    <UseProxy>true</UseProxy>
+    <UseProxy>false</UseProxy>
     <ProxyAddress>http://localhost:3128</ProxyAddress>
   </ProxyConfig>
 </RegistryClientSettings>
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/BaSys40.Technologies.oneM2M.csproj b/sdks/csnet/BaSys40.Technologies.oneM2M/BaSys40.Technologies.oneM2M.csproj
index 9f0e8d6..19e34be 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/BaSys40.Technologies.oneM2M.csproj
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/BaSys40.Technologies.oneM2M.csproj
@@ -1,18 +1,28 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
+    <Configurations>Debug;Release</Configurations>
+    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
   </PropertyGroup>
   
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugType>Full</DebugType>
   </PropertyGroup>
+  
+  <ItemGroup>
+    <PackageReference Include="M2MqttDotnetCore" Version="1.0.8" />
+    <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
+    <PackageReference Include="NLog" Version="4.5.11" />
+  </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="M2MqttDotnetCore" Version="1.0.7" />
-    <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
-    <PackageReference Include="NLog" Version="4.5.6" />
+    <ProjectReference Include="..\BaSys40.Utils\BaSys40.Utils.csproj" />
   </ItemGroup>
 
+  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+    <Exec Command="copy &quot;$(ProjectDir)bin\Debug\BaSys40.Technologies.oneM2M.1.0.0.nupkg&quot; &quot;C:\Development\BaSys40\SDK\packages&quot; /Y" />
+  </Target>
+
 
 </Project>
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Bindings/Http/HttpBinding.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Bindings/Http/HttpBinding.cs
index c6bc1ba..4a0846f 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Bindings/Http/HttpBinding.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Bindings/Http/HttpBinding.cs
@@ -1,4 +1,4 @@
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 using System;
 using System.Collections.Generic;
 using System.Net;
@@ -21,7 +21,7 @@
             httpClient = new HttpClient(
                 new HttpClientHandler
                 {
-                    MaxConnectionsPerServer = 100,
+                    MaxConnectionsPerServer = 100,                    
                     UseProxy = false
                 });
         }
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Bindings/Mqtt/MqttBinding.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Bindings/Mqtt/MqttBinding.cs
index 02d5adb..3edbc6b 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Bindings/Mqtt/MqttBinding.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Bindings/Mqtt/MqttBinding.cs
@@ -1,6 +1,6 @@
 using System;
 using System.Text;
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 using uPLibrary.Networking.M2Mqtt;
 using uPLibrary.Networking.M2Mqtt.Messages;
 using System.Threading;
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Client/IClient.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Client/IClient.cs
index b1ffeae..4dbbeb2 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Client/IClient.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Client/IClient.cs
@@ -1,4 +1,4 @@
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 
 namespace oneM2MClient.Client
 {
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Request.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Request.cs
index 481acd8..9e52446 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Request.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Client/Request.cs
@@ -9,7 +9,7 @@
         public rqp RequestPrimitive { get; set; } = new rqp();
         public string ContentMIME { get; set; } = "application/json";
         public string AcceptMIME { get; set; } =  "application/json";
-        public int MillisecondsTimeout { get; set; } = 1000;
+        public int MillisecondsTimeout { get; set; } = 30000;
         public string EndpointAddress { get; set; } = string.Empty;
         public Uri RequestPath { get; set; }
         public string CSEName { get; set; } = string.Empty;
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/LICENSE-3RD-PARTY.txt b/sdks/csnet/BaSys40.Technologies.oneM2M/LICENSE-3RD-PARTY.txt
deleted file mode 100644
index c82e9d2..0000000
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/LICENSE-3RD-PARTY.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-1. Used 3rd party software components
-
-- IOTDM Client (https://github.com/opendaylight/iotdm, structure has been adapted for oneM2M C# client), Eclipse Public License Version 1.0, Copyright (c) 2015 Cisco Systems, Inc. and others.
-
-2. License Texts
-
-2.1 Eclipse Public License Version 1.0
-
-Eclipse Public License, Version 1.0 (EPL-1.0)
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
-    a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
-    b) in the case of each subsequent Contributor:
-    i) changes to the Program, and
-    ii) additions to the Program;
-    where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
-
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this Agreement.
-
-"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
-    a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
-    b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
-    c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
-    d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
-
-3. REQUIREMENTS
-
-A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
-
-    a) it complies with the terms and conditions of this Agreement; and
-    b) its license agreement:
-    i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
-    ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
-    iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
-    iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
-
-When the Program is made available in source code form:
-
-    a) it must be made available under this Agreement; and
-    b) a copy of this Agreement must be included with each copy of the Program.
-
-Contributors may not remove or alter any copyright notices contained within the Program.
-
-Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/ApplicationEntity.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/ApplicationEntity.cs
index 55ff7af..4559d97 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/ApplicationEntity.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/ApplicationEntity.cs
@@ -1,7 +1,7 @@
 using oneM2MClient.Client;
 using oneM2MClient.Protocols;
 using oneM2MClient.Utils;
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/CSEBase.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/CSEBase.cs
index 956e1e7..84baa7c 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/CSEBase.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/CSEBase.cs
@@ -1,6 +1,6 @@
 using oneM2MClient.Client;
 using oneM2MClient.Utils;
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 using System;
 using System.Collections.Generic;
 using static oneM2MClient.oneM2M;
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/Container.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/Container.cs
index 1029594..279af56 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/Container.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/Container.cs
@@ -1,7 +1,7 @@
 using oneM2MClient.Client;
 using oneM2MClient.Protocols;
 using oneM2MClient.Utils;
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/ContentInstance.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/ContentInstance.cs
index 4c92f3c..7d12537 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/ContentInstance.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/ContentInstance.cs
@@ -1,7 +1,7 @@
 using oneM2MClient.Client;
 using oneM2MClient.Protocols;
 using oneM2MClient.Utils;
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/Subscription.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/Subscription.cs
index 64154d0..1223249 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/Subscription.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Resources/Subscription.cs
@@ -1,7 +1,7 @@
 using oneM2MClient.Client;
 using oneM2MClient.Protocols;
 using oneM2MClient.Utils;
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/CrudExtensions.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/CrudExtensions.cs
index 479f98c..591a0b8 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/CrudExtensions.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/CrudExtensions.cs
@@ -1,6 +1,6 @@
 using oneM2MClient.Client;
 using oneM2MClient.Resources;
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
 
 namespace oneM2MClient.Utils
 {
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/Helper.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/Helper.cs
index 14a7422..69fa764 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/Helper.cs
+++ b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/Helper.cs
@@ -1,7 +1,8 @@
 using oneM2MClient.Client;
 using oneM2MClient.Resources;
 using oneM2MClient.Protocols;
-using oneM2MClient.Utils.ResultHandling;
+using BaSys40.Utils.ResultHandling;
+using BaSys40.Utils.ModelHandling;
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -158,7 +159,8 @@
             if (additionalPath != null && additionalPath.Length > 0)
                 request.AddPath(additionalPath);
 
-            request.AddPath("la");
+            if(!request.RequestPath.Segments.Contains("la"))
+                request.AddPath("la");
 
             var contResp = CSEBase.Retrieve(client, request);
             if (contResp.Success && contResp.Entity != null && contResp.Entity.PrimitiveContent != null)
@@ -516,8 +518,8 @@
                 return new Result<T>(false, default(T), new Message(MessageType.Error, e.Message));
             else
             {
-                result.Messages.Add(new Message(MessageType.Exception, e.Message, e.HResult.ToString()));
-                result.Success = false;
+                var newResult = new Result<T>(e);
+                newResult.Messages.AddRange(result.Messages);
                 return result;
             }
         }
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/IMessage.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/IMessage.cs
deleted file mode 100644
index 6a16697..0000000
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/IMessage.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace oneM2MClient.Utils.ResultHandling
-{
-    public interface IMessage
-    {
-        MessageType MessageType { get; set; }
-        string Code { get; set; }
-        string Text { get; set; }
-        string ToString();
-    }
-}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/IResult.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/IResult.cs
deleted file mode 100644
index 40df822..0000000
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/IResult.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-
-namespace oneM2MClient.Utils.ResultHandling
-{
-    public interface IResult
-    {
-        Type EntityType { get; }
-        object EntityObject { get; }
-        bool Success { get; }
-        List<IMessage> Messages { get; }
-        T GetEntity<T>();
-    }
-
-    public interface IResult<TEntity> : IResult
-    {
-        [JsonConverter(typeof(CustomTypeSerializer))]
-        TEntity Entity { get; }
-    }
-}
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/Message.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/Message.cs
deleted file mode 100644
index e79dd14..0000000
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/Message.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Threading;
-
-namespace oneM2MClient.Utils.ResultHandling
-{
-    public class Message : IMessage
-    {
-        public MessageType MessageType { get; set; }
-        public string Text { get; set; }
-        public string Code { get; set; }
-
-        public Message(MessageType messageType, string text) : this(messageType, text, null)
-        { }
-        public Message(MessageType messageType, string text, string code)
-        {
-            MessageType = messageType;
-            Text = text;
-            Code = code;
-        }
-
-
-        public override string ToString()
-        {
-            return string.Format(Thread.CurrentThread.CurrentCulture,"{0} | {1} - {2}", MessageType, Code, Text);
-        }
-    }
-}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/MessageType.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/MessageType.cs
deleted file mode 100644
index e3c8a07..0000000
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/MessageType.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace oneM2MClient.Utils.ResultHandling
-{
-    public enum MessageType : int
-    {
-        Unspecified = 0,
-        Debug = 1,
-        Information = 2,
-        Warning = 3,
-        Error = 4,
-        Fatal = 5,
-        Exception = 6
-    }
-}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/Result.cs b/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/Result.cs
deleted file mode 100644
index 1a523cc..0000000
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/ResultHandling/Result.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.Serialization;
-
-namespace oneM2MClient.Utils.ResultHandling
-{
-    public class Result : IResult
-    {
-        [DataMember(Order = 0)]
-        public bool Success { get; internal set; }
-        [DataMember(Order = 1)]
-        public Type EntityType { get; private set; }
-        [DataMember(Order = 2)]
-        public object EntityObject { get; private set; }
-        
-        private List<IMessage> messages;
-        [DataMember(Order = 3)]
-        public List<IMessage> Messages
-        {
-            get
-            {
-                if (this.messages == null)
-                    this.messages = new List<IMessage>();
-                return this.messages;
-            }
-        }
-
-        public Result(bool success) : this(success, null, null, null)
-        { }
-
-        public Result(bool success, List<IMessage> messages) : this(success, null, null, messages)
-        { }
-
-        public Result(bool success, object entity, Type entityType) : this(success, entity, entityType, null)
-        { }
-
-        public Result(Exception e) : this(false, e, e.GetType(), new List<IMessage>() { new Message(MessageType.Error, e.Message, e.HResult.ToString()) })
-        { }
-
-        public Result(bool success, object entity, Type entityType, List<IMessage> messages)
-        {
-            Success = success;
-
-            if (messages != null)
-                foreach (Message msg in messages)
-                    Messages.Add(msg);
-
-            if (entity != null && entityType != null)
-            {
-                EntityObject = entity;
-                EntityType = entityType;
-            }
-
-        }
-
-        public T GetEntity<T>()
-        {
-            if (EntityObject != null && 
-                (EntityObject is T ||
-                EntityObject.GetType().IsAssignableFrom(typeof(T)) ||
-                EntityObject.GetType().GetInterfaces().Contains(typeof(T))))
-                return (T)EntityObject;
-            return default(T);
-        }
-    }
-
-    public class Result<TEntity> : Result, IResult<TEntity>
-    {
-        [IgnoreDataMember]
-        public TEntity Entity { get; private set; }
-
-        public Result(bool success, TEntity entity) : this(success, entity, new List<IMessage>())
-        { }
-        public Result(bool success, IMessage message) : this(success, default(TEntity), new List<IMessage>() { message })
-        { }
-        public Result(bool success, List<IMessage> messages) : this(success, default(TEntity), messages)
-        { }
-        public Result(bool success, TEntity entity, IMessage message) : this(success, entity, new List<IMessage>() { message })
-        { }
-        public Result(Exception e) : base(e)
-        { }
-        public Result(bool success, TEntity entity, List<IMessage> messages) : base(success, entity, typeof(TEntity), messages)
-        {
-            Entity = entity;
-        }
-    }
-}
diff --git a/sdks/csnet/BaSys40.Utils/BaSys40.Utils.csproj b/sdks/csnet/BaSys40.Utils/BaSys40.Utils.csproj
index a5d0d16..36e2926 100644
--- a/sdks/csnet/BaSys40.Utils/BaSys40.Utils.csproj
+++ b/sdks/csnet/BaSys40.Utils/BaSys40.Utils.csproj
@@ -1,29 +1,27 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
+    <Configurations>Debug;Release</Configurations>
+    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
   </PropertyGroup>
   
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugType>full</DebugType>
-</PropertyGroup>
-  
-  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
-    <DebugSymbols>true</DebugSymbols>
   </PropertyGroup>
-
+  
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.1.0" />
-    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.0" />
-    <PackageReference Include="Microsoft.Extensions.Options" Version="2.1.0" />
-    <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
-    <PackageReference Include="NLog" Version="4.5.6" />
+    <PackageReference Include="M2MqttDotnetCore" Version="1.0.8" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.2.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Rewrite" Version="2.2.0" />
+    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
+    <PackageReference Include="Microsoft.Extensions.Options" Version="2.2.0" />
+    <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
+    <PackageReference Include="NLog" Version="4.5.11" />
   </ItemGroup>
 
-  <ItemGroup>
-    <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
-      <HintPath>..\..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.extensions.dependencyinjection.abstractions\2.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
-    </Reference>
-  </ItemGroup>
+  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+    <Exec Command="copy &quot;$(ProjectDir)bin\Debug\BaSys40.Utils.1.0.0.nupkg&quot; &quot;C:\Development\BaSys40\SDK\packages&quot; /Y" />
+  </Target>
 
 </Project>
diff --git a/sdks/csnet/BaSys40.Utils/Client/LegacyHttpClient.cs b/sdks/csnet/BaSys40.Utils/Client/Http/LegacyHttpClient.cs
similarity index 97%
rename from sdks/csnet/BaSys40.Utils/Client/LegacyHttpClient.cs
rename to sdks/csnet/BaSys40.Utils/Client/Http/LegacyHttpClient.cs
index cb9da2e..cc6b5e7 100644
--- a/sdks/csnet/BaSys40.Utils/Client/LegacyHttpClient.cs
+++ b/sdks/csnet/BaSys40.Utils/Client/Http/LegacyHttpClient.cs
@@ -3,7 +3,7 @@
 using System.Net;
 using System.Text;
 
-namespace BaSys40.Utils.Client
+namespace BaSys40.Utils.Client.Http
 {
     public class LegacyHttpClient
     {
diff --git a/sdks/csnet/BaSys40.Utils/Client/Http/SimpleHttpClient.cs b/sdks/csnet/BaSys40.Utils/Client/Http/SimpleHttpClient.cs
new file mode 100644
index 0000000..e76fc33
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/Client/Http/SimpleHttpClient.cs
@@ -0,0 +1,159 @@
+using BaSys40.Utils.ResultHandling;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BaSys40.Utils.Client.Http
+{ 
+    public abstract class SimpleHttpClient
+    {
+        public static HttpClient HttpClient { get; }
+        public static HttpClientHandler HttpClientHandler { get; }
+        public JsonSerializerSettings JsonSerializerSettings { get; protected set; }
+
+        static SimpleHttpClient()
+        {
+            HttpClientHandler = new HttpClientHandler() { MaxConnectionsPerServer = 100 };
+            HttpClient = new HttpClient(HttpClientHandler);
+        }
+
+        protected SimpleHttpClient()
+        {
+            JsonSerializerSettings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented };
+        }
+
+        protected virtual IResult<HttpResponseMessage> SendRequest(HttpRequestMessage message, int timeout)
+        {
+            try
+            {
+                var task = HttpClient.SendAsync(message);
+                if (Task.WhenAny(task, Task.Delay(timeout)).Result == task)
+                {
+                    return new Result<HttpResponseMessage>(true, task.Result);
+                }
+                else
+                {
+                    return new Result<HttpResponseMessage>(false, new List<IMessage> { new Message(MessageType.Error, "Error while sending the request: timeout") });
+                }
+            }
+            catch (Exception e)
+            {
+                return new Result<HttpResponseMessage>(e);
+            }
+        }
+
+        protected virtual HttpRequestMessage CreateRequest(Uri uri, HttpMethod method)
+        {
+            return new HttpRequestMessage(method, uri);
+        }
+
+        protected virtual HttpRequestMessage CreateRequest(Uri uri, HttpMethod method, HttpContent content)
+        {           
+            var message = CreateRequest(uri, method);
+            if (content != null)
+                message.Content = content;
+
+            return message;
+        }
+        
+        protected virtual HttpRequestMessage CreateJsonContentRequest(Uri uri, HttpMethod method, object content)
+        {
+            var message = CreateRequest(uri, method, () => 
+            {
+                var serialized = JsonConvert.SerializeObject(content, JsonSerializerSettings);
+                return new StringContent(serialized, Encoding.Default, "application/json");
+            });
+            return message;
+        }
+        
+        protected virtual HttpRequestMessage CreateRequest(Uri uri, HttpMethod method, Func<HttpContent> content)
+        {
+            var message = CreateRequest(uri, method);
+            if (content != null)
+                message.Content = content.Invoke();
+
+            return message;
+        }
+
+        protected virtual IResult EvaluateResponse(IResult result, HttpResponseMessage response)
+        {
+            var messageList = new List<IMessage>();
+            messageList.AddRange(result.Messages);
+
+            if (response != null)
+            {
+                var responseString = response.Content.ReadAsStringAsync().Result;
+                if (response.IsSuccessStatusCode)
+                {
+                    messageList.Add(new Message(MessageType.Information, response.ReasonPhrase, ((int)response.StatusCode).ToString()));
+                    return new Result(true, messageList);
+                }
+                else
+                {
+                    messageList.Add(new Message(MessageType.Error, response.ReasonPhrase + "| " + responseString, ((int)response.StatusCode).ToString()));
+                    return new Result(false, messageList);
+                }
+            }
+            messageList.Add(new Message(MessageType.Error, "Evaluation of response failed - Response from host is null", null));
+            return new Result(false, messageList);
+        }
+
+        protected virtual IResult<T> EvaluateResponse<T>(IResult result, HttpResponseMessage response)
+        {
+            var messageList = new List<IMessage>();
+            messageList.AddRange(result.Messages);
+
+            if (response != null)
+            {
+                var responseString = response.Content.ReadAsStringAsync().Result;
+                if (response.IsSuccessStatusCode)
+                {
+                    try
+                    {
+                        responseString = CheckAndExtractResultContruct(responseString);
+                        var requestResult = JsonConvert.DeserializeObject<T>(responseString, JsonSerializerSettings);
+
+                        messageList.Add(new Message(MessageType.Information, response.ReasonPhrase, ((int)response.StatusCode).ToString()));
+                        return new Result<T>(true, requestResult, messageList);
+                    }
+                    catch (Exception e)
+                    {
+                        messageList.Add(new Message(MessageType.Error, e.Message, e.HelpLink));
+                        return new Result<T>(false, messageList);
+                    }
+                }
+                else
+                {
+                    messageList.Add(new Message(MessageType.Error, response.ReasonPhrase + "| " + responseString, ((int)response.StatusCode).ToString()));
+                    return new Result<T>(false, messageList);
+                }
+            }
+            messageList.Add(new Message(MessageType.Error, "Evaluation of response failed - Response from host is null", null));
+            return new Result<T>(false, messageList);
+        }
+
+        private string CheckAndExtractResultContruct(string responseString)
+        {
+            if (responseString == null)
+                return null;
+
+            try
+            {
+                JObject jObj = JObject.Parse(responseString);
+                var jEntity = jObj.SelectToken("entity");
+                if (jEntity != null)
+                    return jEntity.ToString();
+                else
+                    return responseString;
+            }
+            catch
+            {
+                return responseString;
+            }
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/Client/IMessageClient.cs b/sdks/csnet/BaSys40.Utils/Client/IMessageClient.cs
new file mode 100644
index 0000000..777396f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/Client/IMessageClient.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using BaSys40.Utils.ResultHandling;
+
+namespace BaSys40.Utils.Client
+{
+    public interface IMessageClient
+    {
+        bool IsConnected { get; }
+
+        IResult Publish(string topic, string message, Action<IMessagePublishedEventArgs> messagePublishedHandler, byte qosLevel);
+        IResult Subscribe(string topic, Action<IMessageReceivedEventArgs> messageReceivedHandler, byte qosLevel);
+        IResult Unsubscribe(string topic);
+
+        IResult Start();
+        IResult Stop();
+    }
+    public interface IMessagePublishedEventArgs
+    {
+        bool IsPublished { get; }
+        string MessageId { get; }        
+    }
+    public interface IMessageReceivedEventArgs
+    {
+        string Message { get; }
+        string Topic { get; }
+        byte QosLevel { get; }
+    }
+
+}
diff --git a/sdks/csnet/BaSys40.Utils/Client/Mqtt/MqttConfig.cs b/sdks/csnet/BaSys40.Utils/Client/Mqtt/MqttConfig.cs
new file mode 100644
index 0000000..991c70d
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/Client/Mqtt/MqttConfig.cs
@@ -0,0 +1,83 @@
+using BaSys40.Utils.Config;
+using BaSys40.Utils.Security;
+using System.Security.Cryptography.X509Certificates;
+
+namespace BaSys40.Utils.Client.Mqtt
+{
+    public class MqttConfig : IEventHandlerConfig
+    {
+        public string ClientId { get; }
+
+        public string BrokerEndpoint { get; }
+
+        public ICredentials Credentials { get; }
+
+        public bool SecureConnection { get; set; } = false;
+
+        public int PublishTimeout { get; } = 5000;
+
+        public int ReceiveTimeout { get; } = 5000;
+
+        public ISecurity Security { get; }
+
+        public MqttConnectConfig MqttConnectConfig { get; set; }
+
+        public MqttConfig(string clientId, string brokerEndpoint)
+        {
+            ClientId = clientId;
+            BrokerEndpoint = brokerEndpoint;
+            MqttConnectConfig = new MqttConnectConfig();
+        }
+        public MqttConfig(string clientId, string brokerEndpoint, MqttCredentials credentials) : this(clientId, brokerEndpoint)
+        {
+            Credentials = credentials;
+        }
+
+        public MqttConfig(string clientId, string brokerEndpoint, MqttCredentials credentials, MqttSecurity security) : this(clientId, brokerEndpoint, credentials)
+        {
+            Security = security;
+        }
+    }
+
+    public class MqttConnectConfig
+    {
+        public bool WillRetain { get; set; } = false;
+        public byte WillQosLevel { get; set; } = 0;
+        public bool WillFlag { get; set; } = false;
+        public string WillTopic { get; set; } = null;
+        public string WillMessage { get; set; } = null;
+        public bool CleanSession { get; set; } = true;
+        public ushort KeepAlivePeriod { get; set; } = 60;
+    }
+
+    public class MqttCredentials : ICredentials
+    {
+        public string UserName { get; set; }
+        public string Password { get; set; }
+
+        internal MqttCredentials()
+        { }
+        
+        public MqttCredentials(string userName, string password)
+        {
+            UserName = userName;
+            Password = password;
+        }
+    }
+
+    public class MqttSecurity : ISecurity
+    {
+        public X509Certificate CaCert { get; }
+        public X509Certificate ClientCert { get; }
+
+        public MqttSecurity(X509Certificate caCert)
+        {
+            CaCert = caCert;
+        }
+        public MqttSecurity(X509Certificate caCert, X509Certificate clientCert)
+        {
+            CaCert = caCert;
+            ClientCert = clientCert;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/Client/Mqtt/SimpleMqttClient.cs b/sdks/csnet/BaSys40.Utils/Client/Mqtt/SimpleMqttClient.cs
new file mode 100644
index 0000000..3b2f5bc
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/Client/Mqtt/SimpleMqttClient.cs
@@ -0,0 +1,216 @@
+using System;
+using System.Text;
+using System.Threading;
+using NLog;
+using uPLibrary.Networking.M2Mqtt;
+using uPLibrary.Networking.M2Mqtt.Messages;
+using BaSys40.Utils.ResultHandling;
+using System.Security.Cryptography.X509Certificates;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace BaSys40.Utils.Client.Mqtt
+{
+    public class SimpleMqttClient : IMessageClient
+    {
+        private MqttClient mqttClient;
+        public readonly MqttConfig MqttConfig;
+
+        private Dictionary<string, Action<IMessageReceivedEventArgs>> topicMessageReceivedHandler = new Dictionary<string, Action<IMessageReceivedEventArgs>>();
+        private Action<IMessagePublishedEventArgs> msgPublishedMethod = null;
+
+        private ManualResetEvent connectionClosedResetEvent;
+        public EventHandler<EventArgs> ConnectionClosed;
+
+        private static Logger logger = LogManager.GetCurrentClassLogger();
+
+        public SimpleMqttClient(MqttConfig config)
+        {
+            MqttConfig = config;        
+        }
+
+        public bool IsConnected
+        {
+            get
+            {
+                if (mqttClient != null)
+                    return mqttClient.IsConnected;
+                else
+                    return false;
+            }
+        }
+        public IResult Publish(string topic, string message) => Publish(topic, message, null, 2);
+
+        public IResult Publish(string topic, string message, Action<IMessagePublishedEventArgs> messagePublishedHandler, byte qosLevel)
+        {
+            if (messagePublishedHandler != null && this.msgPublishedMethod == null)
+            {
+                msgPublishedMethod = messagePublishedHandler;
+                mqttClient.MqttMsgPublished += MqttClient_MqttMsgPublished;
+            }
+
+            byte[] bMessage = Encoding.UTF8.GetBytes(message);
+
+            ushort messageId = mqttClient.Publish(topic, bMessage, qosLevel, false);
+            return new Result<ushort>(true, messageId);
+        }
+
+        public IResult Subscribe(string topic, Action<IMessageReceivedEventArgs> messageReceivedHandler, byte qosLevel)
+        {
+            if (string.IsNullOrEmpty(topic))
+                return new Result(new ArgumentNullException("topic", "The topic is null or empty"));
+            if (messageReceivedHandler == null)
+                return new Result(new ArgumentNullException("messageReceivedHandler", "The message received delegate cannot be null since subscribed messages cannot be received"));
+
+            if (!topicMessageReceivedHandler.ContainsKey(topic))
+                topicMessageReceivedHandler.Add(topic, messageReceivedHandler);
+
+            ushort messageId = mqttClient.Subscribe(new string[] { topic }, new byte[] { qosLevel });
+            return new Result<ushort>(true, messageId);
+        }
+
+        public IResult Unsubscribe(string topic)
+        {
+            ushort messageId = mqttClient.Unsubscribe(new string[] { topic });
+            return new Result<ushort>(true, messageId);
+        }
+
+        private void MqttClient_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
+        {
+            string parentOrSelfTopic = GetParentOrSelfTopic(e.Topic, topicMessageReceivedHandler.Keys);
+            if (topicMessageReceivedHandler.TryGetValue(parentOrSelfTopic, out Action<IMessageReceivedEventArgs> action))
+                action.Invoke(new MqttMsgReceivedEventArgs(e));
+        }
+
+        private string GetParentOrSelfTopic(string topic, Dictionary<string, Action<IMessageReceivedEventArgs>>.KeyCollection keys)
+        {
+            foreach (var key in keys)
+            {
+                if (key == topic)
+                    return key;
+                else
+                {
+                    string[] splittedKey = key.Split('/');
+                    string[] splittedTopic = topic.Split('/');
+                    int minLength = Math.Min(splittedKey.Length, splittedTopic.Length);
+                    for (int i = 0; i < minLength; i++)
+                    {
+                        if (splittedKey[i] != splittedTopic[i])
+                        {
+                            if (splittedKey[i] == "#")
+                                return key;
+                        }
+                    }
+
+                }
+            }
+            return topic;
+        }
+
+        private void MqttClient_MqttMsgSubscribed(object sender, MqttMsgSubscribedEventArgs e)
+        {
+            logger.Debug("Subscribed for id = " + e.MessageId);
+        }
+
+        private void MqttClient_MqttMsgPublished(object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishedEventArgs e)
+        {
+            logger.Debug("Published for id = " + e.MessageId);
+            msgPublishedMethod?.Invoke(new MqttMsgPublishedEventArgs(e));
+        }
+
+        public IResult Start()
+        {
+            Uri endpoint = new Uri(MqttConfig.BrokerEndpoint);
+            MqttSslProtocols protocols = MqttConfig.SecureConnection ? MqttSslProtocols.TLSv1_2 : MqttSslProtocols.None;
+            X509Certificate caCert = null;
+            X509Certificate clientCert = null;
+            if (MqttConfig.Security != null && MqttConfig.Security is MqttSecurity security)
+            {
+                caCert = security.CaCert ?? null;
+                clientCert = security.ClientCert ?? null;
+            }
+            mqttClient = new MqttClient(endpoint.Host, endpoint.Port, MqttConfig.SecureConnection, caCert, clientCert, protocols, null, null);
+            mqttClient.ConnectionClosed += MqttClient_ConnectionClosed;
+            
+            try
+            {
+                byte success;
+                MqttConnectConfig config = MqttConfig.MqttConnectConfig;
+                if (MqttConfig.Credentials is MqttCredentials mqttCreds)
+                    success = mqttClient.Connect(Guid.NewGuid().ToString(), mqttCreds.UserName, mqttCreds.Password, config.WillRetain, config.WillQosLevel, config.WillFlag, config.WillTopic, config.WillMessage, config.CleanSession, config.KeepAlivePeriod);
+                else
+                    success = mqttClient.Connect(Guid.NewGuid().ToString(), null, null, config.WillRetain, config.WillQosLevel, config.WillFlag, config.WillTopic, config.WillMessage, config.CleanSession, config.KeepAlivePeriod);
+
+                if (success != 0)
+                    return new Result(false, new Message(MessageType.Error, "Could not connect to MQTT Broker", success.ToString()));
+
+                mqttClient.MqttMsgPublishReceived += MqttClient_MqttMsgPublishReceived;
+                return new Result(true);
+            }
+            catch (Exception e)
+            {
+                logger.Error(e, "Could not connect MQTT-Broker");
+                return new Result(e);
+            }
+        }
+
+        public IResult Stop()
+        {
+            if (mqttClient != null)
+            {
+                if (mqttClient.IsConnected)
+                {
+                    connectionClosedResetEvent = new ManualResetEvent(false);
+                    mqttClient.ConnectionClosed += MqttClient_ConnectionClosed;
+                    mqttClient.MqttMsgPublishReceived -= MqttClient_MqttMsgPublishReceived;
+
+                    mqttClient.Disconnect();
+
+                    bool success = connectionClosedResetEvent.WaitOne(5000);
+
+                    if (!success)
+                    {
+                        logger.Error("Could not close MQTT-Client");
+                        return new Result(false, new Message(MessageType.Error, "Could not close MQTT-Client"));
+                    }
+                }
+                mqttClient = null;
+            }
+            return new Result(true);
+        }
+
+        private void MqttClient_ConnectionClosed(object sender, EventArgs e)
+        {
+            connectionClosedResetEvent?.Set();
+            ConnectionClosed?.Invoke(sender, e);
+        }
+    }
+
+    public class MqttMsgPublishedEventArgs : IMessagePublishedEventArgs
+    {
+        public bool IsPublished { get; }
+        public string MessageId { get; }
+        public MqttMsgPublishedEventArgs(uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishedEventArgs e)
+        {
+            IsPublished = e.IsPublished;
+            MessageId = e.MessageId.ToString();
+        }
+    }
+    public class MqttMsgReceivedEventArgs : IMessageReceivedEventArgs
+    {
+        public string Message { get; }
+        public string Topic { get; }
+        public byte QosLevel { get; }
+        public bool Retain { get; }
+        public bool DupFlag { get; }
+        public MqttMsgReceivedEventArgs(MqttMsgPublishEventArgs e)
+        {
+            Message = Encoding.UTF8.GetString(e.Message);
+            Topic = e.Topic;
+            QosLevel = e.QosLevel;
+            Retain = e.Retain;
+            DupFlag = e.DupFlag;
+        }
+    }
+
+}
diff --git a/sdks/csnet/BaSys40.Utils/Client/SimpleHttpClient.cs b/sdks/csnet/BaSys40.Utils/Client/SimpleHttpClient.cs
deleted file mode 100644
index 72cf7e3..0000000
--- a/sdks/csnet/BaSys40.Utils/Client/SimpleHttpClient.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-using BaSys40.Utils.ResultHandling;
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BaSys40.Utils.Client
-{ 
-    public abstract class SimpleHttpClient
-    {
-        public static HttpClient HttpClient { get; }
-        public static HttpClientHandler HttpClientHandler { get; }
-        public static JsonSerializerSettings JsonSerializerSettings { get; }
-
-        static SimpleHttpClient()
-        {
-            JsonSerializerSettings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented };
-
-            HttpClientHandler = new HttpClientHandler() { MaxConnectionsPerServer = 100 };
-            HttpClient = new HttpClient(HttpClientHandler);
-        }
-
-        protected virtual IResult<HttpResponseMessage> SendRequest(HttpRequestMessage message, int timeout)
-        {
-            try
-            {
-                var task = HttpClient.SendAsync(message);
-                if (Task.WhenAny(task, Task.Delay(timeout)).Result == task)
-                {
-                    return new Result<HttpResponseMessage>(true, task.Result);
-                }
-                else
-                {
-                    return new Result<HttpResponseMessage>(false, new List<IMessage> { new Message(MessageType.Error, "Error while sending the request: timeout") });
-                }
-            }
-            catch (Exception e)
-            {
-                return new Result<HttpResponseMessage>(e);
-            }
-        }
-
-        protected virtual HttpRequestMessage CreateRequest(Uri uri, HttpMethod method)
-        {
-            return CreateRequest(uri, method, null);
-        }
-
-        protected virtual HttpRequestMessage CreateRequest(Uri uri, HttpMethod method, object content)
-        {           
-            HttpRequestMessage message = new HttpRequestMessage(method, uri);
-            if (content != null)
-                message.Content = new StringContent(JsonConvert.SerializeObject(content, JsonSerializerSettings), Encoding.Default, "application/json");
-
-            return message;
-        }
-
-        protected virtual IResult EvaluateResponse(HttpResponseMessage response)
-        {
-            if (response != null)
-            {
-                var responseString = response.Content.ReadAsStringAsync().Result;
-                if (response.IsSuccessStatusCode)
-                    return new Result(true, new List<IMessage> { new Message(MessageType.Information, response.ReasonPhrase, ((int)response.StatusCode).ToString()) });
-                else
-                    return new Result(false, new List<IMessage> { new Message(MessageType.Error, response.ReasonPhrase + "| " + responseString, ((int)response.StatusCode).ToString()) });
-            }
-            return new Result(false, new List<IMessage> { new Message(MessageType.Error, "Response from host is null", null) });
-        }
-
-        protected virtual IResult<T> EvaluateResponse<T>(HttpResponseMessage response)
-        {
-            if (response != null)
-            {
-                var responseString = response.Content.ReadAsStringAsync().Result;
-                if (response.IsSuccessStatusCode)
-                {
-                    try
-                    {
-                        var requestResult = JsonConvert.DeserializeObject<T>(responseString);
-                        return new Result<T>(true, requestResult, new List<IMessage> { new Message(MessageType.Information, response.ReasonPhrase, ((int)response.StatusCode).ToString()) });
-                    }
-                    catch (Exception e)
-                    {
-                        return new Result<T>(false, new List<IMessage> { new Message(MessageType.Error, e.Message, e.HelpLink) });
-                    }
-                }
-                else
-                    return new Result<T>(false, new List<IMessage> { new Message(MessageType.Error, response.ReasonPhrase + "| " + responseString, ((int)response.StatusCode).ToString()) });
-            }
-            return new Result<T>(false, new List<IMessage> { new Message(MessageType.Error, "Response from host is null", null) });
-        }
-    }
-}
diff --git a/sdks/csnet/BaSys40.Utils/Config/IEventHandlerConfig.cs b/sdks/csnet/BaSys40.Utils/Config/IEventHandlerConfig.cs
new file mode 100644
index 0000000..341ce19
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/Config/IEventHandlerConfig.cs
@@ -0,0 +1,14 @@
+using BaSys40.Utils.Security;
+
+namespace BaSys40.Utils.Config
+{
+    public interface IEventHandlerConfig
+    {
+        string ClientId { get; }
+        string BrokerEndpoint { get; }
+        int PublishTimeout { get; }
+        int ReceiveTimeout { get; }
+        ICredentials Credentials { get; }
+        ISecurity Security { get; }
+    }
+}
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Utils/DIExtensions/StandardDIConfiguration.cs b/sdks/csnet/BaSys40.Utils/DIExtensions/StandardDIConfiguration.cs
new file mode 100644
index 0000000..d681f62
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/DIExtensions/StandardDIConfiguration.cs
@@ -0,0 +1,22 @@
+using BaSys40.Utils.JsonHandling;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Options;
+
+namespace BaSys40.Utils.DIExtensions
+{
+    public static class StandardDIConfiguration
+    {
+        public static IServiceCollection ConfigureStandardDI(this IServiceCollection services)
+        {
+            services.TryAddSingleton<IDIExtension>(s =>
+            {
+                return new DIExtension(services);
+            });
+            services.AddTransient<IConfigureOptions<MvcJsonOptions>, JsonOptionsSetup>();
+
+            return services;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/DIExtensions/StandardRewriterOptions.cs b/sdks/csnet/BaSys40.Utils/DIExtensions/StandardRewriterOptions.cs
new file mode 100644
index 0000000..447042d
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/DIExtensions/StandardRewriterOptions.cs
@@ -0,0 +1,62 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Rewrite;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace BaSys40.Utils.DIExtensions
+{
+    public static class StandardRewriterOptions
+    {
+        private static readonly List<string> RouteExceptions = new List<string>() { "fonts", "ui", "scripts", "images"};
+
+        public static void AddStandardRewriterOptions(this IApplicationBuilder applicationBuilder)
+        {
+            RewriteOptions options = new RewriteOptions();
+            options.Add(RewriteRule);
+            applicationBuilder.UseRewriter(options);
+        }
+
+        private static void RewriteRule(RewriteContext obj)
+        {
+            string[] oldPath = obj.HttpContext.Request.Path.ToUriComponent().Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
+
+            List<string> newPath = new List<string>();
+            for (int i = 0; i < oldPath.Length; i++)
+            {
+                string pathElement = oldPath[i].ToLower();
+                bool lastElement = (i == oldPath.Length - 1);
+                if (pathElement == "aas" && lastElement)
+                {
+                    newPath.Add("/aas");
+                    break;
+                }
+                else if (pathElement == "submodels")
+                {
+                    if ((i + 1) <= oldPath.Length - 1)
+                    {
+                        newPath.Add("/submodel");
+                        obj.HttpContext.Request.QueryString = new QueryString("?submodelId=" + oldPath[i + 1]);
+                    }
+                    else
+                        newPath.Add("/aas/submodels");
+                }
+                else if(i > 0 && oldPath[i - 1] != "submodels")
+                {
+                     newPath.Add(oldPath[i]);
+                }
+                else
+                {
+                    if (i == 0 && RouteExceptions.Contains(pathElement))
+                    {
+                        obj.Result = RuleResult.ContinueRules;
+                        return;
+                    }
+                }
+            }
+            obj.HttpContext.Request.Path = new PathString(string.Join("/", newPath.ToArray()));
+            obj.Result = RuleResult.ContinueRules;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/JsonHandling/CustomTypeSerializer.cs b/sdks/csnet/BaSys40.Utils/JsonHandling/CustomTypeSerializer.cs
index 493c5a2..e9551de 100644
--- a/sdks/csnet/BaSys40.Utils/JsonHandling/CustomTypeSerializer.cs
+++ b/sdks/csnet/BaSys40.Utils/JsonHandling/CustomTypeSerializer.cs
@@ -40,7 +40,7 @@
             {
                 JObject o = (JObject)t;
                 Type type = value.GetType();
-                JObject typeWrapper = new JObject(new JProperty(type.FullName, o));
+                JObject typeWrapper = new JObject(new JProperty(type.Namespace + "." + type.Name, o));
 
                 typeWrapper.WriteTo(writer);
             }
diff --git a/sdks/csnet/BaSys40.Utils/JsonHandling/JsonOptionsSetup.cs b/sdks/csnet/BaSys40.Utils/JsonHandling/JsonOptionsSetup.cs
index 72b224a..8f46165 100644
--- a/sdks/csnet/BaSys40.Utils/JsonHandling/JsonOptionsSetup.cs
+++ b/sdks/csnet/BaSys40.Utils/JsonHandling/JsonOptionsSetup.cs
@@ -9,6 +9,8 @@
     public class JsonOptionsSetup : IConfigureOptions<MvcJsonOptions>
     {
         IServiceProvider serviceProvider;
+
+        public MvcJsonOptions Options { get; private set; }
         public JsonOptionsSetup(IServiceProvider serviceProvider)
         {
             this.serviceProvider = serviceProvider;
@@ -17,6 +19,9 @@
         {
             options.SerializerSettings.ContractResolver = new DIContractResolver(serviceProvider.GetService<IDIExtension>(), serviceProvider);
             options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
+            options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
+
+            Options = options;
         }
     }
 }
diff --git a/sdks/csnet/BaSys40.Utils/JsonHandling/PrivatePropertyContractResolver.cs b/sdks/csnet/BaSys40.Utils/JsonHandling/PrivatePropertyContractResolver.cs
new file mode 100644
index 0000000..08d55f5
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/JsonHandling/PrivatePropertyContractResolver.cs
@@ -0,0 +1,27 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using System.Reflection;
+
+namespace BaSys40.Utils.JsonHandling
+{
+    public class PrivatePropertyContractResolver : DefaultContractResolver
+    {
+        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
+        {
+            var prop = base.CreateProperty(member, memberSerialization);
+
+            if (!prop.Writable)
+            {
+                var property = member as PropertyInfo;
+                if (property != null)
+                {
+                    var hasPrivateSetter = property.GetSetMethod(true) != null;
+                    prop.Writable = hasPrivateSetter;
+                }
+            }
+
+            return prop;
+        }
+
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/Logging/LoggingExtentions.cs b/sdks/csnet/BaSys40.Utils/Logging/LoggingExtentions.cs
index 149f0e3..d2432d8 100644
--- a/sdks/csnet/BaSys40.Utils/Logging/LoggingExtentions.cs
+++ b/sdks/csnet/BaSys40.Utils/Logging/LoggingExtentions.cs
@@ -20,7 +20,7 @@
                     logText.Append("Message[" + i + "] = " + result.Messages[i].Text).Append(" || ");
                 }
             }
-            if (result.Entity != null && result is HttpResponseMessage response)
+            if (result.Entity != null && result.Entity is HttpResponseMessage response)
             {
                 logText.Append("StatusCode: " + ((int)response.StatusCode).ToString()).Append(response.ReasonPhrase).Append(" || ");
                 logText.Append("Body: " + response.Content.ReadAsStringAsync().Result).Append(" || ");
diff --git a/sdks/csnet/BaSys40.Utils/ModelHandling/ModelUtils.cs b/sdks/csnet/BaSys40.Utils/ModelHandling/ModelUtils.cs
new file mode 100644
index 0000000..0933f9a
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/ModelHandling/ModelUtils.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+namespace BaSys40.Utils.ModelHandling
+{
+    public class ModelUtils
+    {
+        public static IEnumerable<Type> GetTypesWithAttribute(Assembly assembly, Type attributeType)
+        {
+            foreach (Type type in assembly.GetTypes())
+            {
+                if (type.GetCustomAttributes(attributeType, true).Length > 0)
+                {
+                    yield return type;
+                }
+            }
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/TreeBuilder.cs b/sdks/csnet/BaSys40.Utils/ModelHandling/TreeBuilder.cs
similarity index 99%
rename from sdks/csnet/BaSys40.Technologies.oneM2M/Utils/TreeBuilder.cs
rename to sdks/csnet/BaSys40.Utils/ModelHandling/TreeBuilder.cs
index 720be3e..08d4e31 100644
--- a/sdks/csnet/BaSys40.Technologies.oneM2M/Utils/TreeBuilder.cs
+++ b/sdks/csnet/BaSys40.Utils/ModelHandling/TreeBuilder.cs
@@ -3,7 +3,7 @@
 using System.Collections.ObjectModel;
 using System.Linq;
 
-namespace oneM2MClient.Utils
+namespace BaSys40.Utils.ModelHandling
 {
     public class ObjectTreeBuilder : TreeBuilder<object>
     {
diff --git a/sdks/csnet/BaSys40.Utils/PathHandling/Path.cs b/sdks/csnet/BaSys40.Utils/PathHandling/Path.cs
new file mode 100644
index 0000000..26fd41f
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/PathHandling/Path.cs
@@ -0,0 +1,25 @@
+namespace BaSys40.Utils.PathHandling
+{
+    public static class Path
+    {
+        public static string GetFormattedEndpoint(string endpoint, string aggregateId, string entityId, string separator = "/")
+        {
+            if (endpoint[endpoint.Length - 1] == separator[0])
+            {
+                if (!endpoint.Contains(aggregateId))
+                    endpoint += aggregateId + separator + entityId;
+                else
+                    endpoint += entityId;
+            }
+            else
+            {
+                if (!endpoint.Contains(aggregateId))
+                    endpoint += separator + aggregateId + separator + entityId;
+                else
+                    endpoint += separator + entityId;
+            }
+
+            return endpoint;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/ResultHandling/IResult.cs b/sdks/csnet/BaSys40.Utils/ResultHandling/IResult.cs
index 121d84ed..328726c 100644
--- a/sdks/csnet/BaSys40.Utils/ResultHandling/IResult.cs
+++ b/sdks/csnet/BaSys40.Utils/ResultHandling/IResult.cs
@@ -15,12 +15,14 @@
         [DataMember(IsRequired = true)]
         bool Success { get; }
         [DataMember(EmitDefaultValue = false, IsRequired = false)]
+        bool? IsException { get; }
+        [DataMember(EmitDefaultValue = false, IsRequired = false)]
         List<IMessage> Messages { get; }
 
         T GetEntity<T>();
     }
 
-    public interface IResult<TEntity> : IResult
+    public interface IResult<out TEntity> : IResult
     {
         [JsonConverter(typeof(CustomTypeSerializer))]
         new TEntity Entity { get; }
diff --git a/sdks/csnet/BaSys40.Utils/ResultHandling/Message.cs b/sdks/csnet/BaSys40.Utils/ResultHandling/Message.cs
index 63291b6..bc8fc6a 100644
--- a/sdks/csnet/BaSys40.Utils/ResultHandling/Message.cs
+++ b/sdks/csnet/BaSys40.Utils/ResultHandling/Message.cs
@@ -1,4 +1,5 @@
-using System.Threading;
+using System.Net;
+using System.Threading;
 
 namespace BaSys40.Utils.ResultHandling
 {
@@ -20,7 +21,32 @@
 
         public override string ToString()
         {
-            return string.Format(Thread.CurrentThread.CurrentCulture, "{0} | {1} - {2}", MessageType, Code, Text);
+            if(!string.IsNullOrEmpty(Code))
+                return string.Format(Thread.CurrentThread.CurrentCulture, "{0} | {1} - {2}", MessageType, Code, Text);
+            else
+                return string.Format(Thread.CurrentThread.CurrentCulture, "{0} | {1}", MessageType, Text);
         }
     }
+
+    public class HttpMessage : Message
+    {
+        public HttpStatusCode HttpStatusCode { get; set; }
+
+        public HttpMessage(MessageType messageType, HttpStatusCode httpStatusCode) : base(messageType, httpStatusCode.ToString(), ((int)httpStatusCode).ToString())
+        {
+            HttpStatusCode = httpStatusCode;
+        }
+    }
+
+    public class NotFoundMessage : Message
+    {
+        public NotFoundMessage() : base(MessageType.Information, "NotFound", "404")
+        { }
+    }
+
+    public class EmptyMessage : Message
+    {
+        public EmptyMessage() : base(MessageType.Information, "Empty")
+        { }
+    }
 }
\ No newline at end of file
diff --git a/sdks/csnet/BaSys40.Utils/ResultHandling/Result.cs b/sdks/csnet/BaSys40.Utils/ResultHandling/Result.cs
index ae73a5a..0034e6f 100644
--- a/sdks/csnet/BaSys40.Utils/ResultHandling/Result.cs
+++ b/sdks/csnet/BaSys40.Utils/ResultHandling/Result.cs
@@ -9,6 +9,8 @@
     {
         public bool Success { get; private set; }
 
+        public bool? IsException { get; }
+
         public object Entity { get; private set; }
 
         public Type EntityType { get; private set; }
@@ -24,9 +26,10 @@
                 return this.messages;
             }
         }
-
         public Result(bool success) : this(success, null, null, null)
         { }
+        public Result(bool success, IMessage message) : this(success, new List<IMessage>() { message })
+        { }
 
         public Result(bool success, List<IMessage> messages) : this(success, null, null, messages)
         { }
@@ -34,21 +37,44 @@
         public Result(bool success, object entity, Type entityType) : this(success, entity, entityType, null)
         { }
 
-        public Result(Exception e) : 
-            this(false, e, e.GetType(), new List<IMessage>()
-            {
-                new Message(MessageType.Error, e.Message),
-                new Message(MessageType.Error, e.InnerException != null ? e.InnerException.Message : "InnerException = null")
-            })
+        public Result(Exception e) :
+            this(false, GetMessageListFromException(e))
         { }
 
+        public Result(IResult result) : this(result.Success, result.Entity, result.EntityType, result.Messages)
+        { }
+
+        public static List<IMessage> GetMessageListFromException(Exception e)
+        {
+            List<IMessage> messageList = new List<IMessage>();
+
+            if (e.InnerException != null)
+                messageList.AddRange(GetMessageListFromException(e.InnerException));
+
+            messageList.Add(GetMessageFromException(e));
+
+            return messageList;
+        }
+
+        public static IMessage GetMessageFromException(Exception e)
+        {
+            var message = new Message(MessageType.Exception, e.GetType().Name + ":" + e.Message);
+
+            return message;
+        }
+
         public Result(bool success, object entity, Type entityType, List<IMessage> messages)
         {
             Success = success;
 
             if (messages != null)
                 foreach (Message msg in messages)
+                {
+                    if (msg.MessageType == MessageType.Exception)
+                        IsException = true;
+
                     Messages.Add(msg);
+                }
 
             if (entity != null && entityType != null)
             {
@@ -67,13 +93,30 @@
                 return (T)Entity;
             return default(T);
         }
+        
+        public override string ToString()
+        {
+            string messageTxt = string.Empty;
+            for (int i = 0; i < Messages.Count; i++)
+                messageTxt += Messages[i].ToString() + " || ";
+
+            string entityTxt = string.Empty;
+            if (Entity != null)
+                entityTxt = Entity.ToString();
+
+            var txt =  $"Success: {Success}";
+            if (entityTxt != string.Empty)
+                txt += " | Entity: " + entityTxt;
+            if (messageTxt != string.Empty)
+                txt += " | Messages: " + messageTxt;
+            return txt;
+        }
     }
 
     public class Result<TEntity> : Result, IResult<TEntity>
     {
         [IgnoreDataMember]
         public new TEntity Entity { get; private set; }
-
         public Result(bool success) : this(success, default(TEntity), new List<IMessage>())
         { }
         public Result(bool success, TEntity entity) : this(success, entity, new List<IMessage>())
@@ -86,9 +129,16 @@
         { }
         public Result(Exception e) : base(e)
         { }
+        public Result(IResult result) : base(result)
+        { }
         public Result(bool success, TEntity entity, List<IMessage> messages) : base(success, entity, typeof(TEntity), messages)
         {
             Entity = entity;
         }
+
+        public override string ToString()
+        {
+            return base.ToString();
+        }
     }
 }
diff --git a/sdks/csnet/BaSys40.Utils/ResultHandling/Utils.cs b/sdks/csnet/BaSys40.Utils/ResultHandling/Utils.cs
index 41fbb38..01c3e80 100644
--- a/sdks/csnet/BaSys40.Utils/ResultHandling/Utils.cs
+++ b/sdks/csnet/BaSys40.Utils/ResultHandling/Utils.cs
@@ -1,4 +1,5 @@
-using System;
+using Microsoft.AspNetCore.Mvc;
+using System;
 using System.Diagnostics;
 using System.Net;
 using System.Threading;
@@ -16,7 +17,9 @@
             var stopwatch = Stopwatch.StartNew();
             do
             {
-                if (task()) { return true; }
+                if (task())
+                    return true; 
+
                 Thread.Sleep((int)pause.TotalMilliseconds);
             }
             while (stopwatch.Elapsed < timeout);
@@ -48,5 +51,55 @@
                 return false;
             }
         }
+
+        public static IActionResult EvaluateResult(IResult result, CrudOperation crud)
+        {
+            if (result == null)
+                return new StatusCodeResult(502);
+
+            var objResult = new ObjectResult(result);
+
+            switch (crud)
+            {
+                case CrudOperation.Create:
+                    if (result.Success && result.Entity != null)
+                        objResult.StatusCode = 201;
+                    break;
+                case CrudOperation.Retrieve:
+                    if (result.Success && result.Entity != null)
+                        objResult.StatusCode = 200;
+                    else if (result.Success && result.Entity == null)
+                        objResult.StatusCode = 404;
+                    break;
+                case CrudOperation.Update:
+                    if (result.Success)
+                        objResult.StatusCode = 204;
+                    break;
+                case CrudOperation.Delete:
+                    if (result.Success)
+                        objResult.StatusCode = 204;
+                    break;
+                default:
+                    break;
+            }
+
+            if (!objResult.StatusCode.HasValue)
+            {
+                if (TryParseStatusCode(result, out int httpStatusCode))
+                    objResult.StatusCode = httpStatusCode;
+                else
+                    objResult.StatusCode = 502;
+            }
+
+            return objResult;
+        }
+
+        public enum CrudOperation
+        {
+            Create,
+            Retrieve,
+            Update,
+            Delete
+        }
     }
 }
diff --git a/sdks/csnet/BaSys40.Utils/Security/ICredentials.cs b/sdks/csnet/BaSys40.Utils/Security/ICredentials.cs
new file mode 100644
index 0000000..2d41acd
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/Security/ICredentials.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BaSys40.Utils.Security
+{
+    public interface ICredentials
+    {
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/Security/ISecurity.cs b/sdks/csnet/BaSys40.Utils/Security/ISecurity.cs
new file mode 100644
index 0000000..0e33888
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/Security/ISecurity.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace BaSys40.Utils.Security
+{
+    public interface ISecurity
+    {
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/Server/SimpleLocalHttpServer.cs b/sdks/csnet/BaSys40.Utils/Server/SimpleLocalHttpServer.cs
index f3f508a..ff98fef 100644
--- a/sdks/csnet/BaSys40.Utils/Server/SimpleLocalHttpServer.cs
+++ b/sdks/csnet/BaSys40.Utils/Server/SimpleLocalHttpServer.cs
@@ -6,6 +6,7 @@
 using System.Net;
 using System.Text;
 using System.Threading;
+using System.Threading.Tasks;
 
 namespace BaSys40.Utils.Server
 {
@@ -13,24 +14,38 @@
     {
         public Uri Endpoint { get; }
 
-        private Thread serverThread;
         private HttpListener listener;
+        private CancellationTokenSource cancellationToken;
         private Action<HttpListenerRequest> messageReception = null;
         private Action<HttpListenerResponse> messageResponse = null;
+        private Action<HttpListenerContext> messageHandler = null;
 
         private static Logger logger = LogManager.GetCurrentClassLogger();
 
-        public SimpleLocalHttpServer(int port, string hostAddress = "127.0.0.1")
+        public SimpleLocalHttpServer(string endpoint)
         {
-            string uri = "http://" + hostAddress + ":" + port;
-            Endpoint = new Uri(uri);
+            Endpoint = new Uri(endpoint);
         }
 
 
         public void Start()
         {
-            serverThread = new Thread(this.Listen);
-            serverThread.Start();
+            listener = new HttpListener();
+            listener.Prefixes.Add(Endpoint.OriginalString + "/");
+            cancellationToken = new CancellationTokenSource();
+
+            if (!listener.IsListening)
+            {
+                listener.Start();
+
+                Task.Factory.StartNew(async () =>
+                {
+                    while (!cancellationToken.IsCancellationRequested)
+                        await Listen(listener);
+                }, cancellationToken.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current);
+
+                logger.Info("Http-Listener started");
+            }
         }
 
         public void Start(Action<HttpListenerRequest> receiveMessageMethod)
@@ -46,42 +61,40 @@
             Start();
         }
 
-        private void Listen()
+        public void Start(Action<HttpListenerContext> messageHandlerMethod)
+        {
+            messageHandler = messageHandlerMethod;
+            Start();
+        }
+        private async Task Listen(HttpListener listener)
         {
             try
             {
-                listener = new HttpListener();
-                listener.Prefixes.Add(Endpoint.OriginalString + "/");
-                listener.Start();
-            }
-            catch (Exception e)
-            {
-                logger.Error(e, "Http-Listener could not be started: " + e.Message);
-            }
-
-            while (listener.IsListening)
-            {
-                try
+                HttpListenerContext context = await listener.GetContextAsync();
+                if (messageHandler != null)
+                    messageHandler.Invoke(context);
+                else
                 {
-                    HttpListenerContext context = listener.GetContext();
                     if (messageReception != null)
                         messageReception.Invoke(context.Request);
                     if (messageResponse != null)
                         messageResponse.Invoke(context.Response);
                 }
-                catch (Exception e)
-                {
-                    logger.Warn(e, "Http-Listener Exception: " + e.Message);
-                }
             }
-
-
+            catch (Exception e)
+            {
+                logger.Error(e, "Http-Listener Exception: " + e.Message);
+            }
         }
 
         public void Stop()
         {
-            listener.Stop();
-            serverThread.Abort();
+            if (listener.IsListening)
+            {
+                cancellationToken.Cancel();
+                listener.Stop();
+                logger.Info("Http-Listener stopped");
+            }
         }
 
         public static List<string> GetLocalIpAddresses()
diff --git a/sdks/csnet/BaSys40.Utils/Settings/ResourceChecker.cs b/sdks/csnet/BaSys40.Utils/Settings/ResourceChecker.cs
new file mode 100644
index 0000000..472de5b
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/Settings/ResourceChecker.cs
@@ -0,0 +1,68 @@
+using NLog;
+using System;
+using System.IO;
+using System.Reflection;
+
+namespace BaSys40.Utils.Settings
+{
+    public static class ResourceChecker
+    {
+        private static Logger logger = LogManager.GetCurrentClassLogger();
+
+        /// <summary>
+        /// Prüft ob eine notwendige Ressource vorhanden ist oder nicht
+        /// </summary>
+        /// <param name="resourceName">Name der Ressource inkl. Pfad (z.B. ApplicationStartupPath + "\\WcfClientEndpoints.config")</param>
+        /// <param name="create">Gibt an ob die Ressource notfalls angelegt werden soll</param>
+        /// <returns>
+        /// true = Ressource ist vorhanden
+        /// false = Ressource nicht vorhanden und/oder kann nicht angelegt werden
+        /// </returns>
+        public static bool CheckResource(Assembly sourceAssembly, string nameSpace, string resourceName, bool create)
+        {
+            if (File.Exists(resourceName) || File.Exists(Path.Combine(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location), resourceName)))
+                return true;
+            else if (create)
+            {
+                if (WriteEmbeddedRessourceToFile(sourceAssembly, nameSpace, resourceName, null))
+                    return true;
+                else
+                    return false;
+            }
+            else
+                return false;
+        }
+        /// <summary>
+        /// Schreibt eine eingebette Ressource in eine Datei im gleichen Pfad die gerade ausführende Applikation
+        /// </summary>
+        /// <param name="resourceName">Name der Ressource inkl. Pfad (z.B. ApplicationStartupPath + "\\WcfClientEndpoints.config")</param>
+        /// <returns>
+        /// true = Ressource wurde erfolgreich angelegt
+        /// false = Ressource konnte nicht angelegt werden
+        /// </returns>
+        public static bool WriteEmbeddedRessourceToFile(Assembly sourceAssembly, string nameSpace, string resourceName, string destinationFilename)
+        {
+            try
+            {
+                Stream configStream = sourceAssembly.GetManifestResourceStream(string.Join(".", nameSpace, resourceName));
+                if (configStream == null)
+                    throw new FileNotFoundException("Resource '" + resourceName + "' not found");
+
+                string filePath = string.IsNullOrEmpty(destinationFilename) ? Path.Combine(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location), resourceName) : destinationFilename;
+
+                using (var fileStream = File.Create(filePath))
+                {
+                    configStream.Seek(0, SeekOrigin.Begin);
+                    configStream.CopyTo(fileStream);
+                }
+                return (true);
+            }
+            catch (Exception e)
+            {
+                logger.Error(e, "Error creating '" + resourceName + "' from embedded resource. Exception: " + e.ToString());
+                return (false);
+            }
+
+        }
+    }
+}
diff --git a/sdks/csnet/BaSys40.Utils/Settings/Settings.cs b/sdks/csnet/BaSys40.Utils/Settings/Settings.cs
index cef191a..3b695f6 100644
--- a/sdks/csnet/BaSys40.Utils/Settings/Settings.cs
+++ b/sdks/csnet/BaSys40.Utils/Settings/Settings.cs
@@ -3,6 +3,7 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Reflection;
 using System.Xml;
 using System.Xml.Linq;
 using System.Xml.Serialization;
@@ -13,15 +14,15 @@
     [Serializable]
     public abstract class Settings<T> : ISettings where T : ISettings, new()
     {
-        private FileWatcher fileWatcher;
-
-        public string FilePath { get; set; }
-
-        public const string SettingsAppendix = ".xml";
+        public const string FileExtension = ".xml";
         public const string MiscellaneousConfig = "Miscellaneous";
 
         private static Logger logger = LogManager.GetCurrentClassLogger();
-        public static string FileName => typeof(T).Name + SettingsAppendix;
+        public static string FileName => typeof(T).Name + FileExtension;
+        public static string ExecutingDirectory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+
+        public string FilePath { get; set; }
+        private FileWatcher fileWatcher;
 
         public Settings()
         {
@@ -36,6 +37,16 @@
         {
             fileWatcher = new FileWatcher(settingsFilePath, settingsFileChangedHandler);
         }
+
+        public static T LoadSettings()
+        {
+            string settingsFilePath = Path.Combine(ExecutingDirectory, FileName);
+
+            if (string.IsNullOrEmpty(settingsFilePath) || !File.Exists(settingsFilePath))
+                return default(T);
+            else
+                return LoadSettings(settingsFilePath);
+        }
     
         public static T LoadSettings(string filePath)
         {
diff --git a/sdks/csnet/BaSys40.Utils/StringOperations/StringOperations.cs b/sdks/csnet/BaSys40.Utils/StringOperations/StringOperations.cs
new file mode 100644
index 0000000..2396921
--- /dev/null
+++ b/sdks/csnet/BaSys40.Utils/StringOperations/StringOperations.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace BaSys40.Utils.StringOperations
+{
+    public static class StringOperations
+    {
+        public static string GetValueOrStringEmpty<T>(T? nullable) where T : struct
+        {
+            if (nullable != null)
+            {
+                var value = Nullable.GetUnderlyingType(nullable.GetType());
+                if (value != null && value.IsEnum)
+                    Enum.GetName(Nullable.GetUnderlyingType(nullable.GetType()), nullable.Value);
+                else
+                    return nullable.Value.ToString();
+            }
+            return string.Empty;
+        }
+    }
+}
diff --git a/sdks/csnet/BaSyx.SDK.sln b/sdks/csnet/BaSyx.SDK.sln
new file mode 100644
index 0000000..0626857
--- /dev/null
+++ b/sdks/csnet/BaSyx.SDK.sln
@@ -0,0 +1,84 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.136
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaSys40.API", "BaSys40.API\BaSys40.API.csproj", "{87045925-FD2C-4BC9-BA55-8B4080BBA49C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaSys40.Models", "BaSys40.Models\BaSys40.Models.csproj", "{7F405114-18CB-484B-B6C9-39FB6DF8EE76}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaSys40.Utils", "BaSys40.Utils\BaSys40.Utils.csproj", "{87783EE4-52CD-4B54-B278-B61A7B9E226A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaSys40.Component.REST", "BaSys40.Component.REST\BaSys40.Component.REST.csproj", "{B9158C2C-DF1E-413A-A72E-E82436888302}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaSys40.Registry.Client", "BaSys40.Registry.Client\BaSys40.Registry.Client.csproj", "{B0B1680F-BCE7-461E-AA1D-A23A05A1D41B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaSys40.RI.AAS.SmartControl", "BaSys40.RI.AAS.SmartControl\BaSys40.RI.AAS.SmartControl.csproj", "{E2347CF5-E6C8-45EF-8E78-E438F2940446}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaSys40.Technologies.oneM2M", "BaSys40.Technologies.oneM2M\BaSys40.Technologies.oneM2M.csproj", "{D1A3F11A-2811-42F1-945B-D348A92F77B0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaSys40.Component.REST.Client", "BaSys40.Component.REST.Client\BaSys40.Component.REST.Client.csproj", "{49C167AB-4412-4AC3-801D-6BFF4B939402}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+		RemoteDebug|Any CPU = RemoteDebug|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{87045925-FD2C-4BC9-BA55-8B4080BBA49C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{87045925-FD2C-4BC9-BA55-8B4080BBA49C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{87045925-FD2C-4BC9-BA55-8B4080BBA49C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{87045925-FD2C-4BC9-BA55-8B4080BBA49C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{87045925-FD2C-4BC9-BA55-8B4080BBA49C}.RemoteDebug|Any CPU.ActiveCfg = RemoteDebug|Any CPU
+		{87045925-FD2C-4BC9-BA55-8B4080BBA49C}.RemoteDebug|Any CPU.Build.0 = RemoteDebug|Any CPU
+		{7F405114-18CB-484B-B6C9-39FB6DF8EE76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7F405114-18CB-484B-B6C9-39FB6DF8EE76}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7F405114-18CB-484B-B6C9-39FB6DF8EE76}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7F405114-18CB-484B-B6C9-39FB6DF8EE76}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7F405114-18CB-484B-B6C9-39FB6DF8EE76}.RemoteDebug|Any CPU.ActiveCfg = RemoteDebug|Any CPU
+		{7F405114-18CB-484B-B6C9-39FB6DF8EE76}.RemoteDebug|Any CPU.Build.0 = RemoteDebug|Any CPU
+		{87783EE4-52CD-4B54-B278-B61A7B9E226A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{87783EE4-52CD-4B54-B278-B61A7B9E226A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{87783EE4-52CD-4B54-B278-B61A7B9E226A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{87783EE4-52CD-4B54-B278-B61A7B9E226A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{87783EE4-52CD-4B54-B278-B61A7B9E226A}.RemoteDebug|Any CPU.ActiveCfg = RemoteDebug|Any CPU
+		{87783EE4-52CD-4B54-B278-B61A7B9E226A}.RemoteDebug|Any CPU.Build.0 = RemoteDebug|Any CPU
+		{B9158C2C-DF1E-413A-A72E-E82436888302}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B9158C2C-DF1E-413A-A72E-E82436888302}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B9158C2C-DF1E-413A-A72E-E82436888302}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B9158C2C-DF1E-413A-A72E-E82436888302}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B9158C2C-DF1E-413A-A72E-E82436888302}.RemoteDebug|Any CPU.ActiveCfg = RemoteDebug|Any CPU
+		{B9158C2C-DF1E-413A-A72E-E82436888302}.RemoteDebug|Any CPU.Build.0 = RemoteDebug|Any CPU
+		{B0B1680F-BCE7-461E-AA1D-A23A05A1D41B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B0B1680F-BCE7-461E-AA1D-A23A05A1D41B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B0B1680F-BCE7-461E-AA1D-A23A05A1D41B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B0B1680F-BCE7-461E-AA1D-A23A05A1D41B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B0B1680F-BCE7-461E-AA1D-A23A05A1D41B}.RemoteDebug|Any CPU.ActiveCfg = RemoteDebug|Any CPU
+		{B0B1680F-BCE7-461E-AA1D-A23A05A1D41B}.RemoteDebug|Any CPU.Build.0 = RemoteDebug|Any CPU
+		{E2347CF5-E6C8-45EF-8E78-E438F2940446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E2347CF5-E6C8-45EF-8E78-E438F2940446}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E2347CF5-E6C8-45EF-8E78-E438F2940446}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E2347CF5-E6C8-45EF-8E78-E438F2940446}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E2347CF5-E6C8-45EF-8E78-E438F2940446}.RemoteDebug|Any CPU.ActiveCfg = RemoteDebug|Any CPU
+		{E2347CF5-E6C8-45EF-8E78-E438F2940446}.RemoteDebug|Any CPU.Build.0 = RemoteDebug|Any CPU
+		{D1A3F11A-2811-42F1-945B-D348A92F77B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D1A3F11A-2811-42F1-945B-D348A92F77B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D1A3F11A-2811-42F1-945B-D348A92F77B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D1A3F11A-2811-42F1-945B-D348A92F77B0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D1A3F11A-2811-42F1-945B-D348A92F77B0}.RemoteDebug|Any CPU.ActiveCfg = RemoteDebug|Any CPU
+		{D1A3F11A-2811-42F1-945B-D348A92F77B0}.RemoteDebug|Any CPU.Build.0 = RemoteDebug|Any CPU
+		{49C167AB-4412-4AC3-801D-6BFF4B939402}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{49C167AB-4412-4AC3-801D-6BFF4B939402}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{49C167AB-4412-4AC3-801D-6BFF4B939402}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{49C167AB-4412-4AC3-801D-6BFF4B939402}.Release|Any CPU.Build.0 = Release|Any CPU
+		{49C167AB-4412-4AC3-801D-6BFF4B939402}.RemoteDebug|Any CPU.ActiveCfg = Debug|Any CPU
+		{49C167AB-4412-4AC3-801D-6BFF4B939402}.RemoteDebug|Any CPU.Build.0 = Debug|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {B028A9A2-E37C-44AF-8032-C8F0492BDB00}
+	EndGlobalSection
+EndGlobal
diff --git a/sdks/csnet/Modules/Speaker/Speaker.sln b/sdks/csnet/Modules/Speaker/Speaker.sln
deleted file mode 100644
index 63d231d..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker.sln
+++ /dev/null
@@ -1,25 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27130.2024
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speaker", "Speaker\Speaker.csproj", "{CF6CE935-C79C-43CC-AE30-48298326794C}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{CF6CE935-C79C-43CC-AE30-48298326794C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{CF6CE935-C79C-43CC-AE30-48298326794C}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{CF6CE935-C79C-43CC-AE30-48298326794C}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{CF6CE935-C79C-43CC-AE30-48298326794C}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {B44287AD-7267-4C9C-8F6C-3262B9262A44}
-	EndGlobalSection
-EndGlobal
diff --git a/sdks/csnet/Modules/Speaker/Speaker/App.config b/sdks/csnet/Modules/Speaker/Speaker/App.config
deleted file mode 100644
index 731f6de..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<configuration>
-    <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
-    </startup>
-</configuration>
\ No newline at end of file
diff --git a/sdks/csnet/Modules/Speaker/Speaker/Events/Spoken.cs b/sdks/csnet/Modules/Speaker/Speaker/Events/Spoken.cs
deleted file mode 100644
index 9f3af6b..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker/Events/Spoken.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using System;
-using System.Collections.Generic;
-using BaSys40.Models.Core.Identification;
-
-namespace Speaker.Events
-{
-    public class Spoken : IEventDescription, IPublishableEvent
-    {
-        public string TimeStamp => DateTime.Now.ToString();
-
-        public string Message { get; set; }
-
-        public string Originator => "Microsoft_SAM";
-
-        public string EventName => "Spoken";
-
-        public string EventCategory => "Speaker.Events";
-
-        public EntityType? EntityType => BaSys40.Models.Core.AssetAdministrationShell.Generics.EntityType.Primitive;
-
-        public SchemaType? SchemaType => BaSys40.Models.Core.AssetAdministrationShell.Generics.SchemaType.None;
-
-        public string Schema => null;
-
-        public string Description => "The last spoken words";
-
-        public string DisplayName => "Spoken";
-        public IIdentifiable Parent { get; set; }
-        public Dictionary<string, string> MetaData => null;
-
-        private Identifier Identifier;
-        public Identifier EventDescriptionReference => Identifier;
-        public Identifier Identification
-        {
-            get
-            {
-                if (Identifier == null)
-                    Identifier = new Identifier(Guid.NewGuid().ToString(), Identificator.Internal);
-                return Identifier;
-            }
-        }
-    }
-}
diff --git a/sdks/csnet/Modules/Speaker/Speaker/Events/StartupCompleted.cs b/sdks/csnet/Modules/Speaker/Speaker/Events/StartupCompleted.cs
deleted file mode 100644
index 7e6fa44..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker/Events/StartupCompleted.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using System;
-using System.Collections.Generic;
-using BaSys40.Models.Core.Identification;
-
-namespace Speaker.Events
-{
-    public class StartupCompleted : IEventDescription, IPublishableEvent
-    {
-        public string TimeStamp => DateTime.Now.ToString();
-
-        public string Message { get; set; }
-
-        public string Originator => "Microsoft_SAM";
-
-        public string EventName => "StartupCompleted";
-
-        public string EventCategory => "StatusEvents";
-
-        public EntityType? EntityType => BaSys40.Models.Core.AssetAdministrationShell.Generics.EntityType.Primitive;
-
-        public SchemaType? SchemaType => BaSys40.Models.Core.AssetAdministrationShell.Generics.SchemaType.None;
-
-        public string Schema => null;
-
-        public string Description => "Startup-Completed Event";
-
-        public string DisplayName => "StartupCompleted";
-        public IIdentifiable Parent { get; set; }
-        public Dictionary<string, string> MetaData => null;
-
-
-        private Identifier Identifier;
-        public Identifier EventDescriptionReference => Identifier;
-        public Identifier Identification
-        {
-            get
-            {
-                if (Identifier == null)
-                    Identifier = new Identifier(Guid.NewGuid().ToString(), Identificator.Internal);
-                return Identifier;
-            }
-        }
-    }
-}
diff --git a/sdks/csnet/Modules/Speaker/Speaker/Program.cs b/sdks/csnet/Modules/Speaker/Speaker/Program.cs
deleted file mode 100644
index 657e6b5..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker/Program.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Speaker
-{
-    class Program
-    {
-        static void Main(string[] args)
-        {
-            Speaker speaker = new Speaker();
-            speaker.SaySomething("Hello World!", "en-EN");
-            do
-            {
-                while (!Console.KeyAvailable)
-                {
-                    Console.Write("Please enter text [Q=Exit]:");
-                    var text = Console.ReadLine();
-
-                    if (text == "Q")
-                        return;
-
-                    speaker.SaySomething(text, "en-EN");
-                }
-
-            } while (Console.ReadKey(true).Key != ConsoleKey.Escape);
-
-        }
-    }
-}
diff --git a/sdks/csnet/Modules/Speaker/Speaker/Properties/AssemblyInfo.cs b/sdks/csnet/Modules/Speaker/Speaker/Properties/AssemblyInfo.cs
deleted file mode 100644
index 78d8221..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Speaker")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("BOSCH")]
-[assembly: AssemblyProduct("Speaker")]
-[assembly: AssemblyCopyright("Copyright © BOSCH 2018")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components.  If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("cf6ce935-c79c-43cc-ae30-48298326794c")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/sdks/csnet/Modules/Speaker/Speaker/Speaker.cs b/sdks/csnet/Modules/Speaker/Speaker/Speaker.cs
deleted file mode 100644
index 685023f..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker/Speaker.cs
+++ /dev/null
@@ -1,270 +0,0 @@
-using BaSys40.API.AssetAdministrationShell;
-using BaSys40.API.Components;
-using BaSys40.Models.Core;
-using BaSys40.Models.Core.AssetAdministrationShell.Generics;
-using BaSys40.Models.Core.AssetAdministrationShell.Implementations;
-using BaSys40.Utils.ResultHandling;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Speech.Synthesis;
-using Speaker.Events;
-using BaSys40.Models.Core.Identification;
-using BaSys40.Models.Core.AssetAdministrationShell.Enums;
-using BaSys40.API.Platform;
-using BaSys40.API.AssetAdministrationShell.Connectables;
-
-namespace Speaker
-{
-    public partial class Speaker : IComponentConnector
-    {
-        private readonly SpeechSynthesizer speaker;
-        private IConnectableProperty lastWordsConnected;
-        private Dictionary<string, IConnectableEvent> Events;
-
-        public string LastWords { get; set; }
-
-        public Speaker() : this (1, 100)
-        { }
-
-        public Speaker(int rate, int volume)
-        {
-            //configure speech synthesizer
-            speaker = new SpeechSynthesizer
-            {
-                Rate = rate,
-                Volume = volume                
-            };
- 
-            SaySomething("Hello World", "en-EN");
-        }
-
-        public IResult Register(IAssetAdministrationShellRegistry registry, IAssetAdministrationShell aas)
-        {
-            var createResult = registry.CreateAssetAdministrationShell(aas);
-            return createResult;
-        }
-
-        public IResult CreateStructure(IAssetAdministrationShellManager manager, IAssetAdministrationShellHandler handler, IAssetAdministrationShell aas)
-        {
-            var alreadyExists = manager.RetrieveAssetAdministrationShell(aas.Identification.Id);
-            if (!alreadyExists.Success || alreadyExists.Entity == null)
-            {
-                var created = manager.CreateAssetAdministrationShell(aas);
-                if (!created.Success)
-                    return new Result(created.Success, created.Messages);
-            }
-
-            var cAAS = new ConnectedAssetAdministrationShell(manager, aas);
-            if (cAAS != null)
-            {
-                bool successForAll = (aas.SubModels as List<ISubModel>).TrueForAll(s => cAAS.CreateSubModel(s).Success);
-                if (!successForAll)
-                    return new Result(false, new List<IMessage>() { new Message(MessageType.Error, "Could not create SubModels") });
-
-                var subModel = cAAS.RetrieveSubModel(aas.SubModels[0].Identification.Id).Entity;
-                var cSubModel = new ConnectedSubModel(manager, aas, subModel);
-                if (cSubModel != null)
-                {
-                    var operation = cSubModel.RetrieveOperation(aas.SubModels[0].Operations[0].Identification.Id).Entity;
-                    var cOp = new ConnectedOperation(manager, aas, subModel, operation);
-                    if (cOp != null)
-                        handler.RegisterMethodCalledEventHandler(cSubModel, cOp, SaySomethingHandler);
-
-                    var property = cSubModel.RetrieveProperty(aas.SubModels[0].Properties[0].Identification.Id).Entity;
-                    var cProp = new ConnectedProperty(manager, aas, subModel, property);
-                    if (cProp != null)
-                    {
-                        lastWordsConnected = cProp;
-                        handler.RegisterGetPropertyValueHandler(cSubModel, cProp, LastWordsGetHandler);
-                        handler.RegisterSetPropertyValueHandler(cSubModel, cProp, LastWordsSetHandler);
-                    }
-
-                    Events = new Dictionary<string, IConnectableEvent>();
-                    foreach (var eventable in aas.SubModels[0].Events)
-                    {
-                        var @event = cSubModel.RetrieveEvent(eventable.Identification.Id).Entity;
-                        var cEv = new ConnectedEvent(manager, aas, subModel, @event);
-                        if (cEv != null)
-                        {
-                            Events.Add(eventable.Identification.Id, cEv);
-                        }
-                    }
-                    SendEvent(Events["StartupCompleted"], new StartupCompleted());
-                }
-                return new Result(true);
-            }
-            return new Result(false);
-        }
-
-        private void LastWordsSetHandler(IConnectableProperty property, IValue value)
-        {
-            LastWords = value.ToObject<string>();
-        }
-
-        private IValue LastWordsGetHandler(IConnectableProperty property)
-        {
-            var value = new ElementValue<string>(LastWords);
-            return value;
-        }
-
-        public void SendEvent(IConnectableEvent connectableEvent, IPublishableEvent publishableEvent)
-        {
-            connectableEvent.Publish(publishableEvent, 2);
-        }
-
-        public IResult Unregister(IAssetAdministrationShellRegistry registry, string aasId)
-        {
-            var result = registry.DeleteAssetAdministrationShell(aasId);
-            return result;
-        }
-
-        private OperationResult SaySomethingHandler(IConnectableOperation operation, List<IArgument> inputArguments, out List<IArgument> outputArguments)
-        {
-            if (inputArguments != null && inputArguments.Count >= 2)
-            {
-                var answer = SaySomething(inputArguments[0].Value.ToObject<string>(), inputArguments[1].Value.ToObject<string>());
-                SendEvent(Events["Spoken"], new Spoken() { Message = inputArguments[0].Value.ToObject<string>() });
-                outputArguments = new List<IArgument>();
-                outputArguments.Add(new Argument() { DataType = new DataType(DataObjectType.String, false, false), Value = new ElementValue<string>(answer) });
-
-                if(!string.IsNullOrEmpty(answer))
-                    return new OperationResult(true);
-                else
-                    return new OperationResult(false, new List<IMessage> { new Message(MessageType.Error, "The answer is null or empty") });
-
-            }
-            outputArguments = null;
-            return new OperationResult(false, new List<IMessage> { new Message(MessageType.Error, "Input arguments are null or less than two") });
-        }
-
-        public IAssetAdministrationShell GenerateAssetAdministrationShell()
-        {
-            var aas = new AssetAdministrationShell()
-            {
-                Assets = new ElementContainer<IAsset>()
-                {
-                    new Asset()
-                    {
-                        AssetKind = Kind.Instance,
-                        Identification = new Identifier("Microsoft_SAM_123", Identificator.Internal)
-                    }
-                },
-                SemanticReference = new Identifier("com.microsoft.im.SpeechRecognition", Identificator.Internal),
-                DisplayName = "Microsoft_SAM",
-                Identification = new Identifier("Microsoft_SAM", Identificator.Internal)
-            };
-           
-            var speakerSubModel = new SubModel()
-            {
-                Identification = new Identifier("speaker", Identificator.Internal),
-                SemanticReference = new Identifier("com.microsoft.fb.modules.speakerModules", Identificator.Internal),
-                DisplayName = "speaker",
-                SubModelKind = Kind.Instance,
-                Parent = aas
-            };
-
-            speakerSubModel.Properties = new ElementContainer<IPropertyDescription>
-            {
-                new PropertyDescription()
-                {
-                    Identification = new Identifier("LastWords", Identificator.Internal),
-                    DisplayName = "LastWords",
-                    DataType = new DataType(DataObjectType.String, false, false),
-                    Writable = true,
-                    Readable = true,
-                    Eventable = true,
-                    Endpoint = "http://127.0.0.1:8544",
-                    Parent = speakerSubModel
-                }
-            };
-
-            speakerSubModel.Events = new ElementContainer<IEventDescription>
-            {
-                new EventDescription()
-                {
-                    Identification = new Identifier("StartupCompleted", Identificator.Internal),
-                    DisplayName = "StartupCompleted",
-                    Parent = speakerSubModel,
-                    EntityType = EntityType.Primitive,
-                    EventCategory = "StatusEvents",
-                    EventName = "StartupCompleted"
-                },
-                new EventDescription()
-                {
-                    Identification = new Identifier("Spoken", Identificator.Internal),
-                    DisplayName = "Spoken",
-                    Parent = speakerSubModel,
-                    EntityType = EntityType.Primitive,
-                    EventCategory = "RuntimeEvents",
-                    EventName = "Spoken",
-                }
-            };
-
-            speakerSubModel.Operations = new ElementContainer<IOperationDescription>
-            {
-                new OperationDescription()
-                {
-                    Identification = new Identifier("SaySomething", Identificator.Internal),
-                    DisplayName = "SaySomething",
-                    Endpoint = "http://127.0.0.1:8544",
-                    InputParameters = new List<IParameter>()
-                    {
-                        new Parameter() { Index = 0, DataType = new DataType(DataObjectType.String, false, false), ParameterName = "Text" },
-                        new Parameter() { Index = 1, DataType = new DataType(DataObjectType.String, false, false), ParameterName = "Language"}
-                    },
-                    OutputParameters = new List<IParameter>()
-                    {
-                        new Parameter() { Index = 0, DataType =  new DataType(DataObjectType.String, false, false) }
-                    },
-                    Parent = speakerSubModel
-                }
-            };
-            aas.SubModels = new ElementContainer<ISubModel>();
-            aas.SubModels.Add(speakerSubModel);
-
-            return aas;
-        }
-
-        public string SaySomething(string text, string language)
-        {
-            PromptBuilder prompBuilder = null;
-            CultureInfo info = null;
-            if (!string.IsNullOrEmpty(language))
-            {
-                try
-                {
-                    info = CultureInfo.CreateSpecificCulture(language);
-                }
-                catch
-                {
-                    info = CultureInfo.CurrentCulture;
-                }
-            }
-            else
-            {
-                info = CultureInfo.CurrentCulture;
-            }
-
-            prompBuilder = new PromptBuilder(info);
-            prompBuilder.AppendText(text);
-            speaker.SpeakAsync(new Prompt(prompBuilder));
-            switch (language)
-            {
-                case "de-DE": language = "German";
-                    break;
-                case "en-US":
-                case "en-EN": language = "English";
-                    break;
-                default:
-                    language = "Esperando";
-                    break;
-            }
-            string answer = "I said '" + text + "' in " + language;
-
-            LastWords = answer;
-            lastWordsConnected?.SetRemoteValue(new ElementValue<string>(LastWords));
-
-            return answer;
-        }        
-    }
-}
diff --git a/sdks/csnet/Modules/Speaker/Speaker/Speaker.csproj b/sdks/csnet/Modules/Speaker/Speaker/Speaker.csproj
deleted file mode 100644
index 31ca595..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker/Speaker.csproj
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{CF6CE935-C79C-43CC-AE30-48298326794C}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Speaker</RootNamespace>
-    <AssemblyName>Speaker</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="BaSys40.API, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\BaSys40.API\bin\Debug\net461\BaSys40.API.dll</HintPath>
-    </Reference>
-    <Reference Include="BaSys40.Models, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\BaSys40.API\bin\Debug\net461\BaSys40.Models.dll</HintPath>
-    </Reference>
-    <Reference Include="BaSys40.Utils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\BaSys40.API\bin\Debug\net461\BaSys40.Utils.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Speech" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Events\Spoken.cs" />
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Speaker.cs" />
-    <Compile Include="Events\StartupCompleted.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <PackageReference Include="Newtonsoft.Json">
-      <Version>11.0.1</Version>
-    </PackageReference>
-  </ItemGroup>
-  <ItemGroup>
-    <WCFMetadata Include="Connected Services\" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PostBuildEvent>copy "$(TargetPath)" C:\Development\BaSys40\SDK\basys-sdk\BaSys40.Devices\bin\$(ConfigurationName)\Loader</PostBuildEvent>
-  </PropertyGroup>
-</Project>
\ No newline at end of file
diff --git a/sdks/csnet/Modules/Speaker/Speaker/Speaker.csproj.user b/sdks/csnet/Modules/Speaker/Speaker/Speaker.csproj.user
deleted file mode 100644
index 7937b01..0000000
--- a/sdks/csnet/Modules/Speaker/Speaker/Speaker.csproj.user
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <PublishUrlHistory>publish\</PublishUrlHistory>
-    <InstallUrlHistory />
-    <SupportUrlHistory />
-    <UpdateUrlHistory />
-    <BootstrapperUrlHistory />
-    <ErrorReportUrlHistory />
-    <FallbackCulture>en-US</FallbackCulture>
-    <VerifyUploadedFiles>false</VerifyUploadedFiles>
-  </PropertyGroup>
-</Project>
\ No newline at end of file