From 2b53a85d112adc4286e61e72373fc526bbd7d54f Mon Sep 17 00:00:00 2001
From: "fabian.peller-konrad@kit.edu" <fabian.peller-konrad@kit.edu>
Date: Thu, 29 Apr 2021 15:12:33 +0200
Subject: [PATCH] optional update

---
 source/RobotAPI/interface/aron/Aron.ice       |  17 ++-
 .../libraries/aron/core/CMakeLists.txt        |   8 ++
 source/RobotAPI/libraries/aron/core/Config.h  |   2 +
 .../codeWriter/cpp/AronCppClass.h             |   6 +-
 .../cpp/serializer/AllSerializers.h           |   1 +
 .../codeWriter/cpp/serializer/Serializer.cpp  |  31 ++++-
 .../codeWriter/cpp/serializer/Serializer.h    |  29 +++-
 .../cpp/serializer/SerializerFactory.cpp      |   1 +
 .../cpp/serializer/container/Dict.cpp         |  33 +++--
 .../cpp/serializer/container/List.cpp         |  27 ++--
 .../cpp/serializer/container/Object.cpp       |  18 +--
 .../cpp/serializer/container/Pair.cpp         |  39 ++++--
 .../cpp/serializer/container/Tuple.cpp        |  27 +++-
 .../cpp/serializer/enum/IntEnum.cpp           |  21 +--
 .../cpp/serializer/ndarray/EigenMatrix.cpp    |  18 ++-
 .../serializer/ndarray/EigenQuaternion.cpp    |  18 ++-
 .../cpp/serializer/ndarray/IVTCByteImage.cpp  |  21 +--
 .../cpp/serializer/ndarray/NDArray.cpp        |  99 ++++++++++++++
 .../cpp/serializer/ndarray/NDArray.h          |  69 ++++++++++
 .../cpp/serializer/ndarray/OpenCVMat.cpp      |  29 ++--
 .../cpp/serializer/ndarray/Orientation.cpp    |  16 ++-
 .../cpp/serializer/ndarray/PCLPointCloud.cpp  |  18 ++-
 .../cpp/serializer/ndarray/Pose.cpp           |  18 ++-
 .../cpp/serializer/ndarray/Position.cpp       |  18 ++-
 .../cpp/serializer/primitive/Primitive.cpp    |  14 +-
 .../cpp/serializer/toplevel/IntEnumClass.cpp  |   8 +-
 .../cpp/serializer/toplevel/ObjectClass.cpp   |  47 +++++--
 .../core/codegenerator/typeReader/xml/Data.h  |  15 ++
 .../codegenerator/typeReader/xml/Reader.cpp   |   2 -
 .../typeReader/xml/ReaderFactory.cpp          |  30 +++-
 source/RobotAPI/libraries/aron/core/io/Data.h |   4 +
 .../libraries/aron/core/io/dataIO/Reader.cpp  |  67 +++++++++
 .../libraries/aron/core/io/dataIO/Reader.h    |  10 +-
 .../libraries/aron/core/io/dataIO/Writer.cpp  |  21 +++
 .../aron/core/io/dataIO/reader/ReaderToken.h  |  11 +-
 .../reader/navigator/NavigatorReader.cpp      |   9 +-
 .../dataIO/reader/navigator/NavigatorReader.h |   2 +-
 .../nlohmannJSON/NlohmannJSONReader.cpp       |   9 +-
 .../reader/nlohmannJSON/NlohmannJSONReader.h  |   2 +-
 .../libraries/aron/core/io/typeIO/Reader.cpp  |  21 +++
 .../libraries/aron/core/io/typeIO/Reader.h    | 126 ++++++++++++++---
 .../libraries/aron/core/io/typeIO/Writer.cpp  |  21 +++
 .../libraries/aron/core/io/typeIO/Writer.h    | 121 +++++++++++++---
 .../core/io/typeIO/converter/Converter.cpp    |  80 +++++------
 .../reader/navigator/NavigatorReader.cpp      |  91 ++++++------
 .../typeIO/reader/navigator/NavigatorReader.h |  43 +++---
 .../nlohmannJSON/NlohmannJSONReader.cpp       | 103 ++++++++------
 .../reader/nlohmannJSON/NlohmannJSONReader.h  |  40 +++---
 .../aron/core/io/typeIO/visitor/Visitor.cpp   |  73 +++++-----
 .../writer/navigator/NavigatorWriter.cpp      |  84 +++++++-----
 .../typeIO/writer/navigator/NavigatorWriter.h |  40 +++---
 .../nlohmannJSON/NlohmannJSONWriter.cpp       | 101 +++++++++-----
 .../writer/nlohmannJSON/NlohmannJSONWriter.h  |  40 +++---
 .../core/navigator/data/complex/NDArray.cpp   |   1 +
 .../aron/core/navigator/type/AllNavigators.h  |   1 +
 .../aron/core/navigator/type/Navigator.cpp    |  73 ----------
 .../aron/core/navigator/type/Navigator.h      |   3 +
 .../core/navigator/type/container/Dict.cpp    |  15 +-
 .../aron/core/navigator/type/container/Dict.h |  11 +-
 .../core/navigator/type/container/List.cpp    |  15 +-
 .../aron/core/navigator/type/container/List.h |   3 +
 .../core/navigator/type/container/Object.cpp  |  14 +-
 .../core/navigator/type/container/Object.h    |   3 +
 .../core/navigator/type/container/Pair.cpp    |  18 ++-
 .../aron/core/navigator/type/container/Pair.h |   3 +
 .../core/navigator/type/container/Tuple.cpp   |  14 +-
 .../core/navigator/type/container/Tuple.h     |   3 +
 .../aron/core/navigator/type/enum/IntEnum.cpp |  13 +-
 .../aron/core/navigator/type/enum/IntEnum.h   |   3 +
 .../navigator/type/ndarray/EigenMatrix.cpp    |  18 ++-
 .../core/navigator/type/ndarray/EigenMatrix.h |   3 +
 .../type/ndarray/EigenQuaternion.cpp          |  15 +-
 .../navigator/type/ndarray/EigenQuaternion.h  |   3 +
 .../navigator/type/ndarray/IVTCByteImage.cpp  |  15 +-
 .../navigator/type/ndarray/IVTCByteImage.h    |   3 +
 .../core/navigator/type/ndarray/NDArray.cpp   | 129 ++++++++++++++++++
 .../core/navigator/type/ndarray/NDArray.h     |  77 +++++++++++
 .../core/navigator/type/ndarray/OpenCVMat.cpp |  15 +-
 .../core/navigator/type/ndarray/OpenCVMat.h   |   3 +
 .../navigator/type/ndarray/Orientation.cpp    |  13 +-
 .../core/navigator/type/ndarray/Orientation.h |   3 +
 .../navigator/type/ndarray/PCLPointCloud.cpp  |  15 +-
 .../navigator/type/ndarray/PCLPointCloud.h    |   3 +
 .../aron/core/navigator/type/ndarray/Pose.cpp |  13 +-
 .../aron/core/navigator/type/ndarray/Pose.h   |   3 +
 .../core/navigator/type/ndarray/Position.cpp  |  13 +-
 .../core/navigator/type/ndarray/Position.h    |   3 +
 .../navigator/type/primitive/Primitive.cpp    |  13 +-
 .../core/navigator/type/primitive/Primitive.h |   3 +
 .../libraries/aron/core/test/CMakeLists.txt   |   1 +
 .../libraries/aron/core/test/aronTest.cpp     |   9 ++
 .../aron/core/test/xmls/OptionalTest.xml      |  56 ++++++++
 92 files changed, 1812 insertions(+), 629 deletions(-)
 create mode 100644 source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h
 create mode 100644 source/RobotAPI/libraries/aron/core/io/dataIO/Reader.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/io/dataIO/Writer.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/io/typeIO/Reader.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/io/typeIO/Writer.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.h
 create mode 100644 source/RobotAPI/libraries/aron/core/test/xmls/OptionalTest.xml

diff --git a/source/RobotAPI/interface/aron/Aron.ice b/source/RobotAPI/interface/aron/Aron.ice
index d01b0d60a..74bb97987 100644
--- a/source/RobotAPI/interface/aron/Aron.ice
+++ b/source/RobotAPI/interface/aron/Aron.ice
@@ -43,19 +43,22 @@ module armarx
          ************************/
         module type
         {
-            class AronType { };
+            class AronType {
+                bool is_optional = false; // Every type can be optional or not
+            }
             sequence<AronType> AronTypeList;
             dictionary<string, AronType> AronTypeDict;
 
             // Container types
-            class AronList extends AronType { AronType acceptedType; };
-            class AronTuple extends AronType { AronTypeList elementTypes; };
-            class AronPair extends AronType { AronType acceptedType1; AronType acceptedType2; };
-            class AronObject extends AronType { AronObject parent; string objectName; AronTypeDict elementTypes; };
-            class AronDict extends AronType { AronType acceptedType; };
+            class AronList extends AronType { AronType acceptedType; }
+            class AronTuple extends AronType { AronTypeList elementTypes; }
+            class AronPair extends AronType { AronType acceptedType1; AronType acceptedType2; }
+            class AronObject extends AronType { AronObject parent; string objectName; AronTypeDict elementTypes; }
+            class AronDict extends AronType { AronType acceptedType; }
 
             // Complex Types (serialize to ndarray)
-            class AronEigenMatrix extends AronType { AronIntSequence dimensions; string typeName; };
+            class AronNDArray extends AronType { AronIntSequence dimensions; int elementSize; string typeName; }
+            class AronEigenMatrix extends AronType { AronIntSequence dimensions; string typeName; }
             class AronEigenQuaternion extends AronType { string typeName; }
             class AronIVTCByteImage extends AronType { int width; int height; string typeName; }
             class AronOpenCVMat extends AronType { AronIntSequence dimensions; string typeName; }
diff --git a/source/RobotAPI/libraries/aron/core/CMakeLists.txt b/source/RobotAPI/libraries/aron/core/CMakeLists.txt
index d3239b7e9..c023cc567 100644
--- a/source/RobotAPI/libraries/aron/core/CMakeLists.txt
+++ b/source/RobotAPI/libraries/aron/core/CMakeLists.txt
@@ -43,6 +43,7 @@ set(LIB_FILES
     navigator/type/container/Dict.cpp
     navigator/type/container/Tuple.cpp
     navigator/type/container/Pair.cpp
+    navigator/type/ndarray/NDArray.cpp
     navigator/type/ndarray/EigenMatrix.cpp
     navigator/type/ndarray/EigenQuaternion.cpp
     navigator/type/ndarray/IVTCByteImage.cpp
@@ -58,18 +59,22 @@ set(LIB_FILES
     navigator/visitors/DataVisitor.cpp
     navigator/visitors/TypedDataVisitor.cpp
 
+    io/dataIO/Writer.cpp
     io/dataIO/writer/navigator/NavigatorWriter.cpp
     io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
 
+    io/dataIO/Reader.cpp
     io/dataIO/reader/navigator/NavigatorReader.cpp
     io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
 
     io/dataIO/visitor/Visitor.cpp
     io/dataIO/converter/Converter.cpp
 
+    io/typeIO/Writer.cpp
     io/typeIO/writer/navigator/NavigatorWriter.cpp
     io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
 
+    io/typeIO/Reader.cpp
     io/typeIO/reader/navigator/NavigatorReader.cpp
     io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
 
@@ -85,6 +90,7 @@ set(LIB_FILES
     codegenerator/codeWriter/cpp/serializer/container/Object.cpp
     codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp
     codegenerator/codeWriter/cpp/serializer/container/Pair.cpp
+    codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp
     codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp
     codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp
     codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp
@@ -130,6 +136,7 @@ set(LIB_HEADERS
     navigator/type/container/Dict.h
     navigator/type/container/Tuple.h
     navigator/type/container/Pair.h
+    navigator/type/ndarray/NDArray.h
     navigator/type/ndarray/EigenMatrix.h
     navigator/type/ndarray/EigenQuaternion.h
     navigator/type/ndarray/IVTCByteImage.h
@@ -200,6 +207,7 @@ set(LIB_HEADERS
     codegenerator/codeWriter/cpp/serializer/container/Object.h
     codegenerator/codeWriter/cpp/serializer/container/Tuple.h
     codegenerator/codeWriter/cpp/serializer/container/Pair.h
+    codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h
     codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.h
     codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.h
     codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.h
diff --git a/source/RobotAPI/libraries/aron/core/Config.h b/source/RobotAPI/libraries/aron/core/Config.h
index fc05237a2..7db99c2f1 100644
--- a/source/RobotAPI/libraries/aron/core/Config.h
+++ b/source/RobotAPI/libraries/aron/core/Config.h
@@ -86,6 +86,7 @@ namespace armarx
 
 // All complex types go here
 #define HANDLE_NDARRAY_TYPES \
+    RUN_ARON_MACRO(NDArray, ndarray, NDARRAY) \
     RUN_ARON_MACRO(EigenMatrix, eigenmatrix, EIGEN_MATRIX) \
     RUN_ARON_MACRO(EigenQuaternion, eigenquaternion, EIGEN_QUATERNION) \
     RUN_ARON_MACRO(IVTCByteImage, ivtcbyteimage, IVT_CBYTE_IMAGE) \
@@ -164,6 +165,7 @@ namespace armarx
     RUN_ARON_MACRO(Dict, dict, DICT, Dict, dict, DICT)
 
 #define HANDLE_COMPLEX_CORRESPONDING \
+    RUN_ARON_MACRO(NDArray, ndarray, NDARRAY, NDArray, ndarray, NDARRAY) \
     RUN_ARON_MACRO(EigenMatrix, eigenmatrix, EIGEN_MATRIX, NDArray, ndarray, NDARRAY) \
     RUN_ARON_MACRO(EigenQuaternion, eigenmatrix, EIGEN_MATRIX, NDArray, ndarray, NDARRAY) \
     RUN_ARON_MACRO(IVTCByteImage, ivtcbyteimage, IVT_CBYTE_IMAGE, NDArray, ndarray, NDARRAY) \
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h
index 7098b08c6..a95dce2ca 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h
@@ -51,10 +51,6 @@ namespace armarx::aron::cppcodegenerator
         virtual void initialize() = 0;
         virtual void read(armarx::aron::dataIO::ReaderInterface& r) = 0;
         virtual void write(armarx::aron::dataIO::WriterInterface& w) const = 0;
-        virtual void writeCurrentType(armarx::aron::typeIO::WriterInterface& w) const = 0;
-        static void writeType(armarx::aron::typeIO::WriterInterface& w)
-        {
-            throw error::AronException("AronCppClass", "writeType", "You are not allowed to call this method directly. Each class must inheriting from AronCppClass must implement this static method!");
-        };
+        virtual void writeCurrentType(armarx::aron::typeIO::WriterInterface& w, bool type_is_optional = false) const = 0;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/AllSerializers.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/AllSerializers.h
index d4c7f75c8..20c5ab2be 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/AllSerializers.h
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/AllSerializers.h
@@ -5,6 +5,7 @@
 #include "container/Dict.h"
 #include "container/Tuple.h"
 #include "container/Pair.h"
+#include "ndarray/NDArray.h"
 #include "ndarray/EigenMatrix.h"
 #include "ndarray/EigenQuaternion.h"
 #include "ndarray/IVTCByteImage.h"
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.cpp
index 3b18a9f8c..3a8e511cd 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.cpp
@@ -75,6 +75,15 @@ namespace armarx::aron::cppcodegenerator
         return ret;
     }
 
+    std::string Serializer::ResolveAccessor(const std::string& s, const typenavigator::NavigatorPtr& t)
+    {
+        if (t->isOptional())
+        {
+            return s + ".value()";
+        }
+        return s;
+    }
+
     std::string Serializer::EscapeAccessor(const std::string& accessor)
     {
         std::string escaped_accessor = accessor;
@@ -117,8 +126,8 @@ namespace armarx::aron::cppcodegenerator
     }
 
     // constructors
-    Serializer::Serializer(const std::string& cppName, const std::string& aronDataTypename, const std::string& aronTypeTypename, bool is_ptr) :
-        is_ptr(is_ptr),
+    Serializer::Serializer(const std::string& cppName, const std::string& aronDataTypename, const std::string& aronTypeTypename, SerializerAccessType accessType) :
+        accessType(accessType),
         cppTypename(cppName),
         aronDataTypename(aronDataTypename),
         aronTypeTypename(aronTypeTypename)
@@ -133,7 +142,17 @@ namespace armarx::aron::cppcodegenerator
 
     std::string Serializer::getFullCppTypename() const
     {
-        return is_ptr ? "std::shared_ptr<" + cppTypename + ">" : cppTypename;
+        switch (accessType)
+        {
+            case SerializerAccessType::eDIRECT:
+                return cppTypename;
+            case SerializerAccessType::ePTR:
+                return "std::shared_ptr<" + cppTypename + ">";
+            case SerializerAccessType::eOPTIONAL:
+                return "std::optional<" + cppTypename + ">";
+            default:
+                throw error::AronException("Serializer", "getFullCppTypename", "Received unknown SerializerAccessType");
+        }
     }
 
     std::string Serializer::getAronDataTypename() const
@@ -196,10 +215,10 @@ namespace armarx::aron::cppcodegenerator
     CppMethodPtr Serializer::toWriteInitialTypeMethod() const
     {
         std::stringstream doc;
-        doc << "@brief writeType() - This method returns a new type from the class structure using a type writer implementation. This function is static. \n";
+        doc << "@brief writeInitialType() - This method returns a new type from the class structure using a type writer implementation. This function is static. \n";
         doc << "@return - the result of the writer implementation";
 
-        CppMethodPtr m = CppMethodPtr(new CppMethod("static void writeInitialType(armarx::aron::typeIO::WriterInterface& w)", doc.str()));
+        CppMethodPtr m = CppMethodPtr(new CppMethod("static void writeInitialType(armarx::aron::typeIO::WriterInterface& w, bool type_is_optional = false)", doc.str()));
         CppBlockPtr b = this->getWriteInitialTypeBlock("");
         m->setBlock(b);
         return m;
@@ -211,7 +230,7 @@ namespace armarx::aron::cppcodegenerator
         doc << "@brief writeType() - This method returns a new type from the current class structure using a type writer implementation. \n";
         doc << "@return - the result of the writer implementation";
 
-        CppMethodPtr m = CppMethodPtr(new CppMethod("void writeCurrentType(armarx::aron::typeIO::WriterInterface& w) const override", doc.str()));
+        CppMethodPtr m = CppMethodPtr(new CppMethod("void writeCurrentType(armarx::aron::typeIO::WriterInterface& w, bool type_is_optional = false) const override", doc.str()));
         CppBlockPtr b = this->getWriteCurrentTypeBlock("");
         m->setBlock(b);
         return m;
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h
index 9d115fb42..9e05d78b1 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h
@@ -58,8 +58,15 @@ namespace armarx::aron::cppcodegenerator
         using PointerType = SerializerPtr;
 
     public:
+        enum class SerializerAccessType
+        {
+            eDIRECT,
+            ePTR,
+            eOPTIONAL
+        };
+
         // constructors
-        Serializer(const std::string& cppName, const std::string& aronDataTypename, const std::string& aronTypeTypename, bool is_ptr = false);
+        Serializer(const std::string& cppName, const std::string& aronDataTypename, const std::string& aronTypeTypename, SerializerAccessType = SerializerAccessType::eDIRECT);
 
         // public member methods
         std::string getCoreCppTypename() const;
@@ -109,6 +116,8 @@ namespace armarx::aron::cppcodegenerator
         // static methods
         static std::string ResolveCppTypename(const std::string&);
         static std::vector<std::string> ResolveCppTypenames(const std::vector<std::string>&);
+
+        static std::string ResolveAccessor(const std::string&, const typenavigator::NavigatorPtr&);
         static std::string EscapeAccessor(const std::string&);
         static std::string UnescapeAccessor(const std::string&);
 
@@ -117,6 +126,22 @@ namespace armarx::aron::cppcodegenerator
 
         static SerializerPtr FromAronTypeNaviagtorPtr(const typenavigator::NavigatorPtr&);
 
+    protected:
+        std::string nextEl() const
+        {
+            switch (accessType)
+            {
+                case SerializerAccessType::eDIRECT:
+                    return ".";
+                case SerializerAccessType::ePTR:
+                    return "->";
+                case SerializerAccessType::eOPTIONAL:
+                    return "->";
+                default:
+                    throw error::AronException("Serializer", "getFullCppTypename", "Received unknown SerializerAccessType");
+            }
+        }
+
     private:
         // members
         const static std::string ARON_DATA_NAME;
@@ -130,7 +155,7 @@ namespace armarx::aron::cppcodegenerator
 
         static const SerializerFactoryPtr FACTORY;
 
-        bool is_ptr;
+        SerializerAccessType accessType;
         std::string cppTypename;
         std::string aronDataTypename;
         std::string aronTypeTypename;
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/SerializerFactory.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/SerializerFactory.cpp
index 15d698675..af791c3f8 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/SerializerFactory.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/SerializerFactory.cpp
@@ -41,6 +41,7 @@ namespace armarx::aron::cppcodegenerator
             {type::Descriptor::eList, SerializerFactoryPtr(new ListSerializerFactory())},
             {type::Descriptor::eTuple, SerializerFactoryPtr(new TupleSerializerFactory())},
             {type::Descriptor::ePair, SerializerFactoryPtr(new PairSerializerFactory())},
+            {type::Descriptor::eNDArray, SerializerFactoryPtr(new NDArraySerializerFactory())},
             {type::Descriptor::eEigenMatrix, SerializerFactoryPtr(new EigenMatrixSerializerFactory())},
             {type::Descriptor::eEigenQuaternion, SerializerFactoryPtr(new EigenQuaternionSerializerFactory())},
             {type::Descriptor::eIVTCByteImage, SerializerFactoryPtr(new IVTCByteImageSerializerFactory())},
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.cpp
index 7431b8ee2..a34a8c5e1 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.cpp
@@ -28,9 +28,12 @@
 namespace armarx::aron::cppcodegenerator::serializer
 {
     // constructors
-    DictSerializer::DictSerializer(const typenavigator::DictNavigatorPtr& n) :
-        Serializer("std::map<std::string, " + FromAronTypeNaviagtorPtr(n->getAcceptedType())->getFullCppTypename() + ">", simox::meta::get_type_name(typeid(data::AronDict)), simox::meta::get_type_name(typeid(type::AronDict))),
-        navigator(n)
+    DictSerializer::DictSerializer(const typenavigator::DictNavigatorPtr& e) :
+        Serializer("std::map<std::string, " + FromAronTypeNaviagtorPtr(e->getAcceptedType())->getFullCppTypename() + ">",
+                   simox::meta::get_type_name(typeid(data::AronDict)),
+                   simox::meta::get_type_name(typeid(type::AronDict)),
+                   (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
+        navigator(e)
     {
 
     }
@@ -56,7 +59,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr DictSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".clear();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
@@ -70,7 +73,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr DictSerializer::getWriteInitialTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartDict();");
+        b->addLine("w.writeStartDict({" + std::string(navigator->isOptional() ? "true" : "false") + "});");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         std::string accessor_iterator = escaped_accessor + DICT_ITERATOR_ACCESSOR;
@@ -85,7 +88,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr DictSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartDict();");
+        b->addLine("w.writeStartDict({" + std::string(navigator->isOptional() ? "true" : "false") + "});");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         std::string accessor_iterator = escaped_accessor + DICT_ITERATOR_ACCESSOR;
@@ -99,21 +102,21 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr DictSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr b = std::make_shared<CppBlock>();
         b->addLine("w.writeStartDict();");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         std::string accessor_iterator_key = escaped_accessor + DICT_KEY_ACCESSOR;
         std::string accessor_iterator_val = escaped_accessor + DICT_VALUE_ACCESSOR;
+        std::string resolved_accessor = ResolveAccessor(accessor, navigator);
 
-        b->addLine("for (const auto& [" + accessor_iterator_key + ", " + accessor_iterator_val + "] : " + accessor + ") ");
+        b->addLine("for (const auto& [" + accessor_iterator_key + ", " + accessor_iterator_val + "] : " + resolved_accessor + ") ");
 
         auto type_s = FromAronTypeNaviagtorPtr(navigator->getAcceptedType());
         CppBlockPtr b2 = CppBlockPtr(new CppBlock());
         b2->addLine("w.writeKey(" + accessor_iterator_key + ");");
         b2 = CppBlock::MergeBlocks(b2, type_s->getWriteBlock(accessor_iterator_val));
         b->addBlock(b2);
-
         b->addLine("w.writeEndDict();");
         return b;
     }
@@ -121,7 +124,15 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr DictSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".clear();");
+        if (navigator->isOptional())
+        {
+            b->addLine(accessor + ".emplace();");
+        }
+        else
+        {
+            b->addLine(accessor + " = {};");
+        }
+
         b->addLine("r.readStartDict();");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
@@ -135,7 +146,7 @@ namespace armarx::aron::cppcodegenerator::serializer
         b2->addLine("std::string " + accessor_iterator_key + " = r.readKey();");
         b2->addLine(type_s->getFullCppTypename() + " " + accessor_iterator + ";");
         b2 = CppBlock::MergeBlocks(b2, type_s->getReadBlock(accessor_iterator));
-        b2->addLine(accessor + "[" + accessor_iterator_key + "] = " + accessor_iterator + ";");
+        b2->addLine(accessor + nextEl() + "insert({" + accessor_iterator_key + ", " + accessor_iterator + "});");
 
         b->addBlock(b2);
         return b;
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/List.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/List.cpp
index 2e4f924eb..56dbe6ed8 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/List.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/List.cpp
@@ -28,7 +28,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 {
     // constructors
     ListSerializer::ListSerializer(const typenavigator::ListNavigatorPtr& e) :
-        Serializer("std::vector<" + FromAronTypeNaviagtorPtr(e->getAcceptedType())->getFullCppTypename() + ">", simox::meta::get_type_name(typeid(data::AronList)), simox::meta::get_type_name(typeid(type::AronList))),
+        Serializer("std::vector<" + FromAronTypeNaviagtorPtr(e->getAcceptedType())->getFullCppTypename() + ">",
+                   simox::meta::get_type_name(typeid(data::AronList)),
+                   simox::meta::get_type_name(typeid(type::AronList)),
+                   (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(e)
     {
 
@@ -54,7 +57,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr ListSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".clear();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
@@ -68,7 +71,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr ListSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartList();");
+        b->addLine("w.writeStartList({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         auto type_s = FromAronTypeNaviagtorPtr(typenavigator->getAcceptedType());
 
         CppBlockPtr b2 = type_s->getWriteInitialTypeBlock(type_s->getFullCppTypename());
@@ -81,7 +84,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr ListSerializer::getWriteCurrentTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartList();");
+        b->addLine("w.writeStartList({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         auto type_s = FromAronTypeNaviagtorPtr(typenavigator->getAcceptedType());
 
         CppBlockPtr b2 = type_s->getWriteInitialTypeBlock(type_s->getFullCppTypename()); // TODO: think about having a better solution not ignoting the current type
@@ -100,8 +103,8 @@ namespace armarx::aron::cppcodegenerator::serializer
         std::string accessor_iterator = escaped_accessor + LIST_ITERATOR_ACCESSOR;
 
         auto type_s = FromAronTypeNaviagtorPtr(typenavigator->getAcceptedType());
-        b->addLine("for(unsigned int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + ".size(); ++" + accessor_iterator + ")");
-        CppBlockPtr b2 = type_s->getWriteBlock(accessor + "[" + accessor_iterator + "]");
+        b->addLine("for(unsigned int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + nextEl() + "size(); ++" + accessor_iterator + ")");
+        CppBlockPtr b2 = type_s->getWriteBlock(accessor + nextEl() + "at(" + accessor_iterator + ")");
         b->addBlock(b2);
         b->addLine("w.writeEndList();");
         return b;
@@ -110,7 +113,15 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr ListSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".clear();");
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + ".emplace();");
+        }
+        else
+        {
+            b->addLine(accessor + " = {};");
+        }
+
         b->addLine("r.readStartList();");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
@@ -122,7 +133,7 @@ namespace armarx::aron::cppcodegenerator::serializer
         auto type_s = FromAronTypeNaviagtorPtr(typenavigator->getAcceptedType());
         b2->addLine(type_s->getFullCppTypename() + " " + accessor_iterator + ";");
         b2 = CppBlock::MergeBlocks(b2, type_s->getReadBlock(accessor_iterator));
-        b2->addLine(accessor + ".push_back(" + accessor_iterator + ");");
+        b2->addLine(accessor + nextEl() + "push_back(" + accessor_iterator + ");");
 
         b->addBlock(b2);
         return b;
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.cpp
index 7dbfa3665..855fd6682 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.cpp
@@ -29,10 +29,12 @@ namespace armarx::aron::cppcodegenerator::serializer
 {
     // constructors
     ObjectSerializer::ObjectSerializer(const typenavigator::ObjectNavigatorPtr& e) :
-        Serializer(e->getObjectName(), simox::meta::get_type_name(typeid(data::AronDict)), simox::meta::get_type_name(typeid(type::AronObject))),
+        Serializer(e->getObjectName(),
+                   simox::meta::get_type_name(typeid(data::AronDict)),
+                   simox::meta::get_type_name(typeid(type::AronObject)),
+                   (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         navigator(e)
     {
-        //AddObjectTypeToAllObjectTypesList(ObjectNavigatorPtr(this));
     }
 
     std::vector<CppFieldPtr> ObjectSerializer::getPublicVariableDeclarations(const std::string& name) const
@@ -55,42 +57,42 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr ObjectSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".reset();");
+        b->addLine(accessor + nextEl() + "reset();");
         return b;
     }
 
     CppBlockPtr ObjectSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".initialize();");
+        b->addLine(accessor + nextEl() + "initialize();");
         return b;
     }
 
     CppBlockPtr ObjectSerializer::getWriteInitialTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + "::writeInitialType(w);");
+        b->addLine(accessor + "::writeInitialType(w, " + std::string(navigator->isOptional() ? "true" : "false") + ");");
         return b;
     }
 
     CppBlockPtr ObjectSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".writeCurrentType(w);");
+        b->addLine(accessor + nextEl() + "writeCurrentType(w, " + std::string(navigator->isOptional() ? "true" : "false") + ");");
         return b;
     }
 
     CppBlockPtr ObjectSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".write(w);");
+        b->addLine(accessor + nextEl() + "write(w);");
         return b;
     }
 
     CppBlockPtr ObjectSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".read(r);");
+        b->addLine(accessor + nextEl() + "read(r);");
         return b;
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Pair.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Pair.cpp
index 6981f8625..9981bb644 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Pair.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Pair.cpp
@@ -28,7 +28,10 @@
 namespace armarx::aron::cppcodegenerator::serializer
 {
     PairSerializer::PairSerializer(const typenavigator::PairNavigatorPtr& e) :
-        Serializer("std::pair<" + ExtractCppTypename(e->getFirstAcceptedType()) + ", " + ExtractCppTypename(e->getSecondAcceptedType()) + ">", simox::meta::get_type_name(typeid(data::AronList)), simox::meta::get_type_name(typeid(type::AronPair))),
+        Serializer("std::pair<" + ExtractCppTypename(e->getFirstAcceptedType()) + ", " + ExtractCppTypename(e->getSecondAcceptedType()) + ">",
+                   simox::meta::get_type_name(typeid(data::AronList)),
+                   simox::meta::get_type_name(typeid(type::AronPair)),
+                   (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(e)
     {
 
@@ -56,11 +59,11 @@ namespace armarx::aron::cppcodegenerator::serializer
         CppBlockPtr b = CppBlockPtr(new CppBlock());
 
         auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
-        CppBlockPtr b21 = child_s1->getInitializeBlock(accessor + ".first");
+        CppBlockPtr b21 = child_s1->getInitializeBlock(accessor + nextEl() + "first");
         b->appendBlock(b21);
 
         auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
-        CppBlockPtr b22 = child_s2->getInitializeBlock(accessor + ".second");
+        CppBlockPtr b22 = child_s2->getInitializeBlock(accessor + nextEl() + "second");
         b->appendBlock(b22);
 
         return b;
@@ -69,7 +72,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PairSerializer::getWriteInitialTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartPair();");
+        b->addLine("w.writeStartPair({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
 
@@ -92,7 +95,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PairSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartPair();");
+        b->addLine("w.writeStartPair({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
 
@@ -117,11 +120,11 @@ namespace armarx::aron::cppcodegenerator::serializer
         CppBlockPtr b = CppBlockPtr(new CppBlock());
 
         auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
-        CppBlockPtr b21 = child_s1->getResetBlock(accessor + ".first");
+        CppBlockPtr b21 = child_s1->getResetBlock(accessor + nextEl() + "first");
         b->appendBlock(b21);
 
         auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
-        CppBlockPtr b22 = child_s2->getResetBlock(accessor + ".second");
+        CppBlockPtr b22 = child_s2->getResetBlock(accessor + nextEl() + "second");
         b->appendBlock(b22);
 
         return b;
@@ -132,12 +135,14 @@ namespace armarx::aron::cppcodegenerator::serializer
         CppBlockPtr b = CppBlockPtr(new CppBlock());
         b->addLine("w.writeStartList();");
 
+        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+
         auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
-        CppBlockPtr b21 = child_s1->getWriteBlock(accessor + ".first");
+        CppBlockPtr b21 = child_s1->getWriteBlock(resolved_accessor + nextEl() + "first");
         b->appendBlock(b21);
 
         auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
-        CppBlockPtr b22 = child_s2->getWriteBlock(accessor + ".second");
+        CppBlockPtr b22 = child_s2->getWriteBlock(resolved_accessor + nextEl() + "second");
         b->appendBlock(b22);
 
         b->addLine("w.writeEndList();");
@@ -147,15 +152,25 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PairSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = {};");
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + ".emplace();");
+        }
+        else
+        {
+            b->addLine(accessor + " = {};");
+        }
+
         b->addLine("r.readStartList();");
 
+        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+
         auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
-        CppBlockPtr b21 = child_s1->getReadBlock(accessor + ".first");
+        CppBlockPtr b21 = child_s1->getReadBlock(resolved_accessor + nextEl() + "first");
         b->appendBlock(b21);
 
         auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
-        CppBlockPtr b22 = child_s2->getReadBlock(accessor + ".second");
+        CppBlockPtr b22 = child_s2->getReadBlock(resolved_accessor + nextEl() + "second");
         b->appendBlock(b22);
 
         b->addLine("r.readEndList();");
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp
index b83f2cd9e..7643ef634 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp
@@ -28,7 +28,10 @@
 namespace armarx::aron::cppcodegenerator::serializer
 {
     TupleSerializer::TupleSerializer(const typenavigator::TupleNavigatorPtr& e) :
-        Serializer("std::tuple<" + simox::alg::join(ExtractCppTypenames(e->getAcceptedTypes()), ", ") + ">", simox::meta::get_type_name(typeid(data::AronList)), simox::meta::get_type_name(typeid(type::AronTuple))),
+        Serializer("std::tuple<" + simox::alg::join(ExtractCppTypenames(e->getAcceptedTypes()), ", ") + ">",
+                   simox::meta::get_type_name(typeid(data::AronList)),
+                   simox::meta::get_type_name(typeid(type::AronTuple)),
+                   (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(e)
     {
 
@@ -68,7 +71,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr TupleSerializer::getWriteInitialTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartTuple();");
+        b->addLine("w.writeStartTuple({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         unsigned int i = 0;
@@ -87,7 +90,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr TupleSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartTuple();");
+        b->addLine("w.writeStartTuple({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         unsigned int i = 0;
@@ -122,11 +125,13 @@ namespace armarx::aron::cppcodegenerator::serializer
         CppBlockPtr b = CppBlockPtr(new CppBlock());
         b->addLine("w.writeStartList();");
 
+        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+
         unsigned int i = 0;
         for (const auto& type : typenavigator->getAcceptedTypes())
         {
             auto type_s = FromAronTypeNaviagtorPtr(type);
-            CppBlockPtr b2 = type_s->getWriteBlock("std::get<" + std::to_string(i++) + ">(" + accessor + ")");
+            CppBlockPtr b2 = type_s->getWriteBlock("std::get<" + std::to_string(i++) + ">(" + resolved_accessor + ")");
             b->appendBlock(b2);
         }
         b->addLine("w.writeEndList();");
@@ -136,14 +141,24 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr TupleSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = {};");
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + ".emplace();");
+        }
+        else
+        {
+            b->addLine(accessor + " = {};");
+        }
+
         b->addLine("r.readStartList();");
 
+        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+
         unsigned int i = 0;
         for (const auto& type : typenavigator->getAcceptedTypes())
         {
             auto type_s = FromAronTypeNaviagtorPtr(type);
-            CppBlockPtr b2 = type_s->getReadBlock("std::get<" + std::to_string(i++) + ">(" + accessor + ")");
+            CppBlockPtr b2 = type_s->getReadBlock("std::get<" + std::to_string(i++) + ">(" + resolved_accessor + ")");
             b->appendBlock(b2);
         }
         b->addLine("r.readEndList();");
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.cpp
index a7ed2ec33..f0c1a3ff0 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.cpp
@@ -27,9 +27,12 @@
 namespace armarx::aron::cppcodegenerator::serializer
 {
     // constructors
-    IntEnumSerializer::IntEnumSerializer(const typenavigator::IntEnumNavigatorPtr& n) :
-        Serializer(n->getEnumName(), simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronIntEnum))),
-        navigator(n)
+    IntEnumSerializer::IntEnumSerializer(const typenavigator::IntEnumNavigatorPtr& e) :
+        Serializer(e->getEnumName(),
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronIntEnum)),
+                   (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
+        navigator(e)
     {
     }
 
@@ -53,42 +56,42 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr IntEnumSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".reset();");
+        b->addLine(accessor + nextEl() + "reset();");
         return b;
     }
 
     CppBlockPtr IntEnumSerializer::getWriteInitialTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + "::writeInitialType(w);");
+        b->addLine(accessor + "::writeInitialType(w, " + std::string(navigator->isOptional() ? "true" : "false") + ");");
         return b;
     }
 
     CppBlockPtr IntEnumSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".writeCurrentType(w);");
+        b->addLine(accessor + nextEl() + "writeCurrentType(w, " + std::string(navigator->isOptional() ? "true" : "false") + ");");
         return b;
     }
 
     CppBlockPtr IntEnumSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".initialize();");
+        b->addLine(accessor + nextEl() + "initialize();");
         return b;
     }
 
     CppBlockPtr IntEnumSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".write(w);");
+        b->addLine(accessor + nextEl() + "write(w);");
         return b;
     }
 
     CppBlockPtr IntEnumSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + ".read(r);");
+        b->addLine(accessor + nextEl() + "read(r);");
         return b;
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp
index 9bb5203eb..9c5dafcaf 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp
@@ -40,7 +40,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     // constructors
     EigenMatrixSerializer::EigenMatrixSerializer(const typenavigator::EigenMatrixNavigatorPtr& n) :
-        Serializer("Eigen::Matrix<" + ACCEPTED_TYPES.at(n->getTypename()).first + ", " + std::to_string(n->getRows()) + ", " + std::to_string(n->getCols()) + ">", simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronEigenMatrix))),
+        Serializer("Eigen::Matrix<" + ACCEPTED_TYPES.at(n->getTypename()).first + ", " + std::to_string(n->getRows()) + ", " + std::to_string(n->getCols()) + ">",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronEigenMatrix)),
+                   (n->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(n)
     {
     }
@@ -72,28 +75,29 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr EigenMatrixSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeEigenMatrix({" + simox::alg::to_string<int>(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writeEigenMatrix({{" + simox::alg::to_string<int>(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr EigenMatrixSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeEigenMatrix({" + accessor + ".rows(), " + accessor + ".cols()}, \"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writeEigenMatrix({{" + accessor + nextEl() + "rows(), " + accessor + nextEl() + "cols()}, \"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr EigenMatrixSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
     CppBlockPtr EigenMatrixSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeNDArray({" + accessor + ".rows(), " + accessor + ".cols(), " + std::to_string(ACCEPTED_TYPES.at(typenavigator->getTypename()).second) + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + ".data()));");
+
+        b->addLine("w.writeNDArray({" + accessor + nextEl() + "rows(), " + accessor + nextEl() + "cols(), " + std::to_string(ACCEPTED_TYPES.at(typenavigator->getTypename()).second) + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "data()));");
         return b;
     }
 
@@ -101,14 +105,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
         b->addLine("r.readStartNDArray(); // We do not need the dims and type since a EigenMat can not change (templated)");
-        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + ".data()));");
+        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "data()));");
         return b;
     }
 
     CppBlockPtr EigenMatrixSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("if (not (" + accessor + ".isApprox(" + otherInstanceAccessor + ")))");
+        b->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))");
         b->addLine("\t return false;");
         return b;
     }
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp
index 825765164..2a899daa0 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp
@@ -35,7 +35,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     // constructors
     EigenQuaternionSerializer::EigenQuaternionSerializer(const typenavigator::EigenQuaternionNavigatorPtr& n) :
-        Serializer("Eigen::Quaternion<" + ACCEPTED_TYPES.at(n->getTypename()).first + ">", simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronEigenQuaternion))),
+        Serializer("Eigen::Quaternion<" + ACCEPTED_TYPES.at(n->getTypename()).first + ">",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronEigenQuaternion)),
+                   (n->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(n)
     {
     }
@@ -67,14 +70,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr EigenQuaternionSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeEigenQuaternion(\"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writeEigenQuaternion({\"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr EigenQuaternionSerializer::getWriteCurrentTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeEigenQuaternion(\"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writeEigenQuaternion({\"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
@@ -88,7 +91,10 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr EigenQuaternionSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + ", " + std::to_string(ACCEPTED_TYPES.at(typenavigator->getTypename()).second) + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + ".coeffs().data()));");
+
+        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+
+        b->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + ", " + std::to_string(ACCEPTED_TYPES.at(typenavigator->getTypename()).second) + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + resolved_accessor + nextEl() + "coeffs().data()));");
         return b;
     }
 
@@ -96,14 +102,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
         b->addLine("r.readStartNDArray(); // We do not need the dims and type since a EigenMat can not change (templated)");
-        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + ".coeffs().data()));");
+        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "coeffs().data()));");
         return b;
     }
 
     CppBlockPtr EigenQuaternionSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("if (not (" + accessor + ".isApprox(" + otherInstanceAccessor + ")))");
+        b->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))");
         b->addLine("\t return false;");
         return b;
     }
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp
index cdb9e7903..478f1a789 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp
@@ -36,7 +36,9 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     // constructors
     IVTCByteImageSerializer::IVTCByteImageSerializer(const typenavigator::IVTCByteImageNavigatorPtr& e) :
-        Serializer("CByteImage", simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronIVTCByteImage)), true),
+        Serializer("CByteImage",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronIVTCByteImage)), SerializerAccessType::ePTR), // a ptr is by default optional. We ignore the setting here
         typenavigator(e)
     {
         // check if type exists
@@ -63,7 +65,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr IVTCByteImageSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + "->Set(" + accessor + "->width, " + accessor + "->height, " + accessor + "->type);");
+        b->addLine(accessor + nextEl() + "Set(" + accessor + nextEl() + "width, " + accessor + nextEl() + "height, " + accessor + nextEl() + "type);");
         return b;
     }
 
@@ -77,21 +79,22 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr IVTCByteImageSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeIVTCByteImage(" + std::to_string(typenavigator->getWidth()) + ", " + std::to_string(typenavigator->getHeight()) + ", \"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writeIVTCByteImage({" + std::to_string(typenavigator->getWidth()) + ", " + std::to_string(typenavigator->getHeight()) + ", \"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr IVTCByteImageSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeIVTCByteImage(" + accessor + "->width, " + accessor + "->height, \"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writeIVTCByteImage({" + accessor + nextEl() + "width, " + accessor + nextEl() + "height, \"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr IVTCByteImageSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeNDArray({" + accessor + "->width, " + accessor + "->height, " + accessor + "->bytesPerPixel}, std::to_string(" + accessor + "->type), reinterpret_cast<const unsigned char*>(" + accessor + "->pixels));");
+
+        b->addLine("w.writeNDArray({" + accessor + nextEl() + "width, " + accessor + nextEl() + "height, " + accessor + nextEl() + "bytesPerPixel}, std::to_string(" + accessor + nextEl() + "type), reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "pixels));");
         return b;
     }
 
@@ -103,17 +106,17 @@ namespace armarx::aron::cppcodegenerator::serializer
         std::string type_accessor = escaped_accessor + TYPE_ACCESSOR;
 
         b->addLine("const auto [" + dims_accessor + ", " + type_accessor + "] = r.readStartNDArray();");
-        b->addLine(accessor + "->Set(" + dims_accessor + "[0], " + dims_accessor + "[1], static_cast<CByteImage::ImageType>(std::stoi(" + type_accessor + ")));");
-        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + "->pixels));");
+        b->addLine(accessor + nextEl() + "Set(" + dims_accessor + "[0], " + dims_accessor + "[1], static_cast<CByteImage::ImageType>(std::stoi(" + type_accessor + ")));");
+        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "pixels));");
         return b;
     }
 
     CppBlockPtr IVTCByteImageSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("if (not (" + accessor + "->IsCompatible(" + otherInstanceAccessor + ".get())))");
+        b->addLine("if (not (" + accessor + nextEl() + "IsCompatible(" + otherInstanceAccessor + ".get())))");
         b->addLine("\t return false;");
-        b->addLine("if (not (memcmp(" + accessor + "->pixels, " + otherInstanceAccessor + "->pixels, " + accessor + "->width * " + accessor + "->height * " + accessor + "->bytesPerPixel) == 0))");
+        b->addLine("if (not (memcmp(" + accessor + nextEl() + "pixels, " + otherInstanceAccessor + nextEl() + "pixels, " + accessor + nextEl() + "width * " + accessor + nextEl() + "height * " + accessor + nextEl() + "bytesPerPixel) == 0))");
         b->addLine("\t return false;");
         return b;
     }
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp
new file mode 100644
index 000000000..50609e51f
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp
@@ -0,0 +1,99 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
+ * Karlsruhe Institute of Technology (KIT), all rights reserved.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Peller-Konrad (fabian dot peller-konrad at kit dot edu)
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+// Header
+#include "NDArray.h"
+
+namespace armarx::aron::cppcodegenerator::serializer
+{
+    // constructors
+    NDArraySerializer::NDArraySerializer(const typenavigator::NDArrayNavigatorPtr& n) :
+        Serializer("NDArray",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronNDArray))),
+        typenavigator(n)
+    {
+    }
+
+    std::vector<CppFieldPtr> NDArraySerializer::getPublicVariableDeclarations(const std::string& name) const
+    {
+        CppFieldPtr field = CppFieldPtr(new CppField(getFullCppTypename(), name));
+        return {field};
+    }
+
+    std::vector<std::pair<std::string, std::string>> NDArraySerializer::getCtorInitializers(const std::string&) const
+    {
+        return {};
+    }
+
+    CppBlockPtr NDArraySerializer::getCtorBlock(const std::string&) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        return b;
+    }
+
+    CppBlockPtr NDArraySerializer::getResetBlock(const std::string& accessor) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        return b;
+    }
+
+    CppBlockPtr NDArraySerializer::getInitializeBlock(const std::string& accessor) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        return b;
+    }
+
+    CppBlockPtr NDArraySerializer::getWriteInitialTypeBlock(const std::string&) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        return b;
+    }
+
+    CppBlockPtr NDArraySerializer::getWriteCurrentTypeBlock(const std::string&) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        return b;
+    }
+
+    CppBlockPtr NDArraySerializer::getWriteBlock(const std::string& accessor) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        return b;
+    }
+
+    CppBlockPtr NDArraySerializer::getReadBlock(const std::string& accessor) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        return b;
+    }
+
+    CppBlockPtr NDArraySerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        return b;
+    }
+}
+
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h
new file mode 100644
index 000000000..46e45ff14
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h
@@ -0,0 +1,69 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
+ * Karlsruhe Institute of Technology (KIT), all rights reserved.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Peller-Konrad (fabian dot peller-konrad at kit dot edu)
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+// STD/STL
+#include <string>
+#include <map>
+
+// Base Class
+#include <RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h>
+
+// ArmarX
+#include <RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.h>
+
+namespace armarx::aron::cppcodegenerator::serializer
+{
+    class NDArraySerializer;
+    typedef std::shared_ptr<NDArraySerializer> AronNDArrayTypeCppSerializerPtr;
+
+    class NDArraySerializer :
+        virtual public Serializer
+    {
+    public:
+        using PointerType = AronNDArrayTypeCppSerializerPtr;
+
+    public:
+        // constructors
+        NDArraySerializer(const typenavigator::NDArrayNavigatorPtr&);
+
+        // virtual implementations
+        virtual std::vector<CppFieldPtr> getPublicVariableDeclarations(const std::string&) const override;
+        virtual std::vector<std::pair<std::string, std::string>> getCtorInitializers(const std::string&) const override;
+        virtual CppBlockPtr getCtorBlock(const std::string&) const override;
+        virtual CppBlockPtr getWriteInitialTypeBlock(const std::string&) const override;
+        virtual CppBlockPtr getInitializeBlock(const std::string&) const override;
+        virtual CppBlockPtr getWriteCurrentTypeBlock(const std::string&) const override;
+        virtual CppBlockPtr getResetBlock(const std::string&) const override;
+        virtual CppBlockPtr getWriteBlock(const std::string&) const override;
+        virtual CppBlockPtr getReadBlock(const std::string&) const override;
+        virtual CppBlockPtr getEqualsBlock(const std::string&, const std::string&) const override;
+
+    private:
+        static constexpr const char* DIMENSION_ACCESSOR = "_dimensions";
+        static constexpr const char* TYPE_ACCESSOR = "_type";
+
+        typenavigator::NDArrayNavigatorPtr typenavigator;
+    };
+}
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.cpp
index 3961a3884..f926b370c 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.cpp
@@ -40,7 +40,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     // constructors
     OpenCVMatSerializer::OpenCVMatSerializer(const typenavigator::OpenCVMatNavigatorPtr& e) :
-        Serializer("cv::Mat", simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronOpenCVMat))),
+        Serializer("cv::Mat",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronOpenCVMat)),
+                   (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(e)
     {
         // check if type exists
@@ -76,11 +79,11 @@ namespace armarx::aron::cppcodegenerator::serializer
         std::string accessor_iterator = escaped_accessor + ITERATOR_ACCESSOR;
 
         b->addLine("std::vector<int> " + accessor_dimensions + ";");
-        b->addLine("for (int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + ".dims; ++" + accessor_iterator + ")");
+        b->addLine("for (int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + nextEl() + "dims; ++" + accessor_iterator + ")");
         CppBlockPtr b2 = CppBlockPtr(new CppBlock());
-        b2->addLine(accessor_dimensions + ".push_back(" + accessor + ".size[" + accessor_iterator + "]);");
+        b2->addLine(accessor_dimensions + ".push_back(" + accessor + nextEl() + "size[" + accessor_iterator + "]);");
         b->appendBlock(b2);
-        b->addLine(accessor + " = " + getFullCppTypename() + "(" + accessor_dimensions + ", " + accessor + ".type());");
+        b->addLine(accessor + " = " + getFullCppTypename() + "(" + accessor_dimensions + ", " + accessor + nextEl() + "type());");
         return b;
     }
 
@@ -94,7 +97,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr OpenCVMatSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeOpenCVMat({" + simox::alg::to_string<int>(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writeOpenCVMat({{" + simox::alg::to_string<int>(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
@@ -107,11 +110,11 @@ namespace armarx::aron::cppcodegenerator::serializer
         std::string accessor_iterator = escaped_accessor + ITERATOR_ACCESSOR;
 
         b->addLine("std::vector<int> " + accessor_dimensions + ";");
-        b->addLine("for (int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + ".dims; ++" + accessor_iterator + ")");
+        b->addLine("for (int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + nextEl() + "dims; ++" + accessor_iterator + ")");
         CppBlockPtr b2 = CppBlockPtr(new CppBlock());
-        b2->addLine(accessor_dimensions + ".push_back(" + accessor + ".size[" + accessor_iterator + "]);");
+        b2->addLine(accessor_dimensions + ".push_back(" + accessor + nextEl() + "size[" + accessor_iterator + "]);");
         b->appendBlock(b2);
-        b->addLine("w.writeOpenCVMat(" + accessor_dimensions + ", std::to_string(" + accessor + ".type()));");
+        b->addLine("w.writeOpenCVMat({" + accessor_dimensions + ", std::to_string(" + accessor + nextEl() + "type()), " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
@@ -124,12 +127,12 @@ namespace armarx::aron::cppcodegenerator::serializer
         std::string accessor_iterator = escaped_accessor + ITERATOR_ACCESSOR;
 
         b->addLine("std::vector<int> " + accessor_dimensions + ";");
-        b->addLine("for (int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + ".dims; ++" + accessor_iterator + ")");
+        b->addLine("for (int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + nextEl() + "dims; ++" + accessor_iterator + ")");
         CppBlockPtr b2 = CppBlockPtr(new CppBlock());
-        b2->addLine(accessor_dimensions + ".push_back(" + accessor + ".size[" + accessor_iterator + "]);");
+        b2->addLine(accessor_dimensions + ".push_back(" + accessor + nextEl() + "size[" + accessor_iterator + "]);");
         b->appendBlock(b2);
-        b->addLine(accessor_dimensions + ".push_back(" + accessor + ".elemSize());");
-        b->addLine("w.writeNDArray(" + accessor_dimensions + ", std::to_string(" + accessor + ".type()), reinterpret_cast<const unsigned char*>(" + accessor + ".data));");
+        b->addLine(accessor_dimensions + ".push_back(" + accessor + nextEl() + "elemSize());");
+        b->addLine("w.writeNDArray(" + accessor_dimensions + ", std::to_string(" + accessor + nextEl() + "type()), reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "data));");
         return b;
     }
 
@@ -142,7 +145,7 @@ namespace armarx::aron::cppcodegenerator::serializer
 
         b->addLine("const auto [" + accessor_dimensions + ", " + accessor_type + "] = r.readStartNDArray();");
         b->addLine(accessor + " = " + getFullCppTypename() + "(std::vector<int>({" + accessor_dimensions + ".begin(), std::prev(" + accessor_dimensions + ".end())}), std::stoi(" + accessor_type + "));");
-        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + ".data));");
+        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "data));");
         return b;
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.cpp
index a431295f0..ba47bde1d 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.cpp
@@ -28,7 +28,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 {
     // constructors
     OrientationSerializer::OrientationSerializer(const typenavigator::OrientationNavigatorPtr& n) :
-        Serializer("Eigen::Quaternion<" + n->getTypename() + ">", simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronOrientation))),
+        Serializer("Eigen::Quaternion<" + n->getTypename() + ">",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronOrientation)),
+                   (n->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(n)
     {
     }
@@ -67,21 +70,22 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr OrientationSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeOrientation();");
+        b->addLine("w.writeOrientation({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr OrientationSerializer::getWriteCurrentTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeOrientation();");
+        b->addLine("w.writeOrientation({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr OrientationSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + ".coeffs().data()));");
+
+        b->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "coeffs().data()));");
         return b;
     }
 
@@ -94,14 +98,14 @@ namespace armarx::aron::cppcodegenerator::serializer
 
         b->addLine("const auto [" + accessor_dimensions + ", " + accessor_type + "] = r.readStartNDArray();");
         b->addLine(accessor + " = " + getFullCppTypename() + "();");
-        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + ".coeffs().data()));");
+        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "coeffs().data()));");
         return b;
     }
 
     CppBlockPtr OrientationSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("if (not (" + accessor + ".isApprox(" + otherInstanceAccessor + ")))");
+        b->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))");
         b->addLine("\t return false;");
         return b;
     }
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.cpp
index cd14f9221..4fe173666 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.cpp
@@ -41,7 +41,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     // constructors
     PCLPointCloudSerializer::PCLPointCloudSerializer(const typenavigator::PCLPointCloudNavigatorPtr& n) :
-        Serializer("pcl::PointCloud<" + ACCEPTED_TYPES.at(n->getTypename()).first + ">", simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronPCLPointCloud))),
+        Serializer("pcl::PointCloud<" + ACCEPTED_TYPES.at(n->getTypename()).first + ">",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronPCLPointCloud)),
+                   (n->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(n)
     {
     }
@@ -66,7 +69,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PCLPointCloudSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "(" + accessor + ".width, " + accessor + ".height);");
+        b->addLine(accessor + " = " + getFullCppTypename() + "(" + accessor + nextEl() + "width, " + accessor + nextEl() + "height);");
         return b;
     }
 
@@ -80,21 +83,22 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PCLPointCloudSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writePCLPointCloud(" + std::to_string(typenavigator->getWidth()) + ", " + std::to_string(typenavigator->getHeight()) + ", \"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writePCLPointCloud({" + std::to_string(typenavigator->getWidth()) + ", " + std::to_string(typenavigator->getHeight()) + ", \"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr PCLPointCloudSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writePCLPointCloud(" + accessor + ".width, " + accessor + ".height, \"" + typenavigator->getTypename() + "\");");
+        b->addLine("w.writePCLPointCloud({" + accessor + nextEl() + "width, " + accessor + nextEl() + "height, \"" + typenavigator->getTypename() + "\", " + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr PCLPointCloudSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeNDArray({" + accessor + ".width, " + accessor + ".height, " + std::to_string(ACCEPTED_TYPES.at(typenavigator->getTypename()).second) + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + ".points.data()));");
+
+        b->addLine("w.writeNDArray({" + accessor + nextEl() + "width, " + accessor + nextEl() + "height, " + std::to_string(ACCEPTED_TYPES.at(typenavigator->getTypename()).second) + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "points.data()));");
         return b;
     }
 
@@ -107,14 +111,14 @@ namespace armarx::aron::cppcodegenerator::serializer
 
         b->addLine("const auto [" + dims_accessor + ", " + type_accessor + "] = r.readStartNDArray();");
         b->addLine(accessor + " = " + getFullCppTypename() + "(" + dims_accessor + "[0], " + dims_accessor + "[1]);");
-        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + ".points.data()));");
+        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "points.data()));");
         return b;
     }
 
     CppBlockPtr PCLPointCloudSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("if (" + accessor + ".width != " + otherInstanceAccessor + ".width || " + accessor + ".height != " + otherInstanceAccessor + ".height)");
+        b->addLine("if (" + accessor + nextEl() + "width != " + otherInstanceAccessor + nextEl() + "width || " + accessor + nextEl() + "height != " + otherInstanceAccessor + nextEl() + "height)");
         b->addLine("\t return false;");
         //b->addLine("if (" + accessor + "->points != " + otherInstanceAccessor + "->points)");
         //b->addLine("\t return false;");
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.cpp
index b7039894e..9ee7758b1 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.cpp
@@ -28,7 +28,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 {
     // constructors
     PoseSerializer::PoseSerializer(const typenavigator::PoseNavigatorPtr& n) :
-        Serializer("Eigen::Matrix<" + n->getTypename() + ", " + simox::alg::to_string(n->getDimensions(), ", ") + ">", simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronPose))),
+        Serializer("Eigen::Matrix<" + n->getTypename() + ", " + simox::alg::to_string(n->getDimensions(), ", ") + ">",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronPose)),
+                   (n->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(n)
     {
     }
@@ -67,21 +70,24 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PoseSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writePose();");
+        b->addLine("w.writePose({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr PoseSerializer::getWriteCurrentTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writePose();");
+        b->addLine("w.writePose({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr PoseSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + ".data()));");
+
+        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+
+        b->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + resolved_accessor + nextEl() + "data()));");
         return b;
     }
 
@@ -94,14 +100,14 @@ namespace armarx::aron::cppcodegenerator::serializer
 
         b->addLine("const auto [" + accessor_dimensions + ", " + accessor_type + "] = r.readStartNDArray();");
         b->addLine(accessor + " = " + getFullCppTypename() + "();");
-        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + ".data()));");
+        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "data()));");
         return b;
     }
 
     CppBlockPtr PoseSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("if (not (" + accessor + ".isApprox(" + otherInstanceAccessor + ")))");
+        b->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))");
         b->addLine("\t return false;");
         return b;
     }
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.cpp
index 4bb664d2e..672d01502 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.cpp
@@ -28,7 +28,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 {
     // constructors
     PositionSerializer::PositionSerializer(const typenavigator::PositionNavigatorPtr& n) :
-        Serializer("Eigen::Matrix<" + n->getTypename() + ", " + simox::alg::to_string(n->getDimensions(), ", ") + ">", simox::meta::get_type_name(typeid(data::AronNDArray)), simox::meta::get_type_name(typeid(type::AronPosition))),
+        Serializer("Eigen::Matrix<" + n->getTypename() + ", " + simox::alg::to_string(n->getDimensions(), ", ") + ">",
+                   simox::meta::get_type_name(typeid(data::AronNDArray)),
+                   simox::meta::get_type_name(typeid(type::AronPosition)),
+                   (n->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
         typenavigator(n)
     {
     }
@@ -67,21 +70,24 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PositionSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writePosition();");
+        b->addLine("w.writePosition({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr PositionSerializer::getWriteCurrentTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writePosition();");
+        b->addLine("w.writePosition({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr PositionSerializer::getWriteBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + ".data()));");
+
+        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+
+        b->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + resolved_accessor + nextEl() + "data()));");
         return b;
     }
 
@@ -94,14 +100,14 @@ namespace armarx::aron::cppcodegenerator::serializer
 
         b->addLine("const auto [" + accessor_dimensions + ", " + accessor_type + "] = r.readStartNDArray();");
         b->addLine(accessor + " = " + getFullCppTypename() + "();");
-        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + ".data()));");
+        b->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "data()));");
         return b;
     }
 
     CppBlockPtr PositionSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("if (not (" + accessor + ".isApprox(" + otherInstanceAccessor + ")))");
+        b->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))");
         b->addLine("\t return false;");
         return b;
     }
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/primitive/Primitive.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/primitive/Primitive.cpp
index 28c002f1c..fd1abae70 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/primitive/Primitive.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/primitive/Primitive.cpp
@@ -46,7 +46,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 #define RUN_ARON_MACRO(upperType, lowerType, capsType, upperData, lowerData, capsData) \
     /* constructors */ \
     upperType##Serializer::upperType##Serializer(const typenavigator::upperType##NavigatorPtr& e) : \
-        Serializer(convertStdString(#lowerData), simox::meta::get_type_name(typeid(data::Aron##upperData)), simox::meta::get_type_name(typeid(type::Aron##upperType))), \
+        Serializer(convertStdString(#lowerData), \
+                   simox::meta::get_type_name(typeid(data::Aron##upperData)), \
+                   simox::meta::get_type_name(typeid(type::Aron##upperType)), \
+                   (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)), \
         typenavigator(e) \
     { \
         \
@@ -87,27 +90,30 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr upperType##Serializer::getWriteInitialTypeBlock(const std::string&) const \
     { \
         CppBlockPtr b = CppBlockPtr(new CppBlock()); \
-        b->addLine("w.write" + std::string(#upperType) + "();"); \
+        b->addLine("w.write" + std::string(#upperType) + "({" + std::string(typenavigator->isOptional() ? "true" : "false")+"});"); \
         return b; \
     } \
     \
     CppBlockPtr upperType##Serializer::getWriteCurrentTypeBlock(const std::string&) const \
     { \
         CppBlockPtr b = CppBlockPtr(new CppBlock()); \
-        b->addLine("w.write" + std::string(#upperType) + "();"); \
+        b->addLine("w.write" + std::string(#upperType) + "({" + std::string(typenavigator->isOptional() ? "true" : "false")+"});"); \
         return b; \
     } \
     \
     CppBlockPtr upperType##Serializer::getWriteBlock(const std::string& accessor) const \
     { \
         CppBlockPtr b = CppBlockPtr(new CppBlock()); \
-        b->addLine("w.writePrimitive(" + accessor + ");"); \
+        \
+        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator); \
+        b->addLine("w.writePrimitive(" + resolved_accessor + ");"); \
         return b; \
     } \
     \
     CppBlockPtr upperType##Serializer::getReadBlock(const std::string& accessor) const \
     { \
         CppBlockPtr b = CppBlockPtr(new CppBlock()); \
+        \
         b->addLine("r.readPrimitive("+accessor+");"); \
         return b; \
     } \
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.cpp
index d9d22766c..27c683a38 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.cpp
@@ -32,6 +32,10 @@ namespace armarx::aron::cppcodegenerator::serializer
         navigator(n),
         enumName("__ImplEnum")
     {
+        if (n->isOptional())
+        {
+            throw error::AronException("IntEnumClassSerializer", "IntEnumClassSerializer", "Somehow the optional flag of a top level int enum declaration is set. This is not valid!");
+        }
     }
 
     std::vector<CppFieldPtr> IntEnumClassSerializer::getPublicVariableDeclarations(const std::string&) const
@@ -94,14 +98,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr IntEnumClassSerializer::getWriteInitialTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeInt();");
+        b->addLine("w.writeInt({" + std::string(navigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
     CppBlockPtr IntEnumClassSerializer::getWriteCurrentTypeBlock(const std::string&) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeInt();");
+        b->addLine("w.writeInt({" + std::string(navigator->isOptional() ? "true" : "false") + "});");
         return b;
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/ObjectClass.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/ObjectClass.cpp
index 25abfc6f9..370c58e31 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/ObjectClass.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/ObjectClass.cpp
@@ -32,7 +32,10 @@ namespace armarx::aron::cppcodegenerator::serializer
         Serializer(e->getObjectName(), simox::meta::get_type_name(typeid(data::AronDict)), simox::meta::get_type_name(typeid(type::AronObject))),
         navigator(e)
     {
-        //AddObjectTypeToAllObjectTypesList(ObjectNavigatorPtr(this));
+        if (e->isOptional())
+        {
+            throw error::AronException("ObjectClassSerializer", "ObjectClassSerializer", "Somehow the optional flag of a top level object declaration is set. This is not valid!");
+        }
     }
 
     std::vector<CppFieldPtr> ObjectClassSerializer::getPublicVariableDeclarations(const std::string&) const
@@ -103,12 +106,12 @@ namespace armarx::aron::cppcodegenerator::serializer
             b->addLine(extends_s->getFullCppTypename() + "::writeInitialType(w);");
         }
 
-        b->addLine("w.writeStartObject(\"" + navigator->getObjectName() + "\");");
+        b->addLine("w.writeStartObject({\"" + navigator->getObjectName() + "\", type_is_optional});");
         for (const auto& [key, child] : navigator->getMemberTypes())
         {
             const auto child_s = FromAronTypeNaviagtorPtr(child);
             b->addLine("w.writeKey(\"" + key + "\");");
-            CppBlockPtr b2 = child_s->getWriteInitialTypeBlock(child_s->getFullCppTypename());
+            CppBlockPtr b2 = child_s->getWriteInitialTypeBlock(child_s->getCoreCppTypename());
             b->appendBlock(b2);
         }
         b->addLine("w.writeEndObject();");
@@ -124,7 +127,7 @@ namespace armarx::aron::cppcodegenerator::serializer
             b->addLine(extends_s->getFullCppTypename() + "::writeCurrentType(w);");
         }
 
-        b->addLine("w.writeStartObject(\"" + navigator->getObjectName() + "\");");
+        b->addLine("w.writeStartObject({\"" + navigator->getObjectName() + "\", type_is_optional});");
         for (const auto& [key, child] : navigator->getMemberTypes())
         {
             const auto child_s = FromAronTypeNaviagtorPtr(child);
@@ -149,9 +152,21 @@ namespace armarx::aron::cppcodegenerator::serializer
         for (const auto& [key, child] : navigator->getMemberTypes())
         {
             const auto child_s = FromAronTypeNaviagtorPtr(child);
-            b->addLine("w.writeKey(\"" + key + "\");");
-            CppBlockPtr b2 = child_s->getWriteBlock(key);
-            b->appendBlock(b2);
+            CppBlockPtr q = CppBlockPtr(new CppBlock());
+
+            q->addLine("w.writeKey(\"" + key + "\");");
+            CppBlockPtr child_b = child_s->getWriteBlock(key);
+            q->appendBlock(child_b);
+
+            if (child->isOptional())
+            {
+                b->addLine("if (" + key + ".has_value())");
+                b->addBlock(q);
+            }
+            else
+            {
+                b->appendBlock(q);
+            }
         }
         b->addLine("w.writeEndDict();");
         return b;
@@ -170,9 +185,21 @@ namespace armarx::aron::cppcodegenerator::serializer
         for (const auto& [key, child] : navigator->getMemberTypes())
         {
             const auto child_s = FromAronTypeNaviagtorPtr(child);
-            b->addLine("r.loadMember(\"" + key + "\");");
-            CppBlockPtr b2 = child_s->getReadBlock(key);
-            b->appendBlock(b2);
+            CppBlockPtr q = CppBlockPtr(new CppBlock());
+
+            CppBlockPtr child_b = child_s->getReadBlock(key);
+            q->appendBlock(child_b);
+
+            if (child->isOptional())
+            {
+                b->addLine("if (r.loadMember(\"" + key + "\"));");
+                b->addBlock(q);
+            }
+            else
+            {
+                b->addLine("r.loadMember(\"" + key + "\");");
+                b->appendBlock(q);
+            }
         }
         b->addLine("r.readEndDict();");
         return b;
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Data.h b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Data.h
index 2f152c9e4..b0aee6f1e 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Data.h
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Data.h
@@ -56,6 +56,7 @@ namespace armarx::aron::xmltypereader
         static constexpr const char* INCLUDE_TAG = "include";
         static constexpr const char* GENERATE_OBJECT_TAG = "object";
         static constexpr const char* GENERATE_INT_ENUM_TAG = "intenum";
+        static constexpr const char* GENERATE_NDARRAY_TAG = "ndarray";
 
         // Attribute names
         static constexpr const char* METHOD_ATTRIBUTE_NAME = "method";
@@ -74,6 +75,7 @@ namespace armarx::aron::xmltypereader
         static constexpr const char* ROWS_ATTRIBUTE_NAME = "rows";
         static constexpr const char* COLS_ATTRIBUTE_NAME = "cols";
         static constexpr const char* DIMENSIONS_ATTRIBUTE_NAME = "dimensions";
+        static constexpr const char* OPTIONAL_NAME = "optional";
 
         // Second level tags. Only important if in specific top level tag
         static constexpr const char* OBJECT_CHILD_TAG = "objectchild";
@@ -114,6 +116,19 @@ namespace armarx::aron::xmltypereader
             return node.attribute_value(att.c_str());
         }
 
+        static bool AttributeIsTrue(const RapidXmlReaderNode& node, const std::string& att)
+        {
+            if (HasAttribute(node, att))
+            {
+                std::string v = simox::alg::to_lower(node.attribute_value(att.c_str()));
+                if (v == "1" or v == "true" or v == "wahr" or v == "yes" or v == "ja" or v == "")
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
         static bool HasTagName(const RapidXmlReaderNode& node, const std::string& name)
         {
             return (simox::alg::to_lower(name) == simox::alg::to_lower(node.name()));
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.cpp
index cf56e4833..bc2cc0b58 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.cpp
@@ -194,14 +194,12 @@ namespace armarx::aron::xmltypereader
     {
         Data::EnforceTagName(node, Data::GENERATE_OBJECT_TAG);
         return typenavigator::ObjectNavigator::DynamicCastAndCheck(factory.create(node, Path()));
-
     }
 
     typenavigator::IntEnumNavigatorPtr Reader::readGenerateIntEnum(const RapidXmlReaderNode& node) const
     {
         Data::EnforceTagName(node, Data::GENERATE_INT_ENUM_TAG);
         return typenavigator::IntEnumNavigator::DynamicCastAndCheck(factory.create(node, Path()));
-
     }
 
 
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/ReaderFactory.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/ReaderFactory.cpp
index da9eff9f2..4d65cf804 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/ReaderFactory.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/ReaderFactory.cpp
@@ -77,13 +77,15 @@ namespace armarx::aron::xmltypereader
         const auto public_intenum_it = AllPublicIntEnums.find(name);
         if (public_intenum_it != AllPublicIntEnums.end())
         {
-            return public_intenum_it->second->correspondingType;
+            // copy the navigator
+            return typenavigator::Navigator::FromAronType(public_intenum_it->second->correspondingType->getResult());
         }
 
         const auto public_obj_it = AllPublicObjects.find(name);
         if (public_obj_it != AllPublicObjects.end())
         {
-            return public_obj_it->second->correspondingType;
+            // copy the navigator
+            return typenavigator::Navigator::FromAronType(public_obj_it->second->correspondingType->getResult());
         }
 
         throw error::StringNotValidException("XMLReaderFactory", "ResolveTypename", "Could not find a tag. You can only access already finished public objects.", name);
@@ -133,8 +135,11 @@ namespace armarx::aron::xmltypereader
             Data::EnforceAttribute(objectChild, Data::KEY_ATTRIBUTE_NAME);
             const std::string key = objectChild.attribute_value(Data::KEY_ATTRIBUTE_NAME);
 
+            bool is_optional = Data::AttributeIsTrue(objectChild, Data::OPTIONAL_NAME);
+
             std::vector<RapidXmlReaderNode> children = objectChild.nodes();
             typenavigator::NavigatorPtr childNavigator = create(children[0], Path(path, key));
+            childNavigator->setOptional(is_optional);
             aronObjectType->addMemberType(key, childNavigator);
         }
         ObjectGenerationStack.pop();
@@ -163,7 +168,9 @@ namespace armarx::aron::xmltypereader
         Data::EnforceChildSize(node, 1);
         std::vector<RapidXmlReaderNode> listTypeNodeChildren = node.nodes();
         const RapidXmlReaderNode typeNode = listTypeNodeChildren[0];
+        bool is_optional = Data::AttributeIsTrue(typeNode, Data::OPTIONAL_NAME);
         typenavigator::NavigatorPtr type = create(typeNode, Path(path, "type"));
+        type->setOptional(is_optional);
 
         list->setAcceptedType(type);
         return list;
@@ -178,9 +185,11 @@ namespace armarx::aron::xmltypereader
         Data::EnforceChildSize(node, 1);
         std::vector<RapidXmlReaderNode> dictTypeNodeChildren = node.nodes();
         const RapidXmlReaderNode typeNode = dictTypeNodeChildren[0];
+        bool is_optional = Data::AttributeIsTrue(typeNode, Data::OPTIONAL_NAME);
         typenavigator::NavigatorPtr type = create(typeNode, Path(path, "type"));
-        dict->setAcceptedType(type);
+        type->setOptional(is_optional);
 
+        dict->setAcceptedType(type);
         return dict;
     }
 
@@ -203,8 +212,11 @@ namespace armarx::aron::xmltypereader
 
             std::vector<RapidXmlReaderNode> typeNodeChildren = tupleTypeDeclarationNode.nodes();
             const RapidXmlReaderNode typeNode = typeNodeChildren[0];
+            bool is_optional = Data::AttributeIsTrue(typeNode, Data::OPTIONAL_NAME);
 
             typenavigator::NavigatorPtr type = create(typeNode, Path(path, "<" + std::to_string(i++) + ">"));
+            type->setOptional(is_optional);
+
             tuple->addAcceptedType(type);
         }
         return tuple;
@@ -227,19 +239,31 @@ namespace armarx::aron::xmltypereader
         std::vector<RapidXmlReaderNode> type1NodeChildren = nodeChildren[0].nodes();
         const RapidXmlReaderNode type1Node = type1NodeChildren[0];
 
+        bool is_optional1 = Data::AttributeIsTrue(type1Node, Data::OPTIONAL_NAME);
+
         typenavigator::NavigatorPtr type1 = create(type1Node, Path(path, std::to_string(0)));
+        type1->setOptional(is_optional1);
         pair->setFirstAcceptedType(type1);
 
         Data::EnforceChildSize(nodeChildren[1], 1);
         std::vector<RapidXmlReaderNode> type2NodeChildren = nodeChildren[1].nodes();
         const RapidXmlReaderNode type2Node = type2NodeChildren[0];
 
+        bool is_optional2 = Data::AttributeIsTrue(type2Node, Data::OPTIONAL_NAME);
+
         typenavigator::NavigatorPtr type2 = create(type2Node, Path(path, std::to_string(1)));
+        type2->setOptional(is_optional2);
         pair->setSecondAcceptedType(type2);
 
         return pair;
     }
 
+    // Complex type (NDArray)
+    typenavigator::NavigatorPtr NDArrayReaderFactory::createSpecific(const RapidXmlReaderNode& node, const Path& path) const
+    {
+        return nullptr;
+    }
+
     // Complex type (IVTCByteImage)
     typenavigator::NavigatorPtr IVTCByteImageReaderFactory::createSpecific(const RapidXmlReaderNode& node, const Path& path) const
     {
diff --git a/source/RobotAPI/libraries/aron/core/io/Data.h b/source/RobotAPI/libraries/aron/core/io/Data.h
index 73c693b53..dd2b5eb0f 100644
--- a/source/RobotAPI/libraries/aron/core/io/Data.h
+++ b/source/RobotAPI/libraries/aron/core/io/Data.h
@@ -41,6 +41,8 @@ namespace armarx::aron::io
     public:
         // TODO: Remove copy from ReaderWriter
         static constexpr const char* READER_WRITER_NAME_SLUG = "__ARON_NAME";
+        static constexpr const char* READER_WRITER_OPTIONAL_SLUG = "__OPTIONAL";
+
         static constexpr const char* READER_WRITER_DICT_ACCEPTED_TYPE_SLUG = "__ARON_DICT_ACCEPTED_TYPE";
         static constexpr const char* READER_WRITER_LIST_ACCEPTED_TYPE_SLUG = "__ARON_LIST_ACCEPTED_TYPE";
 
@@ -53,6 +55,8 @@ namespace armarx::aron::io
         static constexpr const char* READER_WRITER_INT_ENUM_VALUE_SLUG = "__ARON_INT_ENUM_VALUE";
         static constexpr const char* READER_WRITER_ENUM_KEY_SLUG = "__ARON_ENUM_KEY";
 
+        static constexpr const char* READER_WRITER_PRIMITIVE_NAME_SLUG = "__ARON_PRIMITIVE_NAME";
+
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
     static constexpr const char* READER_WRITER_##capsType##_TYPENAME_SLUG = #capsType;
 
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.cpp
new file mode 100644
index 000000000..6ebf4a1ff
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.cpp
@@ -0,0 +1,67 @@
+/*
+* This file is part of ArmarX.
+*
+* ArmarX is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* ArmarX is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* @author     Fabian Peller (fabian dot peller at kit dot edu)
+* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+*             GNU General Public License
+*/
+
+#include "Reader.h"
+
+namespace armarx::aron::dataIO
+{
+    void ReaderInterface::readPrimitive(std::optional<int>& o)
+    {
+        int i;
+        readPrimitive(i);
+        o = i;
+    }
+
+    void ReaderInterface::readPrimitive(std::optional<long>& o)
+    {
+        long i;
+        readPrimitive(i);
+        o = i;
+    }
+
+    void ReaderInterface::readPrimitive(std::optional<float>& o)
+    {
+        float i;
+        readPrimitive(i);
+        o = i;
+    }
+
+    void ReaderInterface::readPrimitive(std::optional<double>& o)
+    {
+        double i;
+        readPrimitive(i);
+        o = i;
+    }
+
+    void ReaderInterface::readPrimitive(std::optional<std::string>& o)
+    {
+        std::string i;
+        readPrimitive(i);
+        o = i;
+    }
+
+    void ReaderInterface::readPrimitive(std::optional<bool>& o)
+    {
+        bool i;
+        readPrimitive(i);
+        o = i;
+    }
+}
+
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h
index 574b9167d..6c7019ae5 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h
@@ -24,6 +24,7 @@
 #include <memory>
 #include <string>
 #include <vector>
+#include <optional>
 
 // ArmarX
 #include <RobotAPI/libraries/aron/core/Config.h>
@@ -52,6 +53,13 @@ namespace armarx::aron::dataIO
         virtual void readPrimitive(std::string&) = 0;
         virtual void readPrimitive(bool&) = 0;
 
+        void readPrimitive(std::optional<int>&);
+        void readPrimitive(std::optional<long>&);
+        void readPrimitive(std::optional<float>&);
+        void readPrimitive(std::optional<double>&);
+        void readPrimitive(std::optional<std::string>&);
+        void readPrimitive(std::optional<bool>&);
+
         template<class T>
         T readPrimitive()
         {
@@ -61,7 +69,7 @@ namespace armarx::aron::dataIO
         }
 
         virtual std::string readKey() = 0;
-        virtual void loadMember(const std::string&) = 0;
+        virtual bool loadMember(const std::string&) = 0;
 
         // Helper functions
         virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const = 0;
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.cpp
new file mode 100644
index 000000000..e78a27bd5
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.cpp
@@ -0,0 +1,21 @@
+/*
+* This file is part of ArmarX.
+*
+* ArmarX is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* ArmarX is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* @author     Fabian Peller (fabian dot peller at kit dot edu)
+* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+*             GNU General Public License
+*/
+
+#include "Writer.h"
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h
index b1c8e774e..2b9379be1 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h
@@ -85,6 +85,15 @@ namespace armarx::aron::dataIO
             return this->currentKey;
         }
 
+        bool hasKey(const std::string& k) const
+        {
+            if (descriptor != data::Descriptor::eDict)
+            {
+                throw error::DescriptorNotValidException("ReaderTokenInterface", "hasKey", "Checking whether a container has a key only makes sense in a dict.", descriptor);
+            }
+            return std::find(allMemberNames.begin(), allMemberNames.end(), k) != allMemberNames.end();
+        }
+
         void setCurrentKey(const std::string& s)
         {
             currentKey = s;
@@ -92,7 +101,7 @@ namespace armarx::aron::dataIO
 
         void assertType(data::Descriptor t) const
         {
-            if (getDescriptor() != t)
+            if (descriptor != t)
             {
                 throw error::DescriptorNotValidException("dataIO::ReaderTokenInterface", "assertType", "The type was not equal.", t);
             }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.cpp
index 2dc7c3db8..d3cefab09 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.cpp
@@ -183,10 +183,15 @@ namespace armarx::aron::dataIO::reader
         return token->getCurrentKey();
     }
 
-    void NavigatorReader::loadMember(const std::string& k)
+    bool NavigatorReader::loadMember(const std::string& k)
     {
         auto token = stack.top();
-        token->setCurrentKey(k);
+        if (token->hasKey(k))
+        {
+            token->setCurrentKey(k);
+            return true;
+        }
+        return false;
     }
 
     // Helper functions
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.h
index db52ad1d8..d5365a888 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.h
@@ -64,7 +64,7 @@ namespace armarx::aron::dataIO::reader
         virtual void readPrimitive(bool&) override;
 
         virtual std::string readKey() override;
-        virtual void loadMember(const std::string&) override;
+        virtual bool loadMember(const std::string&) override;
 
         virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const override;
 
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
index c243c4e4b..59a2351ac 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
@@ -175,10 +175,15 @@ namespace armarx::aron::dataIO::reader
         return token->getCurrentKey();
     }
 
-    void NlohmannJSONReader::loadMember(const std::string& k)
+    bool NlohmannJSONReader::loadMember(const std::string& k)
     {
         auto token = stack.top();
-        token->setCurrentKey(k);
+        if (token->hasKey(k))
+        {
+            token->setCurrentKey(k);
+            return true;
+        }
+        return false;
     }
 
     // Helper functions
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h
index 774953030..03202f7be 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h
@@ -62,7 +62,7 @@ namespace armarx::aron::dataIO::reader
         virtual void readPrimitive(bool&) override;
 
         virtual std::string readKey() override;
-        virtual void loadMember(const std::string&) override;
+        virtual bool loadMember(const std::string&) override;
 
         virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const override;
 
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/Reader.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/Reader.cpp
new file mode 100644
index 000000000..4fe8d311a
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/Reader.cpp
@@ -0,0 +1,21 @@
+/*
+* This file is part of ArmarX.
+*
+* ArmarX is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* ArmarX is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* @author     Fabian Peller (fabian dot peller at kit dot edu)
+* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+*             GNU General Public License
+*/
+
+#include "Reader.h"
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/Reader.h b/source/RobotAPI/libraries/aron/core/io/typeIO/Reader.h
index 738b4c351..d3ea62010 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/Reader.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/Reader.h
@@ -38,33 +38,117 @@ namespace armarx::aron::typeIO
     class ReaderInterface
     {
     public:
-        virtual std::tuple<std::string, int> readStartObject() = 0;
+        struct ReadStartObjectReturnType
+        {
+            std::string name;
+            unsigned int elements;
+            bool is_optional;
+        };
+        virtual ReadStartObjectReturnType readStartObject() = 0;
         virtual bool readEndObject() = 0;
-        virtual int readStartList() = 0;
+
+        struct ReadStartListReturnType
+        {
+            unsigned int elements;
+            bool is_optional;
+        };
+        virtual ReadStartListReturnType readStartList() = 0;
         virtual bool readEndList() = 0;
-        virtual int readStartDict() = 0;
+
+        struct ReadStartDictReturnType
+        {
+            unsigned int elements;
+            bool is_optional;
+        };
+        virtual ReadStartDictReturnType readStartDict() = 0;
         virtual bool readEndDict() = 0;
-        virtual int readStartTuple() = 0;
+
+        struct ReadStartTupleReturnType
+        {
+            unsigned int elements;
+            bool is_optional;
+        };
+        virtual ReadStartTupleReturnType readStartTuple() = 0;
         virtual bool readEndTuple() = 0;
-        virtual int readStartPair() = 0;
+
+        struct ReadStartPairReturnType
+        {
+            unsigned int elements;
+            bool is_optional;
+        };
+        virtual ReadStartPairReturnType readStartPair() = 0;
         virtual bool readEndPair() = 0;
 
-        virtual std::tuple<std::vector<int>, std::string> readEigenMatrix() = 0;
-        virtual std::string readEigenQuaternion() = 0;
-        virtual std::tuple<unsigned int, unsigned int, std::string> readIVTCByteImage() = 0;
-        virtual std::tuple<std::vector<int>, std::string> readOpenCVMat() = 0;
-        virtual std::tuple<unsigned int, unsigned int, std::string> readPCLPointCloud() = 0;
-        virtual void readPosition() = 0;
-        virtual void readOrientation() = 0;
-        virtual void readPose() = 0;
-
-        virtual void readInt() = 0;
-        virtual void readLong() = 0;
-        virtual void readFloat() = 0;
-        virtual void readDouble() = 0;
-        virtual void readString() = 0;
-        virtual void readBool() = 0;
-        virtual void readTime() = 0;
+        struct ReadEigenMatrixReturnType
+        {
+            std::vector<int> dimensions;
+            std::string type;
+            bool is_optional;
+        };
+        virtual ReadEigenMatrixReturnType readEigenMatrix() = 0;
+
+        struct ReadEigenQuaternionReturnType
+        {
+            std::string type;
+            bool is_optional;
+        };
+        virtual ReadEigenQuaternionReturnType readEigenQuaternion() = 0;
+
+        struct ReadIVTCbyteImageReturnType
+        {
+            unsigned int width;
+            unsigned int height;
+            std::string type;
+            bool is_optional;
+        };
+        virtual ReadIVTCbyteImageReturnType readIVTCByteImage() = 0;
+
+        struct ReadOpenCVMatReturnType
+        {
+            std::vector<int> dimensions;
+            std::string type;
+            bool is_optional;
+        };
+        virtual ReadOpenCVMatReturnType readOpenCVMat() = 0;
+
+        struct ReadPCLPointCloudReturnType
+        {
+            unsigned int width;
+            unsigned int height;
+            std::string type;
+            bool is_optional;
+        };
+        virtual ReadPCLPointCloudReturnType readPCLPointCloud() = 0;
+
+        struct ReadPositionReturnType
+        {
+            bool is_optional;
+        };
+        virtual ReadPositionReturnType readPosition() = 0;
+
+        struct ReadOrientationReturnType
+        {
+            bool is_optional;
+        };
+        virtual ReadOrientationReturnType readOrientation() = 0;
+
+        struct ReadPoseReturnType
+        {
+            bool is_optional;
+        };
+        virtual ReadPoseReturnType readPose() = 0;
+
+        struct ReadPrimitiveReturnType
+        {
+            bool is_optional;
+        };
+        virtual ReadPrimitiveReturnType readInt() = 0;
+        virtual ReadPrimitiveReturnType readLong() = 0;
+        virtual ReadPrimitiveReturnType readFloat() = 0;
+        virtual ReadPrimitiveReturnType readDouble() = 0;
+        virtual ReadPrimitiveReturnType readString() = 0;
+        virtual ReadPrimitiveReturnType readBool() = 0;
+        virtual ReadPrimitiveReturnType readTime() = 0;
 
         virtual std::string readKey() = 0;
         virtual void loadMember(const std::string&) = 0;
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.cpp
new file mode 100644
index 000000000..e78a27bd5
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.cpp
@@ -0,0 +1,21 @@
+/*
+* This file is part of ArmarX.
+*
+* ArmarX is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* ArmarX is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* @author     Fabian Peller (fabian dot peller at kit dot edu)
+* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+*             GNU General Public License
+*/
+
+#include "Writer.h"
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.h b/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.h
index 552b5fc1a..58f5bcc32 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.h
@@ -39,33 +39,112 @@ namespace armarx::aron::typeIO
     class WriterInterface
     {
     public:
-        virtual void writeStartObject(const std::string&) = 0;
+        struct WriteStartObjectInput
+        {
+            std::string name;
+            bool is_optional;
+        };
+        virtual void writeStartObject(const WriteStartObjectInput&) = 0;
         virtual void writeEndObject() = 0;
-        virtual void writeStartList() = 0;
+
+        struct WriteStartListInput
+        {
+            bool is_optional;
+        };
+        virtual void writeStartList(const WriteStartListInput&) = 0;
         virtual void writeEndList() = 0;
-        virtual void writeStartDict() = 0;
+
+        struct WriteStartDictInput
+        {
+            bool is_optional;
+        };
+        virtual void writeStartDict(const WriteStartDictInput&) = 0;
         virtual void writeEndDict() = 0;
-        virtual void writeStartTuple() = 0;
+
+        struct WriteStartTupleInput
+        {
+            bool is_optional;
+        };
+        virtual void writeStartTuple(const WriteStartTupleInput&) = 0;
         virtual void writeEndTuple() = 0;
-        virtual void writeStartPair() = 0;
+
+        struct WriteStartPairInput
+        {
+            bool is_optional;
+        };
+        virtual void writeStartPair(const WriteStartPairInput&) = 0;
         virtual void writeEndPair() = 0;
 
-        virtual void writeEigenMatrix(const std::vector<int>&, const std::string&) = 0;
-        virtual void writeEigenQuaternion(const std::string&) = 0;
-        virtual void writeIVTCByteImage(unsigned int w, unsigned int h, const std::string&) = 0;
-        virtual void writeOpenCVMat(const std::vector<int>&, const std::string&) = 0;
-        virtual void writePCLPointCloud(unsigned int w, unsigned int h, const std::string&) = 0;
-        virtual void writePosition() = 0;
-        virtual void writeOrientation() = 0;
-        virtual void writePose() = 0;
-
-        virtual void writeInt() = 0;
-        virtual void writeLong() = 0;
-        virtual void writeFloat() = 0;
-        virtual void writeDouble() = 0;
-        virtual void writeString() = 0;
-        virtual void writeBool() = 0;
-        virtual void writeTime() = 0;
+        struct WriteEigenMatrixInput
+        {
+            std::vector<int> dimensions;
+            std::string type;
+            bool is_optional;
+        };
+        virtual void writeEigenMatrix(const WriteEigenMatrixInput&) = 0;
+
+        struct WriteEigenQuaternionInput
+        {
+            std::string type;
+            bool is_optional;
+        };
+        virtual void writeEigenQuaternion(const WriteEigenQuaternionInput&) = 0;
+
+        struct WriteIVTCByteImageInput
+        {
+            unsigned int width;
+            unsigned int height;
+            std::string type;
+            bool is_optional;
+        };
+        virtual void writeIVTCByteImage(const WriteIVTCByteImageInput&) = 0;
+
+        struct WriteOpenCVMatInput
+        {
+            std::vector<int> dimensions;
+            std::string type;
+            bool is_optional;
+        };
+        virtual void writeOpenCVMat(const WriteOpenCVMatInput&) = 0;
+
+        struct WritePCLPointCloudInput
+        {
+            unsigned int width;
+            unsigned int height;
+            std::string type;
+            bool is_optional;
+        };
+        virtual void writePCLPointCloud(const WritePCLPointCloudInput&) = 0;
+
+        struct WritePositionInput
+        {
+            bool is_optional;
+        };
+        virtual void writePosition(const WritePositionInput&) = 0;
+
+        struct WriteOrientationInput
+        {
+            bool is_optional;
+        };
+        virtual void writeOrientation(const WriteOrientationInput&) = 0;
+
+        struct WritePoseInput
+        {
+            bool is_optional;
+        };
+        virtual void writePose(const WritePoseInput&) = 0;
+
+        struct WritePrimitiveInput
+        {
+            bool is_optional;
+        };
+        virtual void writeInt(const WritePrimitiveInput&) = 0;
+        virtual void writeLong(const WritePrimitiveInput&) = 0;
+        virtual void writeFloat(const WritePrimitiveInput&) = 0;
+        virtual void writeDouble(const WritePrimitiveInput&) = 0;
+        virtual void writeString(const WritePrimitiveInput&) = 0;
+        virtual void writeBool(const WritePrimitiveInput&) = 0;
+        virtual void writeTime(const WritePrimitiveInput&) = 0;
 
         virtual void writeKey(const std::string&) = 0;
     };
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.cpp
index 48decff3a..9750bfc93 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.cpp
@@ -34,10 +34,10 @@ namespace armarx::aron::typeIO
         {
             case type::Descriptor::eObject:
             {
-                const auto [name, elements] = reader.readStartObject();
-                writer.writeStartObject(name);
+                const auto readStartObject = reader.readStartObject();
+                writer.writeStartObject({readStartObject.name, readStartObject.is_optional});
 
-                for (int i = 0; i < elements; ++i)
+                for (unsigned int i = 0; i < readStartObject.elements; ++i)
                 {
                     std::string key = reader.readKey();
                     writer.writeKey(key);
@@ -50,8 +50,8 @@ namespace armarx::aron::typeIO
             }
             case type::Descriptor::eDict:
             {
-                reader.readStartDict();
-                writer.writeStartDict();
+                const auto readStartDict = reader.readStartDict();
+                writer.writeStartDict({readStartDict.is_optional});
 
                 Converter::ReadAndConvert(reader, writer);
 
@@ -61,10 +61,10 @@ namespace armarx::aron::typeIO
             }
             case type::Descriptor::eTuple:
             {
-                int elements = reader.readStartTuple();
-                writer.writeStartTuple();
+                const auto readStartTuple = reader.readStartTuple();
+                writer.writeStartTuple({readStartTuple.is_optional});
 
-                for (int i = 0; i < elements; ++i)
+                for (unsigned int i = 0; i < readStartTuple.elements; ++i)
                 {
                     Converter::ReadAndConvert(reader, writer);
                 }
@@ -75,8 +75,8 @@ namespace armarx::aron::typeIO
             }
             case type::Descriptor::eList:
             {
-                reader.readStartList();
-                writer.writeStartList();
+                const auto readStartList = reader.readStartList();
+                writer.writeStartList({readStartList.is_optional});
 
                 Converter::ReadAndConvert(reader, writer);
 
@@ -86,92 +86,92 @@ namespace armarx::aron::typeIO
             }
             case type::Descriptor::eEigenMatrix:
             {
-                auto x = reader.readEigenMatrix();
-                writer.writeEigenMatrix(std::get<0>(x), std::get<1>(x));
+                const auto readEigenMatrix = reader.readEigenMatrix();
+                writer.writeEigenMatrix({readEigenMatrix.dimensions, readEigenMatrix.type, readEigenMatrix.is_optional});
                 break;
             }
             case type::Descriptor::eEigenQuaternion:
             {
-                auto x = reader.readEigenQuaternion();
-                writer.writeEigenQuaternion(x);
+                const auto readEigenQuaternion = reader.readEigenQuaternion();
+                writer.writeEigenQuaternion({readEigenQuaternion.type, readEigenQuaternion.is_optional});
                 break;
             }
             case type::Descriptor::eIVTCByteImage:
             {
-                auto x = reader.readIVTCByteImage();
-                writer.writeIVTCByteImage(std::get<0>(x), std::get<1>(x), std::get<2>(x));
+                const auto readIVTCByteImage = reader.readIVTCByteImage();
+                writer.writeIVTCByteImage({readIVTCByteImage.width, readIVTCByteImage.height, readIVTCByteImage.type, readIVTCByteImage.is_optional});
                 break;
             }
             case type::Descriptor::eOpenCVMat:
             {
-                auto x = reader.readOpenCVMat();
-                writer.writeOpenCVMat(std::get<0>(x), std::get<1>(x));
+                const auto readOpenCVMat = reader.readOpenCVMat();
+                writer.writeOpenCVMat({readOpenCVMat.dimensions, readOpenCVMat.type, readOpenCVMat.is_optional});
                 break;
             }
             case type::Descriptor::ePCLPointCloud:
             {
-                auto x = reader.readPCLPointCloud();
-                writer.writePCLPointCloud(std::get<0>(x), std::get<1>(x), std::get<2>(x));
+                const auto readPCLPointCloud = reader.readPCLPointCloud();
+                writer.writePCLPointCloud({readPCLPointCloud.width, readPCLPointCloud.height, readPCLPointCloud.type, readPCLPointCloud.is_optional});
                 break;
             }
             case type::Descriptor::ePosition:
             {
-                reader.readPosition();
-                writer.writePosition();
+                const auto readPosition = reader.readPosition();
+                writer.writePosition({readPosition.is_optional});
                 break;
             }
             case type::Descriptor::eOrientation:
             {
-                reader.readOrientation();
-                writer.writeOrientation();
+                const auto readOrientation = reader.readOrientation();
+                writer.writeOrientation({readOrientation.is_optional});
                 break;
             }
             case type::Descriptor::ePose:
             {
-                reader.readPose();
-                writer.writePose();
+                const auto readPose = reader.readPose();
+                writer.writePose({readPose.is_optional});
                 break;
             }
             case type::Descriptor::eInt:
             {
-                reader.readInt();
-                writer.writeInt();
+                const auto readInt = reader.readInt();
+                writer.writeInt({readInt.is_optional});
                 break;
             }
             case type::Descriptor::eLong:
             {
-                reader.readLong();
-                writer.writeLong();
+                const auto readLong = reader.readLong();
+                writer.writeLong({readLong.is_optional});
                 break;
             }
             case type::Descriptor::eFloat:
             {
-                reader.readFloat();
-                writer.writeFloat();
+                const auto readFloat = reader.readFloat();
+                writer.writeFloat({readFloat.is_optional});
                 break;
             }
             case type::Descriptor::eDouble:
             {
-                reader.readDouble();
-                writer.writeDouble();
+                const auto readDouble = reader.readDouble();
+                writer.writeDouble({readDouble.is_optional});
                 break;
             }
             case type::Descriptor::eString:
             {
-                reader.readString();
-                writer.writeString();
+                const auto readString = reader.readString();
+                writer.writeString({readString.is_optional});
                 break;
             }
             case type::Descriptor::eBool:
             {
-                reader.readBool();
-                writer.writeBool();
+                const auto readBool = reader.readBool();
+                writer.writeBool({readBool.is_optional});
                 break;
             }
             case type::Descriptor::eTime:
             {
-                reader.readTime();
-                writer.writeTime();
+                const auto readTime = reader.readTime();
+                writer.writeTime({readTime.is_optional});
                 break;
             }
             default:
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.cpp
index 0effe2a60..d31e4fca7 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.cpp
@@ -31,7 +31,6 @@
 #include <RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.h>
 
 
-
 namespace armarx::aron::typeIO::reader
 {
     NavigatorReader::NavigatorReader(const typenavigator::NavigatorPtr& n) :
@@ -55,13 +54,13 @@ namespace armarx::aron::typeIO::reader
         return lastToken->getNextElementAndIncreaseCnt();
     }
 
-    std::tuple<std::string, int> NavigatorReader::readStartObject()
+    ReaderInterface::ReadStartObjectReturnType NavigatorReader::readStartObject()
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::ObjectNavigator::DynamicCastAndCheck(current_nav);
         auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::eObject, current_nav_casted);
         stack.push(newToken);
-        return {newToken->getElementName(), newToken->getElementChildrenSize()};
+        return {newToken->getElementName(), newToken->getElementChildrenSize(), current_nav_casted->isOptional()};
     }
 
     bool NavigatorReader::readEndObject()
@@ -77,13 +76,13 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    int NavigatorReader::readStartDict()
+    ReaderInterface::ReadStartDictReturnType NavigatorReader::readStartDict()
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::DictNavigator::DynamicCastAndCheck(current_nav);
         auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::eDict, current_nav_casted);
         stack.push(newToken);
-        return newToken->getElementChildrenSize();
+        return {newToken->getElementChildrenSize(), current_nav_casted->isOptional()};
     }
 
     bool NavigatorReader::readEndDict()
@@ -99,13 +98,13 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    int NavigatorReader::readStartList()
+    ReaderInterface::ReadStartListReturnType NavigatorReader::readStartList()
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::ListNavigator::DynamicCastAndCheck(current_nav);
         auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::eList, current_nav_casted);
         stack.push(newToken);
-        return newToken->getElementChildrenSize();
+        return {newToken->getElementChildrenSize(), current_nav_casted->isOptional()};
     }
 
     bool NavigatorReader::readEndList()
@@ -121,13 +120,13 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    int NavigatorReader::readStartTuple()
+    ReaderInterface::ReadStartTupleReturnType NavigatorReader::readStartTuple()
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::TupleNavigator::DynamicCastAndCheck(current_nav);
         auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::eTuple, current_nav_casted);
         stack.push(newToken);
-        return newToken->getElementChildrenSize();
+        return {newToken->getElementChildrenSize(), current_nav_casted->isOptional()};
     }
 
     bool NavigatorReader::readEndTuple()
@@ -143,13 +142,13 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    int NavigatorReader::readStartPair()
+    ReaderInterface::ReadStartPairReturnType NavigatorReader::readStartPair()
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::PairNavigator::DynamicCastAndCheck(current_nav);
         auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::ePair, current_nav_casted);
         stack.push(newToken);
-        return newToken->getElementChildrenSize();
+        return {newToken->getElementChildrenSize(), current_nav_casted->isOptional()};
     }
 
     bool NavigatorReader::readEndPair()
@@ -165,100 +164,110 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    std::tuple<std::vector<int>, std::string> NavigatorReader::readEigenMatrix()
+    ReaderInterface::ReadEigenMatrixReturnType NavigatorReader::readEigenMatrix()
     {
         auto nav = getNextAndIncrease();
         auto casted = typenavigator::EigenMatrixNavigator::DynamicCastAndCheck(nav);
-        return std::make_tuple(casted->getDimensions(), casted->getTypename());
+        return {casted->getDimensions(), casted->getTypename(), casted->isOptional()};
     }
 
-    std::string NavigatorReader::readEigenQuaternion()
+    ReaderInterface::ReadEigenQuaternionReturnType NavigatorReader::readEigenQuaternion()
     {
         auto nav = getNextAndIncrease();
         auto casted = typenavigator::EigenMatrixNavigator::DynamicCastAndCheck(nav);
-        return casted->getTypename();
+        return {casted->getTypename(), casted->isOptional()};
     }
 
-    std::tuple<unsigned int, unsigned int, std::string> NavigatorReader::readIVTCByteImage()
+    ReaderInterface::ReadIVTCbyteImageReturnType NavigatorReader::readIVTCByteImage()
     {
         auto nav = getNextAndIncrease();
         auto casted = typenavigator::IVTCByteImageNavigator::DynamicCastAndCheck(nav);
-        return make_tuple(casted->getWidth(), casted->getHeight(), casted->getTypename());
+        return {casted->getWidth(), casted->getHeight(), casted->getTypename(), casted->isOptional()};
     }
 
-    std::tuple<std::vector<int>, std::string> NavigatorReader::readOpenCVMat()
+    ReaderInterface::ReadOpenCVMatReturnType NavigatorReader::readOpenCVMat()
     {
         auto nav = getNextAndIncrease();
         auto casted = typenavigator::OpenCVMatNavigator::DynamicCastAndCheck(nav);
-        return make_tuple(casted->getDimensions(), casted->getTypename());
+        return {casted->getDimensions(), casted->getTypename(), casted->isOptional()};
     }
 
-    std::tuple<unsigned int, unsigned int, std::string> NavigatorReader::readPCLPointCloud()
+    ReaderInterface::ReadPCLPointCloudReturnType NavigatorReader::readPCLPointCloud()
     {
         auto nav = getNextAndIncrease();
         auto casted = typenavigator::PCLPointCloudNavigator::DynamicCastAndCheck(nav);
-        return make_tuple(casted->getWidth(), casted->getHeight(), casted->getTypename());
+        return {casted->getWidth(), casted->getHeight(), casted->getTypename(), casted->isOptional()};
     }
 
-    void NavigatorReader::readPosition()
+    ReaderInterface::ReadPositionReturnType NavigatorReader::readPosition()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::PositionNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::PositionNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
-    void NavigatorReader::readOrientation()
+    ReaderInterface::ReadOrientationReturnType NavigatorReader::readOrientation()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::OrientationNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::OrientationNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
-    void NavigatorReader::readPose()
+    ReaderInterface::ReadPoseReturnType NavigatorReader::readPose()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::PoseNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::PoseNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
     // Read primitives
-    void NavigatorReader::readInt()
+    ReaderInterface::ReadPrimitiveReturnType NavigatorReader::readInt()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::IntNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::IntNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
-    void NavigatorReader::readFloat()
+    ReaderInterface::ReadPrimitiveReturnType NavigatorReader::readFloat()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::FloatNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::FloatNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
-    void NavigatorReader::readLong()
+    ReaderInterface::ReadPrimitiveReturnType NavigatorReader::readLong()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::LongNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::LongNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
-    void NavigatorReader::readDouble()
+    ReaderInterface::ReadPrimitiveReturnType NavigatorReader::readDouble()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::DoubleNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::DoubleNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
-    void NavigatorReader::readString()
+    ReaderInterface::ReadPrimitiveReturnType NavigatorReader::readString()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::StringNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::StringNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
-    void NavigatorReader::readBool()
+    ReaderInterface::ReadPrimitiveReturnType NavigatorReader::readBool()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::BoolNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::BoolNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
-    void NavigatorReader::readTime()
+    ReaderInterface::ReadPrimitiveReturnType NavigatorReader::readTime()
     {
         auto nav = getNextAndIncrease();
-        typenavigator::TimeNavigator::DynamicCastAndCheck(nav);
+        auto casted = typenavigator::TimeNavigator::DynamicCastAndCheck(nav);
+        return {casted->isOptional()};
     }
 
     std::string NavigatorReader::readKey()
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.h b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.h
index 0b733ce7c..d85113eb9 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.h
@@ -49,34 +49,33 @@ namespace armarx::aron::typeIO::reader
         NavigatorReader(const typenavigator::NavigatorPtr& n);
         NavigatorReader(const type::AronTypePtr& n);
 
-
-        virtual std::tuple<std::string, int> readStartObject() override;
+        virtual ReadStartObjectReturnType readStartObject() override;
         virtual bool readEndObject() override;
-        virtual int readStartList() override;
+        virtual ReadStartListReturnType readStartList() override;
         virtual bool readEndList() override;
-        virtual int readStartDict() override;
+        virtual ReadStartDictReturnType readStartDict() override;
         virtual bool readEndDict() override;
-        virtual int readStartTuple() override;
+        virtual ReadStartTupleReturnType readStartTuple() override;
         virtual bool readEndTuple() override;
-        virtual int readStartPair() override;
+        virtual ReadStartPairReturnType readStartPair() override;
         virtual bool readEndPair() override;
 
-        virtual std::tuple<std::vector<int>, std::string> readEigenMatrix() override;
-        virtual std::string readEigenQuaternion() override;
-        virtual std::tuple<unsigned int, unsigned int, std::string> readIVTCByteImage() override;
-        virtual std::tuple<std::vector<int>, std::string> readOpenCVMat() override;
-        virtual std::tuple<unsigned int, unsigned int, std::string> readPCLPointCloud() override;
-        virtual void readPosition() override;
-        virtual void readOrientation() override;
-        virtual void readPose() override;
-
-        virtual void readInt() override;
-        virtual void readLong() override;
-        virtual void readFloat() override;
-        virtual void readDouble() override;
-        virtual void readString() override;
-        virtual void readBool() override;
-        virtual void readTime() override;
+        virtual ReadEigenMatrixReturnType readEigenMatrix() override;
+        virtual ReadEigenQuaternionReturnType readEigenQuaternion() override;
+        virtual ReadIVTCbyteImageReturnType readIVTCByteImage() override;
+        virtual ReadOpenCVMatReturnType readOpenCVMat() override;
+        virtual ReadPCLPointCloudReturnType readPCLPointCloud() override;
+        virtual ReadPositionReturnType readPosition() override;
+        virtual ReadOrientationReturnType readOrientation() override;
+        virtual ReadPoseReturnType readPose() override;
+
+        virtual ReadPrimitiveReturnType readInt() override;
+        virtual ReadPrimitiveReturnType readLong() override;
+        virtual ReadPrimitiveReturnType readFloat() override;
+        virtual ReadPrimitiveReturnType readDouble() override;
+        virtual ReadPrimitiveReturnType readString() override;
+        virtual ReadPrimitiveReturnType readBool() override;
+        virtual ReadPrimitiveReturnType readTime() override;
 
         virtual std::string readKey() override;
         virtual void loadMember(const std::string&) override;
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
index 98d6953ad..175918c82 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
@@ -55,12 +55,13 @@ namespace armarx::aron::typeIO::reader
         return lastToken->getNextElementAndIncreaseCnt();
     }
 
-    std::tuple<std::string, int> NlohmannJSONReader::readStartObject()
+    ReaderInterface::ReadStartObjectReturnType NlohmannJSONReader::readStartObject()
     {
         nlohmann::json current_json = getNextAndIncrease();
         auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::eObject, current_json);
         stack.push(newToken);
-        return {newToken->getElementName(), newToken->getElementChildrenSize()};
+        bool o = current_json[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {newToken->getElementName(), newToken->getElementChildrenSize(), o};
     }
 
     bool NlohmannJSONReader::readEndObject()
@@ -76,12 +77,13 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    int NlohmannJSONReader::readStartDict()
+    ReaderInterface::ReadStartDictReturnType NlohmannJSONReader::readStartDict()
     {
         nlohmann::json current_json = getNextAndIncrease();
         auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::eDict, current_json);
         stack.push(newToken);
-        return newToken->getElementChildrenSize();
+        bool o = current_json[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {newToken->getElementChildrenSize(), o};
     }
 
     bool NlohmannJSONReader::readEndDict()
@@ -97,12 +99,13 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    int NlohmannJSONReader::readStartList()
+    ReaderInterface::ReadStartListReturnType NlohmannJSONReader::readStartList()
     {
         nlohmann::json current_json = getNextAndIncrease();
         auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::eList, current_json);
         stack.push(newToken);
-        return newToken->getElementChildrenSize();
+        bool o = current_json[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {newToken->getElementChildrenSize(), o};
     }
 
     bool NlohmannJSONReader::readEndList()
@@ -118,12 +121,13 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    int NlohmannJSONReader::readStartTuple()
+    ReaderInterface::ReadStartTupleReturnType NlohmannJSONReader::readStartTuple()
     {
         nlohmann::json current_json = getNextAndIncrease();
         auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::eTuple, current_json);
         stack.push(newToken);
-        return newToken->getElementChildrenSize();
+        bool o = current_json[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {newToken->getElementChildrenSize(), o};
     }
 
     bool NlohmannJSONReader::readEndTuple()
@@ -139,12 +143,13 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    int NlohmannJSONReader::readStartPair()
+    ReaderInterface::ReadStartPairReturnType NlohmannJSONReader::readStartPair()
     {
         nlohmann::json current_json = getNextAndIncrease();
         auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::ePair, current_json);
         stack.push(newToken);
-        return newToken->getElementChildrenSize();
+        bool o = current_json[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {newToken->getElementChildrenSize(), o};
     }
 
     bool NlohmannJSONReader::readEndPair()
@@ -160,97 +165,119 @@ namespace armarx::aron::typeIO::reader
         return false;
     }
 
-    std::tuple<std::vector<int>, std::string> NlohmannJSONReader::readEigenMatrix()
+    ReaderInterface::ReadEigenMatrixReturnType NlohmannJSONReader::readEigenMatrix()
     {
         nlohmann::json j = getNextAndIncrease();
         std::vector<int> dims = j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG];
         std::string type = j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG];
-        return std::make_tuple(dims, type);
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {dims, type, o};
     }
 
-    std::string NlohmannJSONReader::readEigenQuaternion()
+    ReaderInterface::ReadEigenQuaternionReturnType NlohmannJSONReader::readEigenQuaternion()
     {
         nlohmann::json j = getNextAndIncrease();
         std::string type = j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG];
-        return type;
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {type, o};
     }
 
-    std::tuple<unsigned int, unsigned int, std::string> NlohmannJSONReader::readIVTCByteImage()
+    ReaderInterface::ReadIVTCbyteImageReturnType NlohmannJSONReader::readIVTCByteImage()
     {
         nlohmann::json j = getNextAndIncrease();
-        std::vector<int> dims = j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG];
+        std::vector<unsigned int> dims = j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG];
         std::string type = j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG];
-        return std::make_tuple(dims[0], dims[1], type);
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {dims[0], dims[1], type, o};
     }
 
-    std::tuple<std::vector<int>, std::string> NlohmannJSONReader::readOpenCVMat()
+    ReaderInterface::ReadOpenCVMatReturnType NlohmannJSONReader::readOpenCVMat()
     {
         nlohmann::json j = getNextAndIncrease();
         std::vector<int> dims = j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG];
         std::string type = j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG];
-        return std::make_tuple(dims, type);
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {dims, type, o};
     }
 
-    std::tuple<unsigned int, unsigned int, std::string> NlohmannJSONReader::readPCLPointCloud()
+    ReaderInterface::ReadPCLPointCloudReturnType NlohmannJSONReader::readPCLPointCloud()
     {
         nlohmann::json j = getNextAndIncrease();
-        std::vector<int> dims = j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG];
+        std::vector<unsigned int> dims = j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG];
         std::string type = j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG];
-        return std::make_tuple(dims[0], dims[1], type);
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {dims[0], dims[1], type, o};
     }
 
-    void NlohmannJSONReader::readPosition()
+    ReaderInterface::ReadPositionReturnType NlohmannJSONReader::readPosition()
     {
-        getNextAndIncrease();
-        return;
+        nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
-    void NlohmannJSONReader::readOrientation()
+    ReaderInterface::ReadOrientationReturnType NlohmannJSONReader::readOrientation()
     {
-        getNextAndIncrease();
-        return;
+        nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
-    void NlohmannJSONReader::readPose()
+    ReaderInterface::ReadPoseReturnType NlohmannJSONReader::readPose()
     {
-        getNextAndIncrease();
-        return;
+        nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
     // Read primitives
-    void NlohmannJSONReader::readInt()
+    ReaderInterface::ReadPrimitiveReturnType NlohmannJSONReader::readInt()
     {
         nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
-    void NlohmannJSONReader::readLong()
+    ReaderInterface::ReadPrimitiveReturnType NlohmannJSONReader::readLong()
     {
         nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
-    void NlohmannJSONReader::readFloat()
+    ReaderInterface::ReadPrimitiveReturnType NlohmannJSONReader::readFloat()
     {
         nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
-    void NlohmannJSONReader::readDouble()
+    ReaderInterface::ReadPrimitiveReturnType NlohmannJSONReader::readDouble()
     {
         nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
-    void NlohmannJSONReader::readString()
+    ReaderInterface::ReadPrimitiveReturnType NlohmannJSONReader::readString()
     {
         nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
-    void NlohmannJSONReader::readBool()
+    ReaderInterface::ReadPrimitiveReturnType NlohmannJSONReader::readBool()
     {
         nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
-    void NlohmannJSONReader::readTime()
+    ReaderInterface::ReadPrimitiveReturnType NlohmannJSONReader::readTime()
     {
         nlohmann::json j = getNextAndIncrease();
+        bool o = j[io::Data::READER_WRITER_OPTIONAL_SLUG];
+        return {o};
     }
 
     std::string NlohmannJSONReader::readKey()
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.h b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.h
index 70efcc50e..78caf17db 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.h
@@ -47,33 +47,33 @@ namespace armarx::aron::typeIO::reader
         NlohmannJSONReader(const nlohmann::json& n);
         NlohmannJSONReader(const std::string& n);
 
-        virtual std::tuple<std::string, int> readStartObject() override;
+        virtual ReadStartObjectReturnType readStartObject() override;
         virtual bool readEndObject() override;
-        virtual int readStartList() override;
+        virtual ReadStartListReturnType readStartList() override;
         virtual bool readEndList() override;
-        virtual int readStartDict() override;
+        virtual ReadStartDictReturnType readStartDict() override;
         virtual bool readEndDict() override;
-        virtual int readStartTuple() override;
+        virtual ReadStartTupleReturnType readStartTuple() override;
         virtual bool readEndTuple() override;
-        virtual int readStartPair() override;
+        virtual ReadStartPairReturnType readStartPair() override;
         virtual bool readEndPair() override;
 
-        virtual std::tuple<std::vector<int>, std::string> readEigenMatrix() override;
-        virtual std::string readEigenQuaternion() override;
-        virtual std::tuple<unsigned int, unsigned int, std::string> readIVTCByteImage() override;
-        virtual std::tuple<std::vector<int>, std::string> readOpenCVMat() override;
-        virtual std::tuple<unsigned int, unsigned int, std::string> readPCLPointCloud() override;
-        virtual void readPosition() override;
-        virtual void readOrientation() override;
-        virtual void readPose() override;
+        virtual ReadEigenMatrixReturnType readEigenMatrix() override;
+        virtual ReadEigenQuaternionReturnType readEigenQuaternion() override;
+        virtual ReadIVTCbyteImageReturnType readIVTCByteImage() override;
+        virtual ReadOpenCVMatReturnType readOpenCVMat() override;
+        virtual ReadPCLPointCloudReturnType readPCLPointCloud() override;
+        virtual ReadPositionReturnType readPosition() override;
+        virtual ReadOrientationReturnType readOrientation() override;
+        virtual ReadPoseReturnType readPose() override;
 
-        virtual void readInt() override;
-        virtual void readLong() override;
-        virtual void readFloat() override;
-        virtual void readDouble() override;
-        virtual void readString() override;
-        virtual void readBool() override;
-        virtual void readTime() override;
+        virtual ReadPrimitiveReturnType readInt() override;
+        virtual ReadPrimitiveReturnType readLong() override;
+        virtual ReadPrimitiveReturnType readFloat() override;
+        virtual ReadPrimitiveReturnType readDouble() override;
+        virtual ReadPrimitiveReturnType readString() override;
+        virtual ReadPrimitiveReturnType readBool() override;
+        virtual ReadPrimitiveReturnType readTime() override;
 
         virtual std::string readKey() override;
         virtual void loadMember(const std::string&) override;
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.cpp
index 1b0bb02c4..a18cc2daa 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.cpp
@@ -45,8 +45,8 @@ namespace armarx::aron::typeIO
         {
             case type::Descriptor::eObject:
             {
-                type::AronObjectPtr casted = type::AronObjectPtr::dynamicCast(aron);
-                writer.writeStartObject(casted->objectName);
+                auto casted = type::AronObjectPtr::dynamicCast(aron);
+                writer.writeStartObject({casted->objectName, casted->is_optional});
                 for (const auto& [key, value] : casted->elementTypes)
                 {
                     writer.writeKey(key);
@@ -57,16 +57,16 @@ namespace armarx::aron::typeIO
             }
             case type::Descriptor::eDict:
             {
-                type::AronDictPtr casted = type::AronDictPtr::dynamicCast(aron);
-                writer.writeStartDict();
+                auto casted = type::AronDictPtr::dynamicCast(aron);
+                writer.writeStartDict({casted->is_optional});
                 Visitor::VisitAndSetup(writer, casted->acceptedType);
                 writer.writeEndDict();
                 break;
             }
             case type::Descriptor::eTuple:
             {
-                type::AronTuplePtr casted = type::AronTuplePtr::dynamicCast(aron);
-                writer.writeStartTuple();
+                auto casted = type::AronTuplePtr::dynamicCast(aron);
+                writer.writeStartTuple({casted->is_optional});
                 for (const auto& value : casted->elementTypes)
                 {
                     Visitor::VisitAndSetup(writer, value);
@@ -76,97 +76,100 @@ namespace armarx::aron::typeIO
             }
             case type::Descriptor::eList:
             {
-                type::AronListPtr casted = type::AronListPtr::dynamicCast(aron);
-                writer.writeStartList();
+                auto casted = type::AronListPtr::dynamicCast(aron);
+                writer.writeStartList({casted->is_optional});
                 Visitor::VisitAndSetup(writer, casted->acceptedType);
                 writer.writeEndList();
                 break;
             }
             case type::Descriptor::eEigenMatrix:
             {
-                type::AronEigenMatrixPtr casted = type::AronEigenMatrixPtr::dynamicCast(aron);
-                writer.writeEigenMatrix(casted->dimensions, casted->typeName);
+                auto casted = type::AronEigenMatrixPtr::dynamicCast(aron);
+                writer.writeEigenMatrix({casted->dimensions, casted->typeName, casted->is_optional});
                 break;
             }
             case type::Descriptor::eEigenQuaternion:
             {
-                type::AronEigenQuaternionPtr casted = type::AronEigenQuaternionPtr::dynamicCast(aron);
-                writer.writeEigenQuaternion(casted->typeName);
+                auto casted = type::AronEigenQuaternionPtr::dynamicCast(aron);
+                writer.writeEigenQuaternion({casted->typeName, casted->is_optional});
                 break;
             }
             case type::Descriptor::eIVTCByteImage:
             {
-                type::AronIVTCByteImagePtr casted = type::AronIVTCByteImagePtr::dynamicCast(aron);
-                writer.writeIVTCByteImage(casted->width, casted->height, casted->typeName);
+                auto casted = type::AronIVTCByteImagePtr::dynamicCast(aron);
+                writer.writeIVTCByteImage({(unsigned int) casted->width, (unsigned int) casted->height, casted->typeName, casted->is_optional});
                 break;
             }
             case type::Descriptor::eOpenCVMat:
             {
-                type::AronOpenCVMatPtr casted = type::AronOpenCVMatPtr::dynamicCast(aron);
-                writer.writeOpenCVMat(casted->dimensions, casted->typeName);
+                auto casted = type::AronOpenCVMatPtr::dynamicCast(aron);
+                writer.writeOpenCVMat({casted->dimensions, casted->typeName, casted->is_optional});
                 break;
             }
             case type::Descriptor::ePCLPointCloud:
             {
-                type::AronPCLPointCloudPtr casted = type::AronPCLPointCloudPtr::dynamicCast(aron);
-                writer.writePCLPointCloud(casted->width, casted->height, casted->typeName);
+                auto casted = type::AronPCLPointCloudPtr::dynamicCast(aron);
+                writer.writePCLPointCloud({(unsigned int) casted->width, (unsigned int) casted->height, casted->typeName, casted->is_optional});
                 break;
             }
             case type::Descriptor::ePosition:
             {
-                writer.writePosition();
+                auto casted = type::AronPositionPtr::dynamicCast(aron);
+                writer.writePosition({casted->is_optional});
                 break;
             }
             case type::Descriptor::eOrientation:
             {
-                writer.writeOrientation();
+                auto casted = type::AronOrientationPtr::dynamicCast(aron);
+                writer.writeOrientation({casted->is_optional});
                 break;
             }
             case type::Descriptor::ePose:
             {
-                writer.writePose();
+                auto casted = type::AronPosePtr::dynamicCast(aron);
+                writer.writePose({casted->is_optional});
                 break;
             }
             case type::Descriptor::eInt:
             {
-                type::AronIntPtr casted = type::AronIntPtr::dynamicCast(aron);
-                writer.writeInt();
+                auto casted = type::AronIntPtr::dynamicCast(aron);
+                writer.writeInt({casted->is_optional});
                 break;
             }
             case type::Descriptor::eLong:
             {
-                type::AronLongPtr casted = type::AronLongPtr::dynamicCast(aron);
-                writer.writeLong();
+                auto casted = type::AronLongPtr::dynamicCast(aron);
+                writer.writeLong({casted->is_optional});
                 break;
             }
             case type::Descriptor::eFloat:
             {
-                type::AronFloatPtr casted = type::AronFloatPtr::dynamicCast(aron);
-                writer.writeFloat();
+                auto casted = type::AronFloatPtr::dynamicCast(aron);
+                writer.writeFloat({casted->is_optional});
                 break;
             }
             case type::Descriptor::eDouble:
             {
-                type::AronDoublePtr casted = type::AronDoublePtr::dynamicCast(aron);
-                writer.writeDouble();
+                auto casted = type::AronDoublePtr::dynamicCast(aron);
+                writer.writeDouble({casted->is_optional});
                 break;
             }
             case type::Descriptor::eString:
             {
-                type::AronStringPtr casted = type::AronStringPtr::dynamicCast(aron);
-                writer.writeString();
+                auto casted = type::AronStringPtr::dynamicCast(aron);
+                writer.writeString({casted->is_optional});
                 break;
             }
             case type::Descriptor::eBool:
             {
-                type::AronBoolPtr casted = type::AronBoolPtr::dynamicCast(aron);
-                writer.writeBool();
+                auto casted = type::AronBoolPtr::dynamicCast(aron);
+                writer.writeBool({casted->is_optional});
                 break;
             }
             case type::Descriptor::eTime:
             {
-                type::AronTimePtr casted = type::AronTimePtr::dynamicCast(aron);
-                writer.writeTime();
+                auto casted = type::AronTimePtr::dynamicCast(aron);
+                writer.writeTime({casted->is_optional});
                 break;
             }
             default:
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.cpp
index 06e8c0076..e50169c74 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.cpp
@@ -53,11 +53,12 @@ namespace armarx::aron::typeIO::writer
     }
 
     // interface
-    void NavigatorWriter::writeStartObject(const std::string& n)
+    void NavigatorWriter::writeStartObject(const WriteStartObjectInput& o)
     {
         Path path = generatePath();
         auto type = std::make_shared<typenavigator::ObjectNavigator>(path);
-        type->setObjectName(n);
+        type->setObjectName(o.name);
+        type->setOptional(o.is_optional);
         auto new_token = std::make_shared<NavigatorWriterToken>(type->getDescriptor(), type);
         stack.push(new_token);
     }
@@ -74,10 +75,11 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NavigatorWriter::writeStartDict()
+    void NavigatorWriter::writeStartDict(const WriteStartDictInput& o)
     {
         Path path = generatePath();
         auto type = std::make_shared<typenavigator::DictNavigator>(path);
+        type->setOptional(o.is_optional);
         auto new_token = std::make_shared<NavigatorWriterToken>(type->getDescriptor(), type);
         stack.push(new_token);
     }
@@ -94,10 +96,11 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NavigatorWriter::writeStartList()
+    void NavigatorWriter::writeStartList(const WriteStartListInput& o)
     {
         Path path = generatePath();
         auto type = std::make_shared<typenavigator::ListNavigator>(path);
+        type->setOptional(o.is_optional);
         auto new_token = std::make_shared<NavigatorWriterToken>(type->getDescriptor(), type);
         stack.push(new_token);
     }
@@ -114,10 +117,11 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NavigatorWriter::writeStartTuple()
+    void NavigatorWriter::writeStartTuple(const WriteStartTupleInput& o)
     {
         Path path = generatePath();
         auto type = std::make_shared<typenavigator::TupleNavigator>(path);
+        type->setOptional(o.is_optional);
         auto new_token = std::make_shared<NavigatorWriterToken>(type->getDescriptor(), type);
         stack.push(new_token);
     }
@@ -134,10 +138,11 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NavigatorWriter::writeStartPair()
+    void NavigatorWriter::writeStartPair(const WriteStartPairInput& o)
     {
         Path path = generatePath();
         auto type = std::make_shared<typenavigator::PairNavigator>(path);
+        type->setOptional(o.is_optional);
         auto new_token = std::make_shared<NavigatorWriterToken>(type->getDescriptor(), type);
         stack.push(new_token);
     }
@@ -154,134 +159,149 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NavigatorWriter::writeEigenMatrix(const std::vector<int>& dims, const std::string& t)
+    void NavigatorWriter::writeEigenMatrix(const WriteEigenMatrixInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::EigenMatrixNavigatorPtr aron(new typenavigator::EigenMatrixNavigator(path));
-        aron->setTypename(t);
-        aron->setDimensions(dims);
+        aron->setTypename(o.type);
+        aron->setDimensions(o.dimensions);
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeEigenQuaternion(const std::string& t)
+    void NavigatorWriter::writeEigenQuaternion(const WriteEigenQuaternionInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::EigenQuaternionNavigatorPtr aron(new typenavigator::EigenQuaternionNavigator(path));
-        aron->setTypename(t);
+        aron->setTypename(o.type);
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeIVTCByteImage(unsigned int w, unsigned int h, const std::string& t)
+    void NavigatorWriter::writeIVTCByteImage(const WriteIVTCByteImageInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::IVTCByteImageNavigatorPtr aron(new typenavigator::IVTCByteImageNavigator(path));
-        aron->setTypename(t);
-        aron->setWidth(w);
-        aron->setHeight(h);
+        aron->setTypename(o.type);
+        aron->setWidth(o.width);
+        aron->setHeight(o.height);
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeOpenCVMat(const std::vector<int>& dims, const std::string& t)
+    void NavigatorWriter::writeOpenCVMat(const WriteOpenCVMatInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::OpenCVMatNavigatorPtr aron(new typenavigator::OpenCVMatNavigator(path));
-        aron->setTypename(t);
-        aron->setDimensions(dims);
+        aron->setTypename(o.type);
+        aron->setDimensions(o.dimensions);
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writePCLPointCloud(unsigned int w, unsigned int h, const std::string& t)
+    void NavigatorWriter::writePCLPointCloud(const WritePCLPointCloudInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::PCLPointCloudNavigatorPtr aron(new typenavigator::PCLPointCloudNavigator(path));
-        aron->setTypename(t);
-        aron->setWidth(w);
-        aron->setHeight(h);
+        aron->setTypename(o.type);
+        aron->setWidth(o.width);
+        aron->setHeight(o.height);
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writePosition()
+    void NavigatorWriter::writePosition(const WritePositionInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::PositionNavigatorPtr aron(new typenavigator::PositionNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeOrientation()
+    void NavigatorWriter::writeOrientation(const WriteOrientationInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::OrientationNavigatorPtr aron(new typenavigator::OrientationNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writePose()
+    void NavigatorWriter::writePose(const WritePoseInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::PoseNavigatorPtr aron(new typenavigator::PoseNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeInt()
+    void NavigatorWriter::writeInt(const WritePrimitiveInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::IntNavigatorPtr aron(new typenavigator::IntNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeLong()
+    void NavigatorWriter::writeLong(const WritePrimitiveInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::LongNavigatorPtr aron(new typenavigator::LongNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeFloat()
+    void NavigatorWriter::writeFloat(const WritePrimitiveInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::FloatNavigatorPtr aron(new typenavigator::FloatNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeDouble()
+    void NavigatorWriter::writeDouble(const WritePrimitiveInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::DoubleNavigatorPtr aron(new typenavigator::DoubleNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeString()
+    void NavigatorWriter::writeString(const WritePrimitiveInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::StringNavigatorPtr aron(new typenavigator::StringNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeBool()
+    void NavigatorWriter::writeBool(const WritePrimitiveInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::BoolNavigatorPtr aron(new typenavigator::BoolNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
-    void NavigatorWriter::writeTime()
+    void NavigatorWriter::writeTime(const WritePrimitiveInput& o)
     {
         Path path = generatePath();
         NavigatorWriterTokenPtr token = stack.top();
         typenavigator::TimeNavigatorPtr aron(new typenavigator::TimeNavigator(path));
+        aron->setOptional(o.is_optional);
         token->addElement(aron);
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h
index 00b7ed96e..b15ab9e9b 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h
@@ -43,33 +43,33 @@ namespace armarx::aron::typeIO::writer
     public:
         NavigatorWriter() = default;
 
-        virtual void writeStartObject(const std::string&) override;
+        virtual void writeStartObject(const WriteStartObjectInput&) override;
         virtual void writeEndObject() override;
-        virtual void writeStartList() override;
+        virtual void writeStartList(const WriteStartListInput&) override;
         virtual void writeEndList() override;
-        virtual void writeStartDict() override;
+        virtual void writeStartDict(const WriteStartDictInput&) override;
         virtual void writeEndDict() override;
-        virtual void writeStartTuple() override;
+        virtual void writeStartTuple(const WriteStartTupleInput&) override;
         virtual void writeEndTuple() override;
-        virtual void writeStartPair() override;
+        virtual void writeStartPair(const WriteStartPairInput&) override;
         virtual void writeEndPair() override;
 
-        virtual void writeEigenMatrix(const std::vector<int>&, const std::string&) override;
-        virtual void writeEigenQuaternion(const std::string&) override;
-        virtual void writeIVTCByteImage(unsigned int w, unsigned int h, const std::string&) override;
-        virtual void writeOpenCVMat(const std::vector<int>&, const std::string&) override;
-        virtual void writePCLPointCloud(unsigned int w, unsigned int h, const std::string&) override;
-        virtual void writePosition() override;
-        virtual void writeOrientation() override;
-        virtual void writePose() override;
+        virtual void writeEigenMatrix(const WriteEigenMatrixInput&) override;
+        virtual void writeEigenQuaternion(const WriteEigenQuaternionInput&) override;
+        virtual void writeIVTCByteImage(const WriteIVTCByteImageInput&) override;
+        virtual void writeOpenCVMat(const WriteOpenCVMatInput&) override;
+        virtual void writePCLPointCloud(const WritePCLPointCloudInput&) override;
+        virtual void writePosition(const WritePositionInput&) override;
+        virtual void writeOrientation(const WriteOrientationInput&) override;
+        virtual void writePose(const WritePoseInput&) override;
 
-        virtual void writeInt() override;
-        virtual void writeLong() override;
-        virtual void writeFloat() override;
-        virtual void writeDouble() override;
-        virtual void writeString() override;
-        virtual void writeBool() override;
-        virtual void writeTime() override;
+        virtual void writeInt(const WritePrimitiveInput&) override;
+        virtual void writeLong(const WritePrimitiveInput&) override;
+        virtual void writeFloat(const WritePrimitiveInput&) override;
+        virtual void writeDouble(const WritePrimitiveInput&) override;
+        virtual void writeString(const WritePrimitiveInput&) override;
+        virtual void writeBool(const WritePrimitiveInput&) override;
+        virtual void writeTime(const WritePrimitiveInput&) override;
 
         virtual void writeKey(const std::string&) override;
 
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
index 0f3e96192..af8b31837 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
@@ -26,10 +26,11 @@
 namespace armarx::aron::typeIO::writer
 {
 
-    void NlohmannJSONWriter::writeStartObject(const std::string& n)
+    void NlohmannJSONWriter::writeStartObject(const WriteStartObjectInput& o)
     {
         nlohmann::json data;
-        data[io::Data::READER_WRITER_NAME_SLUG] = n;
+        data[io::Data::READER_WRITER_NAME_SLUG] = o.name;
+        data[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eObject, data);
         stack.push(new_token);
     }
@@ -46,9 +47,10 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NlohmannJSONWriter::writeStartList()
+    void NlohmannJSONWriter::writeStartList(const WriteStartListInput& o)
     {
         nlohmann::json data;
+        data[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eList, data);
         stack.push(new_token);
     }
@@ -65,9 +67,10 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NlohmannJSONWriter::writeStartDict()
+    void NlohmannJSONWriter::writeStartDict(const WriteStartDictInput& o)
     {
         nlohmann::json data;
+        data[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eDict, data);
         stack.push(new_token);
     }
@@ -84,9 +87,10 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NlohmannJSONWriter::writeStartTuple()
+    void NlohmannJSONWriter::writeStartTuple(const WriteStartTupleInput& o)
     {
         nlohmann::json data;
+        data[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eTuple, data);
         stack.push(new_token);
     }
@@ -103,9 +107,10 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NlohmannJSONWriter::writeStartPair()
+    void NlohmannJSONWriter::writeStartPair(const WriteStartPairInput& o)
     {
         nlohmann::json data;
+        data[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::ePair, data);
         stack.push(new_token);
     }
@@ -122,125 +127,147 @@ namespace armarx::aron::typeIO::writer
         }
     }
 
-    void NlohmannJSONWriter::writeEigenMatrix(const std::vector<int>& dims, const std::string& t)
+    void NlohmannJSONWriter::writeEigenMatrix(const WriteEigenMatrixInput& o)
     {
         auto token = stack.top();
         nlohmann::json j;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         j[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] = "EigenMatrix";
-        j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG] = dims;
-        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = t;
+        j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG] = o.dimensions;
+        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = o.type;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeEigenQuaternion(const std::string& t)
+    void NlohmannJSONWriter::writeEigenQuaternion(const WriteEigenQuaternionInput& o)
     {
         auto token = stack.top();
         nlohmann::json j;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         j[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] = "EigenQuaternion";
-        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = t;
+        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = o.type;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeIVTCByteImage(unsigned int w, unsigned int h, const std::string& t)
+    void NlohmannJSONWriter::writeIVTCByteImage(const WriteIVTCByteImageInput& o)
     {
         auto token = stack.top();
         nlohmann::json j;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         j[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] = "IVTCByteImage";
-        j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG] = {w, h};
-        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = t;
+        j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG] = {o.width, o.height};
+        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = o.type;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeOpenCVMat(const std::vector<int>& dims, const std::string& t)
+    void NlohmannJSONWriter::writeOpenCVMat(const WriteOpenCVMatInput& o)
     {
         auto token = stack.top();
         nlohmann::json j;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         j[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] = "OpenCVMat";
-        j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG] = dims;
-        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = t;
+        j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG] = o.dimensions;
+        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = o.type;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writePCLPointCloud(unsigned int w, unsigned int h, const std::string& t)
+    void NlohmannJSONWriter::writePCLPointCloud(const WritePCLPointCloudInput& o)
     {
         auto token = stack.top();
         nlohmann::json j;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         j[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] = "PCLPointCloud";
-        j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG] = {w, h};
-        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = t;
+        j[io::Data::READER_WRITER_NDARRAY_DIMENSIONS_SLUG] = {o.width, o.height};
+        j[io::Data::READER_WRITER_NDARRAY_TYPE_SLUG] = o.type;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writePosition()
+    void NlohmannJSONWriter::writePosition(const WritePositionInput& o)
     {
         auto token = stack.top();
         nlohmann::json j;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         j[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] = "Position";
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeOrientation()
+    void NlohmannJSONWriter::writeOrientation(const WriteOrientationInput& o)
     {
         auto token = stack.top();
         nlohmann::json j;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         j[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] = "Orientation";
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writePose()
+    void NlohmannJSONWriter::writePose(const WritePoseInput& o)
     {
         auto token = stack.top();
         nlohmann::json j;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         j[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] = "Pose";
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeInt()
+    void NlohmannJSONWriter::writeInt(const WritePrimitiveInput& o)
     {
         auto token = stack.top();
-        nlohmann::json j(io::Data::READER_WRITER_INT_TYPENAME_SLUG);
+        nlohmann::json j;
+        j[io::Data::READER_WRITER_PRIMITIVE_NAME_SLUG] = io::Data::READER_WRITER_INT_TYPENAME_SLUG;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeLong()
+    void NlohmannJSONWriter::writeLong(const WritePrimitiveInput& o)
     {
         auto token = stack.top();
-        nlohmann::json j(io::Data::READER_WRITER_LONG_TYPENAME_SLUG);
+        nlohmann::json j;
+        j[io::Data::READER_WRITER_PRIMITIVE_NAME_SLUG] = io::Data::READER_WRITER_LONG_TYPENAME_SLUG;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeFloat()
+    void NlohmannJSONWriter::writeFloat(const WritePrimitiveInput& o)
     {
         auto token = stack.top();
-        nlohmann::json j(io::Data::READER_WRITER_FLOAT_TYPENAME_SLUG);
+        nlohmann::json j;
+        j[io::Data::READER_WRITER_PRIMITIVE_NAME_SLUG] = io::Data::READER_WRITER_FLOAT_TYPENAME_SLUG;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeDouble()
+    void NlohmannJSONWriter::writeDouble(const WritePrimitiveInput& o)
     {
         auto token = stack.top();
-        nlohmann::json j(io::Data::READER_WRITER_DOUBLE_TYPENAME_SLUG);
+        nlohmann::json j;
+        j[io::Data::READER_WRITER_PRIMITIVE_NAME_SLUG] = io::Data::READER_WRITER_DOUBLE_TYPENAME_SLUG;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeString()
+    void NlohmannJSONWriter::writeString(const WritePrimitiveInput& o)
     {
         auto token = stack.top();
-        nlohmann::json j(io::Data::READER_WRITER_STRING_TYPENAME_SLUG);
+        nlohmann::json j;
+        j[io::Data::READER_WRITER_PRIMITIVE_NAME_SLUG] = io::Data::READER_WRITER_STRING_TYPENAME_SLUG;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeBool()
+    void NlohmannJSONWriter::writeBool(const WritePrimitiveInput& o)
     {
         auto token = stack.top();
-        nlohmann::json j(io::Data::READER_WRITER_BOOL_TYPENAME_SLUG);
+        nlohmann::json j;
+        j[io::Data::READER_WRITER_PRIMITIVE_NAME_SLUG] = io::Data::READER_WRITER_BOOL_TYPENAME_SLUG;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         token->addElement(j);
     }
 
-    void NlohmannJSONWriter::writeTime()
+    void NlohmannJSONWriter::writeTime(const WritePrimitiveInput& o)
     {
         auto token = stack.top();
-        nlohmann::json j(io::Data::READER_WRITER_TIME_TYPENAME_SLUG);
+        nlohmann::json j;
+        j[io::Data::READER_WRITER_PRIMITIVE_NAME_SLUG] = io::Data::READER_WRITER_TIME_TYPENAME_SLUG;
+        j[io::Data::READER_WRITER_OPTIONAL_SLUG] = o.is_optional;
         token->addElement(j);
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h
index 7826f895e..3be0f4a13 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h
@@ -40,33 +40,33 @@ namespace armarx::aron::typeIO::writer
     public:
         NlohmannJSONWriter() = default;
 
-        virtual void writeStartObject(const std::string&) override;
+        virtual void writeStartObject(const WriteStartObjectInput&) override;
         virtual void writeEndObject() override;
-        virtual void writeStartList() override;
+        virtual void writeStartList(const WriteStartListInput&) override;
         virtual void writeEndList() override;
-        virtual void writeStartDict() override;
+        virtual void writeStartDict(const WriteStartDictInput&) override;
         virtual void writeEndDict() override;
-        virtual void writeStartTuple() override;
+        virtual void writeStartTuple(const WriteStartTupleInput&) override;
         virtual void writeEndTuple() override;
-        virtual void writeStartPair() override;
+        virtual void writeStartPair(const WriteStartPairInput&) override;
         virtual void writeEndPair() override;
 
-        virtual void writeEigenMatrix(const std::vector<int>&, const std::string&) override;
-        virtual void writeEigenQuaternion(const std::string&) override;
-        virtual void writeIVTCByteImage(unsigned int w, unsigned int h, const std::string&) override;
-        virtual void writeOpenCVMat(const std::vector<int>&, const std::string&) override;
-        virtual void writePCLPointCloud(unsigned int w, unsigned int h, const std::string&) override;
-        virtual void writePosition() override;
-        virtual void writeOrientation() override;
-        virtual void writePose() override;
+        virtual void writeEigenMatrix(const WriteEigenMatrixInput&) override;
+        virtual void writeEigenQuaternion(const WriteEigenQuaternionInput&) override;
+        virtual void writeIVTCByteImage(const WriteIVTCByteImageInput&) override;
+        virtual void writeOpenCVMat(const WriteOpenCVMatInput&) override;
+        virtual void writePCLPointCloud(const WritePCLPointCloudInput&) override;
+        virtual void writePosition(const WritePositionInput&) override;
+        virtual void writeOrientation(const WriteOrientationInput&) override;
+        virtual void writePose(const WritePoseInput&) override;
 
-        virtual void writeInt() override;
-        virtual void writeLong() override;
-        virtual void writeFloat() override;
-        virtual void writeDouble() override;
-        virtual void writeString() override;
-        virtual void writeBool() override;
-        virtual void writeTime() override;
+        virtual void writeInt(const WritePrimitiveInput&) override;
+        virtual void writeLong(const WritePrimitiveInput&) override;
+        virtual void writeFloat(const WritePrimitiveInput&) override;
+        virtual void writeDouble(const WritePrimitiveInput&) override;
+        virtual void writeString(const WritePrimitiveInput&) override;
+        virtual void writeBool(const WritePrimitiveInput&) override;
+        virtual void writeTime(const WritePrimitiveInput&) override;
 
         virtual void writeKey(const std::string&) override;
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.cpp
index 6806d9dd4..ed82f0a7e 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.cpp
@@ -29,6 +29,7 @@
 
 // ArmarX
 #include <RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.h>
+#include <RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.h>
 #include <RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.h>
 #include <RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.h>
 #include <RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.h>
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/AllNavigators.h b/source/RobotAPI/libraries/aron/core/navigator/type/AllNavigators.h
index d1b5b03a2..6e41b9cd9 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/AllNavigators.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/AllNavigators.h
@@ -5,6 +5,7 @@
 #include "container/Object.h"
 #include "container/Pair.h"
 #include "container/Tuple.h"
+#include "ndarray/NDArray.h"
 #include "ndarray/EigenMatrix.h"
 #include "ndarray/EigenQuaternion.h"
 #include "ndarray/IVTCByteImage.h"
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/Navigator.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/Navigator.cpp
index 1e38841d2..d79127245 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/Navigator.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/Navigator.cpp
@@ -62,79 +62,6 @@ namespace armarx::aron::typenavigator
             throw error::AronException(c, m, "Could not cast an NavigatorPtr. The Ptr was NULL.", p);
         }
     }
-
-    /* AronSingleAcceptedTypeHavingTypeNavigator */
-    /*NavigatorPtr AronSingleAcceptedTypeHavingTypeNavigator::getAcceptedType() const
-    {
-        return acceptedTypeNavigator;
-    }
-
-    size_t AronSingleAcceptedTypeHavingTypeNavigator::childrenSize() const
-    {
-        return 1;
-    }*/
-
-    /* AronMultipleListAcceptedTypeHavingTypeNavigator */
-    /*std::vector<NavigatorPtr> AronMultipleListAcceptedTypeHavingTypeNavigator::getAcceptedTypes() const
-    {
-        return acceptedTypeNavigators;
-    }
-
-    NavigatorPtr AronMultipleListAcceptedTypeHavingTypeNavigator::getAcceptedType(unsigned int i) const
-    {
-        if (i >= acceptedTypeNavigators.size())
-        {
-            return nullptr;
-        }
-        return acceptedTypeNavigators[i];
-    }
-
-    size_t AronMultipleListAcceptedTypeHavingTypeNavigator::childrenSize() const
-    {
-        return acceptedTypeNavigators.size();
-    }*/
-
-    /* AronMultipleDictAcceptedTypeHavingTypeNavigator */
-    /*std::map<std::string, NavigatorPtr> AronMultipleDictAcceptedTypeHavingTypeNavigator::getAcceptedTypes() const
-    {
-        return acceptedTypeNavigators;
-    }
-
-    NavigatorPtr AronMultipleDictAcceptedTypeHavingTypeNavigator::getAcceptedType(const std::string& s) const
-    {
-        if (acceptedTypeNavigators.find(s) == acceptedTypeNavigators.end())
-        {
-            return nullptr;
-        }
-        return acceptedTypeNavigators.at(s);
-    }
-
-    size_t AronMultipleDictAcceptedTypeHavingTypeNavigator::childrenSize() const
-    {
-        return acceptedTypeNavigators.size();
-    }
-
-    std::vector<std::string> AronMultipleDictAcceptedTypeHavingTypeNavigator::getAllKeys() const
-    {
-        std::vector<std::string> ret;
-        for (const auto& [key, _] : acceptedTypeNavigators)
-        {
-            ret.push_back(key);
-        }
-        return ret;
-    }*/
-
-    /* AronComplexTypeNavigator */
-    /*size_t AronComplexTypeNavigator::childrenSize() const
-    {
-        return 0;
-    }*/
-
-    /* AronPrimitiveTypeNavigator */
-    /*size_t AronPrimitiveTypeNavigator::childrenSize() const
-    {
-        return 0;
-    }*/
 }
 
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/Navigator.h b/source/RobotAPI/libraries/aron/core/navigator/type/Navigator.h
index 863cfac1c..b49f59f6c 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/Navigator.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/Navigator.h
@@ -62,6 +62,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override = 0;
         virtual std::string getName() const override = 0;
 
+        virtual void setOptional(bool v) = 0;
+        virtual bool isOptional() const = 0;
+
         // static methods
         static NavigatorPtr FromAronType(const type::AronTypePtr&, const Path& = Path());
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/container/Dict.cpp
index fd14e22ea..386b276aa 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Dict.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Dict.cpp
@@ -39,10 +39,9 @@ namespace armarx::aron::typenavigator
     DictNavigator::DictNavigator(const type::AronDictPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eDict, path),
         Navigator(type::Descriptor::eDict, path),
-        type(o)
+        acceptedType(FromAronType(o->acceptedType)),
+        type(new type::AronDict(*o))
     {
-        CheckAronPtrForNull("DictNavigator", "DictNavigator", getPath(), o);
-        acceptedType = FromAronType(o->acceptedType);
     }
 
     NavigatorPtr DictNavigator::getAcceptedType() const
@@ -97,5 +96,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronDictType<" + acceptedType->getName() + ">";
     }
+
+    void DictNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool DictNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Dict.h b/source/RobotAPI/libraries/aron/core/navigator/type/container/Dict.h
index 08ba52bed..50e33e47d 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Dict.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Dict.h
@@ -56,10 +56,13 @@ namespace armarx::aron::typenavigator
         static DictNavigatorPtr DynamicCastAndCheck(const NavigatorPtr& n);
 
         // virtual implementations
-        virtual std::vector<NavigatorPtr> getChildren() const override;
-        virtual size_t childrenSize() const override;
-        virtual type::AronTypePtr getResult() const override;
-        virtual std::string getName() const override;
+        std::vector<NavigatorPtr> getChildren() const override;
+        size_t childrenSize() const override;
+        type::AronTypePtr getResult() const override;
+        std::string getName() const override;
+
+        void setOptional(bool v) override;
+        bool isOptional() const override;
 
     private:
         // members
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/List.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/container/List.cpp
index 3e87c4d5f..690d50557 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/List.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/List.cpp
@@ -37,10 +37,9 @@ namespace armarx::aron::typenavigator
     ListNavigator::ListNavigator(const type::AronListPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eList, path),
         Navigator(type::Descriptor::eList, path),
-        type(o)
+        acceptedType(FromAronType(o->acceptedType)),
+        type(new type::AronList(*o))
     {
-        CheckAronPtrForNull("ListNavigator", "ListNavigator", getPath(), o);
-        acceptedType = FromAronType(o->acceptedType);
     }
 
     // Member functions
@@ -96,4 +95,14 @@ namespace armarx::aron::typenavigator
     {
         return "AronListType<" + acceptedType->getName() + ">";
     }
+
+    void ListNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool ListNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/List.h b/source/RobotAPI/libraries/aron/core/navigator/type/container/List.h
index 2dac8bebb..17dc3deca 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/List.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/List.h
@@ -61,6 +61,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     private:
         // members
         NavigatorPtr acceptedType;
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp
index bc030f335..32e8b09e0 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp
@@ -50,10 +50,8 @@ namespace armarx::aron::typenavigator
     ObjectNavigator::ObjectNavigator(const type::AronObjectPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eObject, path),
         Navigator(type::Descriptor::eObject, path),
-        type(o)
+        type(new type::AronObject(*o))
     {
-        CheckAronPtrForNull("ObjectNavigator", "ObjectNavigator", getPath(), o);
-
         for (const auto& [key, t] : o->elementTypes)
         {
             memberTypes[key] = FromAronType(t);
@@ -180,5 +178,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronObjectType<" + type->objectName + ">";
     }
+
+    void ObjectNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool ObjectNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.h b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.h
index 47d501628..b22989f52 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.h
@@ -74,6 +74,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     private:
         // members
         ObjectNavigatorPtr extends;
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Pair.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/container/Pair.cpp
index 60e8947d4..95c4edca4 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Pair.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Pair.cpp
@@ -39,12 +39,10 @@ namespace armarx::aron::typenavigator
     PairNavigator::PairNavigator(const type::AronPairPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::ePair, path),
         Navigator(type::Descriptor::ePair, path),
-        type(o)
+        acceptedType1(FromAronType(o->acceptedType1)),
+        acceptedType2(FromAronType(o->acceptedType2)),
+        type(new type::AronPair(*o))
     {
-        CheckAronPtrForNull("AronPairTypeNavigator", "AronPairTypeNavigator", getPath(), o);
-
-        acceptedType1 = FromAronType(o->acceptedType1);
-        acceptedType2 = FromAronType(o->acceptedType2);
     }
 
     // Member functions
@@ -131,5 +129,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronPairType<" + acceptedType1->getName() + ", " + acceptedType2->getName() + ">";
     }
+
+    void PairNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool PairNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Pair.h b/source/RobotAPI/libraries/aron/core/navigator/type/container/Pair.h
index 999a6c856..85da737c9 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Pair.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Pair.h
@@ -65,6 +65,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     private:
         // members
         NavigatorPtr acceptedType1;
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Tuple.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/container/Tuple.cpp
index 14a94b890..cf76c0afa 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Tuple.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Tuple.cpp
@@ -38,10 +38,8 @@ namespace armarx::aron::typenavigator
     TupleNavigator::TupleNavigator(const type::AronTuplePtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eTuple, path),
         Navigator(type::Descriptor::eTuple, path),
-        type(o)
+        type(new type::AronTuple(*o))
     {
-        CheckAronPtrForNull("TupleNavigator", "TupleNavigator", getPath(), o);
-
         for (const auto& t : type->elementTypes)
         {
             acceptedTypes.push_back(FromAronType(t));
@@ -114,5 +112,15 @@ namespace armarx::aron::typenavigator
         }
         return "AronTupleType<" + simox::alg::to_string(names, ", ") + ">";
     }
+
+    void TupleNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool TupleNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Tuple.h b/source/RobotAPI/libraries/aron/core/navigator/type/container/Tuple.h
index 83348835c..11275bc0b 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Tuple.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Tuple.h
@@ -62,6 +62,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     private:
         std::vector<NavigatorPtr> acceptedTypes;
         type::AronTuplePtr type;
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/enum/IntEnum.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/enum/IntEnum.cpp
index 682a177ea..26791f2d6 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/enum/IntEnum.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/enum/IntEnum.cpp
@@ -37,9 +37,8 @@ namespace armarx::aron::typenavigator
     IntEnumNavigator::IntEnumNavigator(const type::AronIntEnumPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eIntEnum, path),
         Navigator(type::Descriptor::eIntEnum, path),
-        type(o)
+        type(new type::AronIntEnum(*o))
     {
-        CheckAronPtrForNull("AronEnumTypeNavigator", "AronEnumTypeNavigator", getPath(), o);
     }
 
     std::map<std::string, int> IntEnumNavigator::getAcceptedValues() const
@@ -118,5 +117,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronIntEnumType";
     }
+
+    void IntEnumNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool IntEnumNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/enum/IntEnum.h b/source/RobotAPI/libraries/aron/core/navigator/type/enum/IntEnum.h
index 9556a9d48..f10ac7a31 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/enum/IntEnum.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/enum/IntEnum.h
@@ -67,6 +67,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
 
     private:
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.cpp
index cb76098c3..064e71c77 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.cpp
@@ -30,16 +30,18 @@ namespace armarx::aron::typenavigator
     EigenMatrixNavigator::EigenMatrixNavigator(const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eEigenMatrix, path),
         Navigator(type::Descriptor::eEigenMatrix, path),
-        type(new type::AronEigenMatrix({1, 1}, ""))
+        type(new type::AronEigenMatrix(false,
+    {
+        1, 1
+    }, ""))
     {
     }
 
     EigenMatrixNavigator::EigenMatrixNavigator(const type::AronEigenMatrixPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eDict, path),
         Navigator(type::Descriptor::eEigenMatrix, path),
-        type(o)
+        type(new type::AronEigenMatrix(*o))
     {
-        CheckAronPtrForNull("AronEigenMatrixNavigator", "AronEigenMatrixNavigator", getPath(), o);
         checkDimensions(type->dimensions);
         checkTypename(type->typeName);
     }
@@ -169,5 +171,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronEigenMatrix<" + simox::alg::to_string(type->dimensions, ", ") + ", " + type->typeName + ">";
     }
+
+    void EigenMatrixNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool EigenMatrixNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.h
index 0fb7d9a71..4cf1839f0 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenMatrix.h
@@ -72,6 +72,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
         const std::map<std::string, std::vector<std::string>> ACCEPTED_TYPES =
         {
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.cpp
index 7ec0c21db..b4d8ed39e 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.cpp
@@ -30,16 +30,15 @@ namespace armarx::aron::typenavigator
     EigenQuaternionNavigator::EigenQuaternionNavigator(const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eEigenQuaternion, path),
         Navigator(type::Descriptor::eEigenQuaternion, path),
-        type(new type::AronEigenQuaternion(""))
+        type(new type::AronEigenQuaternion(false, ""))
     {
     }
 
     EigenQuaternionNavigator::EigenQuaternionNavigator(const type::AronEigenQuaternionPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eEigenQuaternion, path),
         Navigator(type::Descriptor::eEigenQuaternion, path),
-        type(o)
+        type(new type::AronEigenQuaternion(*o))
     {
-        CheckAronPtrForNull("AronEigenQuaternionTypeNavigator", "AronEigenQuaternionTypeNavigator", getPath(), o);
     }
 
     bool EigenQuaternionNavigator::checkTypename(const std::string& s) const
@@ -115,5 +114,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronEigenQuaternionType<" + simox::alg::to_string(ACCEPTED_DIMENSION, ", ") + ", " + type->typeName + ">";
     }
+
+    void EigenQuaternionNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool EigenQuaternionNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.h
index 1f388fdf5..8ea5977f7 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/EigenQuaternion.h
@@ -66,6 +66,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
         const std::map<std::string, std::vector<std::string>> ACCEPTED_TYPES =
         {
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/IVTCByteImage.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/IVTCByteImage.cpp
index 8d76320d4..8155f1be1 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/IVTCByteImage.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/IVTCByteImage.cpp
@@ -30,16 +30,15 @@ namespace armarx::aron::typenavigator
     IVTCByteImageNavigator::IVTCByteImageNavigator(const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eIVTCByteImage, path),
         Navigator(type::Descriptor::eIVTCByteImage, path),
-        type(new type::AronIVTCByteImage(0, 0, ""))
+        type(new type::AronIVTCByteImage(false, 0, 0, ""))
     {
     }
 
     IVTCByteImageNavigator::IVTCByteImageNavigator(const type::AronIVTCByteImagePtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eIVTCByteImage, path),
         Navigator(type::Descriptor::eIVTCByteImage, path),
-        type(o)
+        type(new type::AronIVTCByteImage(*o))
     {
-        CheckAronPtrForNull("AronIVTCByteImageTypeNavigator", "AronIVTCByteImageTypeNavigator", getPath(), o);
     }
 
     std::string IVTCByteImageNavigator::checkTypename(const std::string& s) const
@@ -145,5 +144,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronIVTCByteImageType<" + simox::alg::to_string(getDimensions(), ", ") + ", " + type->typeName + ">";
     }
+
+    void IVTCByteImageNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool IVTCByteImageNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/IVTCByteImage.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/IVTCByteImage.h
index aeaf5a3c7..3fd5f987a 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/IVTCByteImage.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/IVTCByteImage.h
@@ -70,6 +70,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
         const std::map<std::string, std::vector<std::string>> ACCEPTED_TYPES =
         {
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.cpp
new file mode 100644
index 000000000..e2b8c7158
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.cpp
@@ -0,0 +1,129 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
+ * Karlsruhe Institute of Technology (KIT), all rights reserved.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Peller-Konrad (fabian dot peller-konrad at kit dot edu)
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+// Header
+#include "NDArray.h"
+
+namespace armarx::aron::typenavigator
+{
+    // constructors
+    NDArrayNavigator::NDArrayNavigator(const Path& path) :
+        aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eNDArray, path),
+        Navigator(type::Descriptor::eNDArray, path),
+        type(new type::AronNDArray(false, {}, 0, ""))
+    {
+    }
+
+    NDArrayNavigator::NDArrayNavigator(const type::AronNDArrayPtr& o, const Path& path) :
+        aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eNDArray, path),
+        Navigator(type::Descriptor::eNDArray, path),
+        type(new type::AronNDArray(*o))
+    {
+    }
+
+    type::AronNDArrayPtr NDArrayNavigator::toAronNDArrayPtr() const
+    {
+        return type;
+    }
+
+    std::vector<int> NDArrayNavigator::getDimensions() const
+    {
+        return type->dimensions;
+    }
+
+    std::string NDArrayNavigator::getTypename() const
+    {
+        return type->typeName;
+    }
+
+    unsigned int NDArrayNavigator::getElementSize() const
+    {
+        return type->elementSize;
+    }
+
+    void NDArrayNavigator::setTypename(const std::string& s)
+    {
+        type->typeName = s;
+    }
+
+    void NDArrayNavigator::setDimensions(const std::vector<int>& v)
+    {
+        type->dimensions = v;
+    }
+
+    void NDArrayNavigator::addDimension(int i)
+    {
+        type->dimensions.push_back(i);
+    }
+
+    void NDArrayNavigator::setElementSize(unsigned int i)
+    {
+        type->elementSize = i;
+    }
+
+    // static methods
+    NDArrayNavigatorPtr NDArrayNavigator::DynamicCast(const NavigatorPtr& n)
+    {
+        return std::dynamic_pointer_cast<NDArrayNavigator>(n);
+    }
+
+    NDArrayNavigatorPtr NDArrayNavigator::DynamicCastAndCheck(const NavigatorPtr& n)
+    {
+        CheckTypeNavigatorPtrForNull("AronNDArrayNavigator", "DynamicCast[Before]", n);
+        NDArrayNavigatorPtr casted = NDArrayNavigator::DynamicCast(n);
+        CheckTypeNavigatorPtrForNull("AronNDArrayNavigator", "DynamicCast[After]", n->getPath(), casted);
+        return casted;
+    }
+
+    // virtual implementations
+    std::vector<NavigatorPtr> NDArrayNavigator::getChildren() const
+    {
+        return {};
+    }
+
+    size_t NDArrayNavigator::childrenSize() const
+    {
+        return 0;
+    }
+
+    type::AronTypePtr NDArrayNavigator::getResult() const
+    {
+        return toAronNDArrayPtr();
+    }
+
+    std::string NDArrayNavigator::getName() const
+    {
+        return "AronPoseType";
+    }
+
+    void NDArrayNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool NDArrayNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
+}
+
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.h
new file mode 100644
index 000000000..44f384402
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.h
@@ -0,0 +1,77 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
+ * Karlsruhe Institute of Technology (KIT), all rights reserved.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Peller-Konrad (fabian dot peller-konrad at kit dot edu)
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+// STD/STL
+#include <string>
+#include <map>
+
+// Base Class
+#include <RobotAPI/libraries/aron/core/navigator/type/Navigator.h>
+
+namespace armarx::aron::typenavigator
+{
+    class NDArrayNavigator;
+    typedef std::shared_ptr<NDArrayNavigator> NDArrayNavigatorPtr;
+
+    class NDArrayNavigator :
+        virtual public Navigator
+    {
+    public:
+        using PointerType = NDArrayNavigatorPtr;
+
+    public:
+        // constructors
+        NDArrayNavigator(const Path& path = Path());
+        NDArrayNavigator(const type::AronNDArrayPtr&, const Path& path = Path());
+
+        std::string getTypename() const;
+        std::vector<int> getDimensions() const;
+        unsigned int getElementSize() const;
+
+        void setTypename(const std::string&);
+        void setDimensions(const std::vector<int>&);
+        void addDimension(int);
+        void setElementSize(unsigned int);
+
+        type::AronNDArrayPtr toAronNDArrayPtr() const;
+
+        // static methods
+        static NDArrayNavigatorPtr DynamicCast(const NavigatorPtr& n);
+        static NDArrayNavigatorPtr DynamicCastAndCheck(const NavigatorPtr& n);
+
+        // virtual implementations
+        virtual std::vector<NavigatorPtr> getChildren() const override;
+        virtual size_t childrenSize() const override;
+        virtual type::AronTypePtr getResult() const override;
+        virtual std::string getName() const override;
+
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
+    private:
+        // members
+        type::AronNDArrayPtr type;
+    };
+}
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.cpp
index e0d159cc3..db77cf3ec 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.cpp
@@ -30,16 +30,15 @@ namespace armarx::aron::typenavigator
     OpenCVMatNavigator::OpenCVMatNavigator(const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eOpenCVMat, path),
         Navigator(type::Descriptor::eOpenCVMat, path),
-        type(new type::AronOpenCVMat({}, ""))
+        type(new type::AronOpenCVMat(false, {}, ""))
     {
     }
 
     OpenCVMatNavigator::OpenCVMatNavigator(const type::AronOpenCVMatPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eOpenCVMat, path),
         Navigator(type::Descriptor::eOpenCVMat, path),
-        type(o)
+        type(new type::AronOpenCVMat(*o))
     {
-        CheckAronPtrForNull("AronOpenCVMatTypeNavigator", "AronOpenCVMatTypeNavigator", getPath(), o);
         checkDimensions(type->dimensions);
         checkTypename(type->typeName);
     }
@@ -144,5 +143,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronOpenCVMatType<" + simox::alg::to_string(type->dimensions, ", ") + ", " + type->typeName + ">";
     }
+
+    void OpenCVMatNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool OpenCVMatNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.h
index 4a1c0a88f..18d61a3c0 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/OpenCVMat.h
@@ -68,6 +68,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
         const std::map<std::string, std::vector<std::string>> ACCEPTED_TYPES =
         {
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Orientation.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Orientation.cpp
index 13be796db..0e768b654 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Orientation.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Orientation.cpp
@@ -37,9 +37,8 @@ namespace armarx::aron::typenavigator
     OrientationNavigator::OrientationNavigator(const type::AronOrientationPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::eOrientation, path),
         Navigator(type::Descriptor::eOrientation, path),
-        type(o)
+        type(new type::AronOrientation(*o))
     {
-        CheckAronPtrForNull("AronOrientationTypeNavigator", "AronOrientationTypeNavigator", getPath(), o);
     }
 
     type::AronOrientationPtr OrientationNavigator::toAronOrientationPtr() const
@@ -91,5 +90,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronOrientationType";
     }
+
+    void OrientationNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool OrientationNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Orientation.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Orientation.h
index 4c9c9929b..001212b29 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Orientation.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Orientation.h
@@ -65,6 +65,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
         const std::string ACCEPTED_TYPE = "float";
         const std::vector<int> ACCEPTED_DIMENSION = {1, 4};
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/PCLPointCloud.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/PCLPointCloud.cpp
index 2de0158a8..5aa5cd89f 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/PCLPointCloud.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/PCLPointCloud.cpp
@@ -30,16 +30,15 @@ namespace armarx::aron::typenavigator
     PCLPointCloudNavigator::PCLPointCloudNavigator(const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::ePCLPointCloud, path),
         Navigator(type::Descriptor::ePCLPointCloud, path),
-        type(new type::AronPCLPointCloud(0, 0, ""))
+        type(new type::AronPCLPointCloud(false, 0, 0, ""))
     {
     }
 
     PCLPointCloudNavigator::PCLPointCloudNavigator(const type::AronPCLPointCloudPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::ePCLPointCloud, path),
         Navigator(type::Descriptor::ePCLPointCloud, path),
-        type(o)
+        type(new type::AronPCLPointCloud(*o))
     {
-        CheckAronPtrForNull("AronPCLPointCloudTypeNavigator", "AronPCLPointCloudTypeNavigator", getPath(), o);
         checkTypename(type->typeName);
     }
 
@@ -147,5 +146,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronPCLPointCloudType<" + simox::alg::to_string(getDimensions(), ", ") + ", " + type->typeName + ">";
     }
+
+    void PCLPointCloudNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool PCLPointCloudNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/PCLPointCloud.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/PCLPointCloud.h
index 2f62f1b57..d0ba9c448 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/PCLPointCloud.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/PCLPointCloud.h
@@ -70,6 +70,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
         const std::map<std::string, std::vector<std::string>> ACCEPTED_TYPES =
         {
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Pose.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Pose.cpp
index 8713907ec..0844950b9 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Pose.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Pose.cpp
@@ -37,9 +37,8 @@ namespace armarx::aron::typenavigator
     PoseNavigator::PoseNavigator(const type::AronPosePtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::ePose, path),
         Navigator(type::Descriptor::ePose, path),
-        type(o)
+        type(new type::AronPose(*o))
     {
-        CheckAronPtrForNull("AronPoseTypeNavigator", "AronPoseTypeNavigator", getPath(), o);
     }
 
     type::AronPosePtr PoseNavigator::toAronPosePtr() const
@@ -91,5 +90,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronPoseType";
     }
+
+    void PoseNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool PoseNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Pose.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Pose.h
index e99d0ea3b..a38aef961 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Pose.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Pose.h
@@ -61,6 +61,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override;
         virtual std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
         const std::string ACCEPTED_TYPE = "float";
         const std::vector<int> ACCEPTED_DIMENSION = {4, 4};
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Position.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Position.cpp
index 2172f431b..0fe6ed842 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Position.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Position.cpp
@@ -37,9 +37,8 @@ namespace armarx::aron::typenavigator
     PositionNavigator::PositionNavigator(const type::AronPositionPtr& o, const Path& path) :
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::ePosition, path),
         Navigator(type::Descriptor::ePosition, path),
-        type(o)
+        type(new type::AronPosition(*o))
     {
-        CheckAronPtrForNull("AronPositionTypeNavigator", "AronPositionTypeNavigator", getPath(), o);
     }
 
     type::AronPositionPtr PositionNavigator::toAronPositionPtr() const
@@ -91,5 +90,15 @@ namespace armarx::aron::typenavigator
     {
         return "AronPositionType";
     }
+
+    void PositionNavigator::setOptional(bool v)
+    {
+        type->is_optional = v;
+    }
+
+    bool PositionNavigator::isOptional() const
+    {
+        return type->is_optional;
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Position.h b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Position.h
index c6a1d0f73..36eccd67a 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Position.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/Position.h
@@ -61,6 +61,9 @@ namespace armarx::aron::typenavigator
         type::AronTypePtr getResult() const override;
         std::string getName() const override;
 
+        void setOptional(bool v) override;
+        bool isOptional() const override;
+
     public:
         const std::string ACCEPTED_TYPE = "float";
         const std::vector<int> ACCEPTED_DIMENSION = {3, 1};
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.cpp
index bebe31969..227155e7e 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.cpp
@@ -46,9 +46,8 @@ namespace armarx::aron::typenavigator
     upperType##Navigator::upperType##Navigator(const type::Aron##upperType##Ptr&o, const Path& path) : \
         aron::Navigator<type::Descriptor, type::AronType>::Navigator(type::Descriptor::e##upperType, path), \
         Navigator(type::Descriptor::e##upperType, path), \
-        type(o) \
+        type(new type::Aron##upperType(*o)) \
     { \
-        CheckAronPtrForNull("typenavigator::" + std::string(#upperType) + "Navigator", std::string(#upperType) + "Navigator", getPath(), o); \
     } \
     \
     type::Aron##upperType##Ptr upperType##Navigator::toAron##upperType##Ptr() const \
@@ -89,6 +88,16 @@ namespace armarx::aron::typenavigator
     std::string upperType##Navigator::getName() const \
     {\
         return "type::Aron" + std::string(#upperType); \
+    }\
+    \
+    void upperType##Navigator::setOptional(bool v) \
+    { \
+        type->is_optional = v; \
+    } \
+    \
+    bool upperType##Navigator::isOptional() const \
+    { \
+        return type->is_optional; \
     }
 
     HANDLE_PRIMITIVE_TYPES
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.h b/source/RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.h
index 9fe2fadf5..3841cd08d 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/primitive/Primitive.h
@@ -61,6 +61,9 @@ namespace armarx::aron::typenavigator
         virtual type::AronTypePtr getResult() const override; \
         virtual std::string getName() const override; \
         \
+        void setOptional(bool v) override; \
+        bool isOptional() const override; \
+        \
     private: \
         type::Aron##upperType##Ptr type; \
     };
diff --git a/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt b/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt
index de44d5a1d..d491c1236 100644
--- a/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt
+++ b/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt
@@ -57,5 +57,6 @@ armarx_enable_aron_file_generation_for_target(
         xmls/PoseTest.xml
         xmls/PositionTest.xml
         xmls/PrimitiveTest.xml
+        xmls/OptionalTest.xml
     #ENABLE_DEBUG_INFO
 )
diff --git a/source/RobotAPI/libraries/aron/core/test/aronTest.cpp b/source/RobotAPI/libraries/aron/core/test/aronTest.cpp
index e8fd551be..96c6a5c53 100644
--- a/source/RobotAPI/libraries/aron/core/test/aronTest.cpp
+++ b/source/RobotAPI/libraries/aron/core/test/aronTest.cpp
@@ -82,6 +82,7 @@
 #include <RobotAPI/libraries/aron/core/test/aron/OrientationTest.aron.generated.h>
 #include <RobotAPI/libraries/aron/core/test/aron/PoseTest.aron.generated.h>
 #include <RobotAPI/libraries/aron/core/test/aron/EnumTest.aron.generated.h>
+#include <RobotAPI/libraries/aron/core/test/aron/OptionalTest.aron.generated.h>
 
 using namespace armarx;
 using namespace aron;
@@ -350,3 +351,11 @@ BOOST_AUTO_TEST_CASE(AronPoseTest)
     PoseTest pc2;
     runTestWithInstances<PoseTest>(pc, pc2);
 }
+
+BOOST_AUTO_TEST_CASE(AronOptionalTest)
+{
+    std::cout << "Running Optional test" << std::endl;
+    OptionalTest pc;
+    OptionalTest pc2;
+    runTestWithInstances<OptionalTest>(pc, pc2);
+}
diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/OptionalTest.xml b/source/RobotAPI/libraries/aron/core/test/xmls/OptionalTest.xml
new file mode 100644
index 000000000..6ab102f24
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/test/xmls/OptionalTest.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<AronTypeDefinition>
+    <CodeIncludes>
+        <Include include="<Eigen/Core>" />
+    </CodeIncludes>
+    <GenerateTypes>
+        <Object name="armarx::OptionalTestElement">
+            <ObjectChild key="val">
+                <Float />
+            </ObjectChild>
+        </Object>
+        <Object name='armarx::OptionalTest'>
+
+            <ObjectChild key='some_float' optional="1">
+                <Float />
+            </ObjectChild>
+
+            <ObjectChild key='some_string' optional="true">
+                <String />
+            </ObjectChild>
+            
+            <ObjectChild key='some_dict' optional="wahr">
+                <Dict>
+                    <Float />
+                </Dict>
+            </ObjectChild>
+
+            <ObjectChild key='some_dict_with_optional_type'>
+                <Dict>
+                    <Float optional="true" />
+                </Dict>
+            </ObjectChild>
+
+            <ObjectChild key='some_list' optional="ja">
+                <List>
+                    <Double />
+                </List>
+            </ObjectChild>
+
+            <ObjectChild key='some_list_with_optional_type'>
+                <List>
+                    <Double optional="true"/>
+                </List>
+            </ObjectChild>
+
+            <ObjectChild key='some_obj' optional="ja">
+                <EigenMatrix rows="25" cols="10" type="long" />
+            </ObjectChild>
+
+            <ObjectChild key='some_obj' optional="ja">
+                <armarx::OptionalTestElement />
+            </ObjectChild>
+
+        </Object>
+    </GenerateTypes>
+</AronTypeDefinition>
-- 
GitLab