From a60f18389802bb1ec03dcee5adae69a5eb1229ca Mon Sep 17 00:00:00 2001
From: "fabian.peller-konrad@kit.edu" <fabian.peller-konrad@kit.edu>
Date: Tue, 4 May 2021 11:23:36 +0200
Subject: [PATCH] update for optional

---
 source/RobotAPI/interface/aron/Aron.ice       |  2 +-
 .../codeWriter/cpp/serializer/Serializer.cpp  | 38 ++++++--
 .../codeWriter/cpp/serializer/Serializer.h    |  4 +-
 .../cpp/serializer/container/Dict.cpp         | 43 ++++------
 .../cpp/serializer/container/Dict.h           |  2 +-
 .../cpp/serializer/container/List.cpp         | 25 ++----
 .../cpp/serializer/container/Object.cpp       | 31 +++++--
 .../cpp/serializer/container/Object.h         |  2 +-
 .../cpp/serializer/container/Pair.cpp         | 86 +++++++++----------
 .../cpp/serializer/container/Tuple.cpp        | 74 ++++++++--------
 .../cpp/serializer/enum/IntEnum.cpp           | 22 +++--
 .../codeWriter/cpp/serializer/enum/IntEnum.h  |  2 +-
 .../cpp/serializer/ndarray/EigenMatrix.cpp    |  8 +-
 .../serializer/ndarray/EigenQuaternion.cpp    | 10 +--
 .../cpp/serializer/ndarray/IVTCByteImage.cpp  |  6 +-
 .../cpp/serializer/ndarray/NDArray.cpp        |  4 +-
 .../cpp/serializer/ndarray/OpenCVMat.cpp      | 24 ++++--
 .../cpp/serializer/ndarray/Orientation.cpp    |  8 +-
 .../cpp/serializer/ndarray/PCLPointCloud.cpp  | 15 +++-
 .../cpp/serializer/ndarray/Pose.cpp           | 12 ++-
 .../cpp/serializer/ndarray/Position.cpp       | 12 ++-
 .../cpp/serializer/primitive/Primitive.cpp    |  9 +-
 .../cpp/serializer/toplevel/ObjectClass.cpp   | 18 +---
 .../libraries/aron/core/io/dataIO/Reader.cpp  | 40 ---------
 .../libraries/aron/core/io/dataIO/Reader.h    |  7 --
 .../libraries/aron/core/io/dataIO/Writer.cpp  |  6 ++
 .../libraries/aron/core/io/dataIO/Writer.h    |  5 +-
 .../aron/core/io/dataIO/reader/ReaderToken.h  |  1 +
 .../reader/navigator/NavigatorReader.cpp      |  7 +-
 .../reader/navigator/NavigatorReaderToken.h   | 21 +++++
 .../nlohmannJSON/NlohmannJSONReader.cpp       |  7 +-
 .../nlohmannJSON/NlohmannJSONReaderToken.h    | 21 ++++-
 .../writer/navigator/NavigatorWriter.cpp      |  8 +-
 .../dataIO/writer/navigator/NavigatorWriter.h |  3 +
 .../writer/navigator/NavigatorWriterToken.h   |  2 +
 .../nlohmannJSON/NlohmannJSONWriter.cpp       |  6 ++
 .../writer/nlohmannJSON/NlohmannJSONWriter.h  |  2 +
 .../aron/core/navigator/NavigatorFactory.h    |  3 +-
 .../core/navigator/data/NavigatorFactory.cpp  | 54 ++++++++++++
 .../core/navigator/data/NavigatorFactory.h    |  3 +-
 .../core/navigator/data/container/Dict.cpp    | 34 +++++++-
 .../core/navigator/data/container/List.cpp    | 37 +++++++-
 .../core/navigator/type/NavigatorFactory.cpp  |  5 ++
 .../core/navigator/type/NavigatorFactory.h    |  3 +-
 .../core/navigator/type/ndarray/NDArray.cpp   |  8 +-
 45 files changed, 460 insertions(+), 280 deletions(-)

diff --git a/source/RobotAPI/interface/aron/Aron.ice b/source/RobotAPI/interface/aron/Aron.ice
index 74bb97987..9b5e96712 100644
--- a/source/RobotAPI/interface/aron/Aron.ice
+++ b/source/RobotAPI/interface/aron/Aron.ice
@@ -57,7 +57,7 @@ module armarx
             class AronDict extends AronType { AronType acceptedType; }
 
             // Complex Types (serialize to ndarray)
-            class AronNDArray extends AronType { AronIntSequence dimensions; int elementSize; string typeName; }
+            class AronNDArray extends AronType { AronIntSequence dimensions; 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; }
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 3a8e511cd..c5d2bc671 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,15 +75,6 @@ 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;
@@ -125,6 +116,35 @@ namespace armarx::aron::cppcodegenerator
         return FACTORY->create(n, n->getPath());
     }
 
+
+    std::string Serializer::ResolveOptionalAccessor(const std::string& s, const typenavigator::NavigatorPtr& t)
+    {
+        if (t->isOptional())
+        {
+            return s + ".value()";
+        }
+        return s;
+    }
+
+    CppBlockPtr Serializer::ResolveOptionalBlock(const std::string& accessor, const CppBlockPtr& block_if_data, const typenavigator::NavigatorPtr& typenavigator)
+    {
+        if (typenavigator->isOptional())
+        {
+            CppBlockPtr b = std::make_shared<CppBlock>();
+            b->addLine("if (" + accessor + ".has_value())");
+            b->addBlock(block_if_data);
+            b->addLine("else");
+            CppBlockPtr block_if_no_data = std::make_shared<CppBlock>();
+            block_if_no_data->addLine("w.writeNull();");
+            b->addBlock(block_if_no_data);
+            return b;
+        }
+        else
+        {
+            return block_if_data;
+        }
+    }
+
     // constructors
     Serializer::Serializer(const std::string& cppName, const std::string& aronDataTypename, const std::string& aronTypeTypename, SerializerAccessType accessType) :
         accessType(accessType),
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 9e05d78b1..8115d8de8 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
@@ -117,7 +117,6 @@ namespace armarx::aron::cppcodegenerator
         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&);
 
@@ -126,6 +125,9 @@ namespace armarx::aron::cppcodegenerator
 
         static SerializerPtr FromAronTypeNaviagtorPtr(const typenavigator::NavigatorPtr&);
 
+        static std::string ResolveOptionalAccessor(const std::string&, const typenavigator::NavigatorPtr&);
+        static CppBlockPtr ResolveOptionalBlock(const std::string&, const CppBlockPtr&, const typenavigator::NavigatorPtr&);
+
     protected:
         std::string nextEl() const
         {
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 a34a8c5e1..a6978a13e 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
@@ -33,7 +33,7 @@ namespace armarx::aron::cppcodegenerator::serializer
                    simox::meta::get_type_name(typeid(data::AronDict)),
                    simox::meta::get_type_name(typeid(type::AronDict)),
                    (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
-        navigator(e)
+        typenavigator(e)
     {
 
     }
@@ -73,12 +73,12 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr DictSerializer::getWriteInitialTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartDict({" + std::string(navigator->isOptional() ? "true" : "false") + "});");
+        b->addLine("w.writeStartDict({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         std::string accessor_iterator = escaped_accessor + DICT_ITERATOR_ACCESSOR;
 
-        auto type_s = FromAronTypeNaviagtorPtr(navigator->getAcceptedType());
+        auto type_s = FromAronTypeNaviagtorPtr(typenavigator->getAcceptedType());
         CppBlockPtr b2 = type_s->getWriteInitialTypeBlock(type_s->getFullCppTypename());
         b->appendBlock(b2);
         b->addLine("w.writeEndDict();");
@@ -88,12 +88,12 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr DictSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartDict({" + std::string(navigator->isOptional() ? "true" : "false") + "});");
+        b->addLine("w.writeStartDict({" + std::string(typenavigator->isOptional() ? "true" : "false") + "});");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         std::string accessor_iterator = escaped_accessor + DICT_ITERATOR_ACCESSOR;
 
-        auto type_s = FromAronTypeNaviagtorPtr(navigator->getAcceptedType());
+        auto type_s = FromAronTypeNaviagtorPtr(typenavigator->getAcceptedType());
         CppBlockPtr b2 = type_s->getWriteCurrentTypeBlock(type_s->getFullCppTypename());
         b->appendBlock(b2);
         b->addLine("w.writeEndDict();");
@@ -102,50 +102,43 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr DictSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = std::make_shared<CppBlock>();
-        b->addLine("w.writeStartDict();");
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
+        block_if_data->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 + "] : " + resolved_accessor + ") ");
+        std::string resolved_accessor = ResolveOptionalAccessor(accessor, typenavigator);
 
-        auto type_s = FromAronTypeNaviagtorPtr(navigator->getAcceptedType());
+        block_if_data->addLine("for (const auto& [" + accessor_iterator_key + ", " + accessor_iterator_val + "] : " + resolved_accessor + ") ");
+
+        auto type_s = FromAronTypeNaviagtorPtr(typenavigator->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;
+        b2->appendBlock(type_s->getWriteBlock(accessor_iterator_val));
+        block_if_data->addBlock(b2);
+        block_if_data->addLine("w.writeEndDict();");
+
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr DictSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        if (navigator->isOptional())
-        {
-            b->addLine(accessor + ".emplace();");
-        }
-        else
-        {
-            b->addLine(accessor + " = {};");
-        }
-
         b->addLine("r.readStartDict();");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         std::string accessor_iterator = escaped_accessor + DICT_ITERATOR_ACCESSOR;
         std::string accessor_iterator_key = escaped_accessor + DICT_KEY_ACCESSOR;
 
-        auto type_s = FromAronTypeNaviagtorPtr(navigator->getAcceptedType());
+        auto type_s = FromAronTypeNaviagtorPtr(typenavigator->getAcceptedType());
 
         b->addLine("while(!r.readEndDict())");
         CppBlockPtr b2 = CppBlockPtr(new CppBlock());
         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->appendBlock(type_s->getReadBlock(accessor_iterator));
         b2->addLine(accessor + nextEl() + "insert({" + accessor_iterator_key + ", " + accessor_iterator + "});");
 
         b->addBlock(b2);
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.h
index 9e2e45976..99fa2f7ae 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.h
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.h
@@ -68,6 +68,6 @@ namespace armarx::aron::cppcodegenerator::serializer
         static constexpr const char* DICT_KEY_ACCESSOR = "_key";
         static constexpr const char* DICT_VALUE_ACCESSOR = "_value";
 
-        typenavigator::DictNavigatorPtr navigator;
+        typenavigator::DictNavigatorPtr typenavigator;
     };
 }
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 56dbe6ed8..5afe9e9b6 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
@@ -96,32 +96,23 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr ListSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartList();");
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->addLine("w.writeStartList();");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         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 + nextEl() + "size(); ++" + accessor_iterator + ")");
-        CppBlockPtr b2 = type_s->getWriteBlock(accessor + nextEl() + "at(" + accessor_iterator + ")");
-        b->addBlock(b2);
-        b->addLine("w.writeEndList();");
-        return b;
+        block_if_data->addLine("for(unsigned int " + accessor_iterator + " = 0; " + accessor_iterator + " < " + accessor + nextEl() + "size(); ++" + accessor_iterator + ")");
+        block_if_data->addBlock(type_s->getWriteBlock(accessor + nextEl() + "at(" + accessor_iterator + ")"));
+        block_if_data->addLine("w.writeEndList();");
+
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr ListSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        if (typenavigator->isOptional())
-        {
-            b->addLine(accessor + ".emplace();");
-        }
-        else
-        {
-            b->addLine(accessor + " = {};");
-        }
-
         b->addLine("r.readStartList();");
 
         std::string escaped_accessor = EscapeAccessor(accessor);
@@ -132,7 +123,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->appendBlock(type_s->getReadBlock(accessor_iterator));
         b2->addLine(accessor + nextEl() + "push_back(" + accessor_iterator + ");");
 
         b->addBlock(b2);
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 855fd6682..7e1aacd7e 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
@@ -33,7 +33,7 @@ namespace armarx::aron::cppcodegenerator::serializer
                    simox::meta::get_type_name(typeid(data::AronDict)),
                    simox::meta::get_type_name(typeid(type::AronObject)),
                    (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
-        navigator(e)
+        typenavigator(e)
     {
     }
 
@@ -57,36 +57,51 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr ObjectSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + nextEl() + "reset();");
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            b->addLine(accessor + nextEl() + "reset();");
+        }
         return b;
     }
 
     CppBlockPtr ObjectSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + nextEl() + "initialize();");
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            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, " + std::string(navigator->isOptional() ? "true" : "false") + ");");
+        b->addLine(accessor + "::writeInitialType(w, " + std::string(typenavigator->isOptional() ? "true" : "false") + ");");
         return b;
     }
 
     CppBlockPtr ObjectSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + nextEl() + "writeCurrentType(w, " + std::string(navigator->isOptional() ? "true" : "false") + ");");
+        b->addLine(accessor + nextEl() + "writeCurrentType(w, " + std::string(typenavigator->isOptional() ? "true" : "false") + ");");
         return b;
     }
 
     CppBlockPtr ObjectSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + nextEl() + "write(w);");
-        return b;
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->addLine(accessor + nextEl() + "write(w);");
+
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr ObjectSerializer::getReadBlock(const std::string& accessor) const
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.h
index b879a8794..226d08f67 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.h
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.h
@@ -66,6 +66,6 @@ namespace armarx::aron::cppcodegenerator::serializer
         // members
         static constexpr const char* EXTENDS_ITERATOR_ACCESSOR = "_extends";
 
-        typenavigator::ObjectNavigatorPtr navigator;
+        typenavigator::ObjectNavigatorPtr typenavigator;
     };
 }
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 9981bb644..56d0ff682 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
@@ -57,15 +57,40 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PairSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
+            CppBlockPtr b21 = child_s1->getInitializeBlock(accessor + nextEl() + "first");
+            b->appendBlock(b21);
 
-        auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
-        CppBlockPtr b21 = child_s1->getInitializeBlock(accessor + nextEl() + "first");
-        b->appendBlock(b21);
+            auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
+            CppBlockPtr b22 = child_s2->getInitializeBlock(accessor + nextEl() + "second");
+            b->appendBlock(b22);
+        }
+        return b;
+    }
 
-        auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
-        CppBlockPtr b22 = child_s2->getInitializeBlock(accessor + nextEl() + "second");
-        b->appendBlock(b22);
+    CppBlockPtr PairSerializer::getResetBlock(const std::string& accessor) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
+            CppBlockPtr b21 = child_s1->getResetBlock(accessor + nextEl() + "first");
+            b->appendBlock(b21);
 
+            auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
+            CppBlockPtr b22 = child_s2->getResetBlock(accessor + nextEl() + "second");
+            b->appendBlock(b22);
+        }
         return b;
     }
 
@@ -115,62 +140,35 @@ namespace armarx::aron::cppcodegenerator::serializer
         return b;
     }
 
-    CppBlockPtr PairSerializer::getResetBlock(const std::string& accessor) const
-    {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
-
-        auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
-        CppBlockPtr b21 = child_s1->getResetBlock(accessor + nextEl() + "first");
-        b->appendBlock(b21);
-
-        auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
-        CppBlockPtr b22 = child_s2->getResetBlock(accessor + nextEl() + "second");
-        b->appendBlock(b22);
-
-        return b;
-    }
-
     CppBlockPtr PairSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartList();");
-
-        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->addLine("w.writeStartList();");
 
         auto child_s1 = FromAronTypeNaviagtorPtr(typenavigator->getFirstAcceptedType());
-        CppBlockPtr b21 = child_s1->getWriteBlock(resolved_accessor + nextEl() + "first");
-        b->appendBlock(b21);
+        CppBlockPtr b21 = child_s1->getWriteBlock(accessor + nextEl() + "first");
+        block_if_data->appendBlock(b21);
 
         auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
-        CppBlockPtr b22 = child_s2->getWriteBlock(resolved_accessor + nextEl() + "second");
-        b->appendBlock(b22);
+        CppBlockPtr b22 = child_s2->getWriteBlock(accessor + nextEl() + "second");
+        block_if_data->appendBlock(b22);
 
-        b->addLine("w.writeEndList();");
-        return b;
+        block_if_data->addLine("w.writeEndList();");
+
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr PairSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        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(resolved_accessor + nextEl() + "first");
+        CppBlockPtr b21 = child_s1->getReadBlock(accessor + nextEl() + "first");
         b->appendBlock(b21);
 
         auto child_s2 = FromAronTypeNaviagtorPtr(typenavigator->getSecondAcceptedType());
-        CppBlockPtr b22 = child_s2->getReadBlock(resolved_accessor + nextEl() + "second");
+        CppBlockPtr b22 = child_s2->getReadBlock(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 7643ef634..9a8e86fbb 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
@@ -57,13 +57,39 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr TupleSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            unsigned int i = 0;
+            for (const auto& child : typenavigator->getAcceptedTypes())
+            {
+                auto child_s = FromAronTypeNaviagtorPtr(child);
+                CppBlockPtr b2 = child_s->getInitializeBlock("std::get<" + std::to_string(i++) + ">(" + accessor + ")");
+                b->appendBlock(b2);
+            }
+        }
+        return b;
+    }
 
-        unsigned int i = 0;
-        for (const auto& child : typenavigator->getAcceptedTypes())
+    CppBlockPtr TupleSerializer::getResetBlock(const std::string& accessor) const
+    {
+        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        if (typenavigator->isOptional())
         {
-            auto child_s = FromAronTypeNaviagtorPtr(child);
-            CppBlockPtr b2 = child_s->getInitializeBlock("std::get<" + std::to_string(i++) + ">(" + accessor + ")");
-            b->appendBlock(b2);
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            unsigned int i = 0;
+            for (const auto& type : typenavigator->getAcceptedTypes())
+            {
+                auto type_s = FromAronTypeNaviagtorPtr(type);
+                CppBlockPtr b2 = type_s->getResetBlock("std::get<" + std::to_string(i++) + ">(" + accessor + ")");
+                b->appendBlock(b2);
+            }
         }
         return b;
     }
@@ -106,53 +132,31 @@ namespace armarx::aron::cppcodegenerator::serializer
         return b;
     }
 
-    CppBlockPtr TupleSerializer::getResetBlock(const std::string& accessor) const
-    {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
-
-        unsigned int i = 0;
-        for (const auto& type : typenavigator->getAcceptedTypes())
-        {
-            auto type_s = FromAronTypeNaviagtorPtr(type);
-            CppBlockPtr b2 = type_s->getResetBlock("std::get<" + std::to_string(i++) + ">(" + accessor + ")");
-            b->appendBlock(b2);
-        }
-        return b;
-    }
-
     CppBlockPtr TupleSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine("w.writeStartList();");
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->addLine("w.writeStartList();");
 
-        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+        std::string resolved_accessor = ResolveOptionalAccessor(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++) + ">(" + resolved_accessor + ")");
-            b->appendBlock(b2);
+            block_if_data->appendBlock(b2);
         }
-        b->addLine("w.writeEndList();");
-        return b;
+        block_if_data->addLine("w.writeEndList();");
+
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr TupleSerializer::getReadBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        if (typenavigator->isOptional())
-        {
-            b->addLine(accessor + ".emplace();");
-        }
-        else
-        {
-            b->addLine(accessor + " = {};");
-        }
-
         b->addLine("r.readStartList();");
 
-        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator);
+        std::string resolved_accessor = ResolveOptionalAccessor(accessor, typenavigator);
 
         unsigned int i = 0;
         for (const auto& type : typenavigator->getAcceptedTypes())
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 f0c1a3ff0..899f4fe1f 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
@@ -32,7 +32,7 @@ namespace armarx::aron::cppcodegenerator::serializer
                    simox::meta::get_type_name(typeid(data::AronNDArray)),
                    simox::meta::get_type_name(typeid(type::AronIntEnum)),
                    (e->isOptional() ? SerializerAccessType::eOPTIONAL : SerializerAccessType::eDIRECT)),
-        navigator(e)
+        typenavigator(e)
     {
     }
 
@@ -56,21 +56,28 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr IntEnumSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + nextEl() + "reset();");
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            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, " + std::string(navigator->isOptional() ? "true" : "false") + ");");
+        b->addLine(accessor + "::writeInitialType(w, " + std::string(typenavigator->isOptional() ? "true" : "false") + ");");
         return b;
     }
 
     CppBlockPtr IntEnumSerializer::getWriteCurrentTypeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + nextEl() + "writeCurrentType(w, " + std::string(navigator->isOptional() ? "true" : "false") + ");");
+        b->addLine(accessor + nextEl() + "writeCurrentType(w, " + std::string(typenavigator->isOptional() ? "true" : "false") + ");");
         return b;
     }
 
@@ -83,9 +90,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr IntEnumSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + nextEl() + "write(w);");
-        return b;
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->addLine(accessor + nextEl() + "write(w);");
+
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr IntEnumSerializer::getReadBlock(const std::string& accessor) const
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.h
index abb82b441..ba53bb47e 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.h
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.h
@@ -65,6 +65,6 @@ namespace armarx::aron::cppcodegenerator::serializer
         // Members
         static const std::map<std::string, std::pair<std::string, int>> ACCEPTED_TYPES;
 
-        typenavigator::IntEnumNavigatorPtr navigator;
+        typenavigator::IntEnumNavigatorPtr typenavigator;
     };
 }
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 9c5dafcaf..b2bd6844f 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
@@ -68,7 +68,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr EigenMatrixSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
@@ -95,10 +95,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr EigenMatrixSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->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()));");
 
-        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;
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr EigenMatrixSerializer::getReadBlock(const std::string& accessor) const
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 2a899daa0..b9e1d3ced 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
@@ -63,7 +63,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr EigenQuaternionSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
@@ -90,12 +90,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr EigenQuaternionSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->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 + nextEl() + "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;
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr EigenQuaternionSerializer::getReadBlock(const std::string& accessor) const
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 478f1a789..5a57d9373 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
@@ -92,10 +92,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr IVTCByteImageSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->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));");
 
-        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;
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr IVTCByteImageSerializer::getReadBlock(const std::string& accessor) const
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
index 50609e51f..c5a586b86 100644
--- 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
@@ -55,14 +55,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr NDArraySerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
     CppBlockPtr NDArraySerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
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 f926b370c..b782c80d2 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
@@ -90,7 +90,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr OpenCVMatSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "(std::vector<int>({" + simox::alg::to_string<int>(typenavigator->getDimensions(), ", ") + "}), " + ACCEPTED_TYPES.at(typenavigator->getTypename()).first + ");");
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            b->addLine(accessor + " = " + getFullCppTypename() + "(std::vector<int>({" + simox::alg::to_string<int>(typenavigator->getDimensions(), ", ") + "}), " + ACCEPTED_TYPES.at(typenavigator->getTypename()).first + ");");
+        }
         return b;
     }
 
@@ -120,20 +127,21 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr OpenCVMatSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         std::string accessor_dimensions = escaped_accessor + DIMENSION_ACCESSOR;
         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 + nextEl() + "dims; ++" + accessor_iterator + ")");
+        block_if_data->addLine("std::vector<int> " + accessor_dimensions + ";");
+        block_if_data->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 + nextEl() + "size[" + accessor_iterator + "]);");
-        b->appendBlock(b2);
-        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;
+        block_if_data->appendBlock(b2);
+        block_if_data->addLine(accessor_dimensions + ".push_back(" + accessor + nextEl() + "elemSize());");
+        block_if_data->addLine("w.writeNDArray(" + accessor_dimensions + ", std::to_string(" + accessor + nextEl() + "type()), reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "data));");
+
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr OpenCVMatSerializer::getReadBlock(const std::string& accessor) const
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 ba47bde1d..9aaddd388 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
@@ -56,7 +56,7 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr OrientationSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
@@ -83,10 +83,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr OrientationSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "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;
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr OrientationSerializer::getReadBlock(const std::string& accessor) const
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 4fe173666..314779853 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
@@ -69,7 +69,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PCLPointCloudSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "(" + accessor + nextEl() + "width, " + accessor + nextEl() + "height);");
+        if (typenavigator->isOptional())
+        {
+            b->addLine(accessor + " = {};");
+        }
+        else
+        {
+            b->addLine(accessor + " = " + getFullCppTypename() + "(" + accessor + nextEl() + "width, " + accessor + nextEl() + "height);");
+        }
         return b;
     }
 
@@ -96,10 +103,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr PCLPointCloudSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->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()));");
 
-        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;
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr PCLPointCloudSerializer::getReadBlock(const std::string& accessor) const
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 9ee7758b1..135379e92 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
@@ -56,14 +56,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PoseSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
     CppBlockPtr PoseSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
@@ -83,12 +83,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr PoseSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "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;
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr PoseSerializer::getReadBlock(const std::string& accessor) const
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 672d01502..c87defd2c 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
@@ -56,14 +56,14 @@ namespace armarx::aron::cppcodegenerator::serializer
     CppBlockPtr PositionSerializer::getResetBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
     CppBlockPtr PositionSerializer::getInitializeBlock(const std::string& accessor) const
     {
         CppBlockPtr b = CppBlockPtr(new CppBlock());
-        b->addLine(accessor + " = " + getFullCppTypename() + "();");
+        b->addLine(accessor + " = {};");
         return b;
     }
 
@@ -83,12 +83,10 @@ namespace armarx::aron::cppcodegenerator::serializer
 
     CppBlockPtr PositionSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        block_if_data->addLine("w.writeNDArray({" + simox::alg::to_string(typenavigator->getDimensions(), ", ") + "}, \"" + typenavigator->getTypename() + "\", reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "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;
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator);
     }
 
     CppBlockPtr PositionSerializer::getReadBlock(const std::string& accessor) const
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 fd1abae70..323414fbb 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
@@ -103,18 +103,17 @@ namespace armarx::aron::cppcodegenerator::serializer
     \
     CppBlockPtr upperType##Serializer::getWriteBlock(const std::string& accessor) const \
     { \
-        CppBlockPtr b = CppBlockPtr(new CppBlock()); \
+        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); \
+        block_if_data->addLine("w.writePrimitive(" + accessor + ");"); \
         \
-        std::string resolved_accessor = ResolveAccessor(accessor, typenavigator); \
-        b->addLine("w.writePrimitive(" + resolved_accessor + ");"); \
-        return b; \
+        return ResolveOptionalBlock(accessor, block_if_data, typenavigator); \
     } \
     \
     CppBlockPtr upperType##Serializer::getReadBlock(const std::string& accessor) const \
     { \
         CppBlockPtr b = CppBlockPtr(new CppBlock()); \
         \
-        b->addLine("r.readPrimitive("+accessor+");"); \
+        b->addLine("r.readPrimitive(" + accessor + ");"); \
         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 370c58e31..75f466fbe 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
@@ -152,21 +152,11 @@ namespace armarx::aron::cppcodegenerator::serializer
         for (const auto& [key, child] : navigator->getMemberTypes())
         {
             const auto child_s = FromAronTypeNaviagtorPtr(child);
-            CppBlockPtr q = CppBlockPtr(new CppBlock());
-
-            q->addLine("w.writeKey(\"" + key + "\");");
-            CppBlockPtr child_b = child_s->getWriteBlock(key);
-            q->appendBlock(child_b);
+            CppBlockPtr child_b = CppBlockPtr(new CppBlock());
 
-            if (child->isOptional())
-            {
-                b->addLine("if (" + key + ".has_value())");
-                b->addBlock(q);
-            }
-            else
-            {
-                b->appendBlock(q);
-            }
+            child_b->addLine("w.writeKey(\"" + key + "\");");
+            child_b->appendBlock(child_s->getWriteBlock(key));
+            b->appendBlock(child_b);
         }
         b->addLine("w.writeEndDict();");
         return b;
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.cpp
index 6ebf4a1ff..2d6a9ff04 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.cpp
@@ -22,46 +22,6 @@
 
 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 6c7019ae5..affc2342e 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h
@@ -53,13 +53,6 @@ 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()
         {
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.cpp
index e78a27bd5..2a5ff9301 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.cpp
@@ -19,3 +19,9 @@
 */
 
 #include "Writer.h"
+
+
+namespace armarx::aron::dataIO
+{
+
+}
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.h b/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.h
index 89aca6407..0cd1caec4 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/Writer.h
@@ -27,8 +27,7 @@
 // ArmarX
 #include <RobotAPI/interface/aron.h>
 #include <RobotAPI/libraries/aron/core/Config.h>
-
-
+#include <RobotAPI/libraries/aron/core/Descriptor.h>
 
 namespace armarx::aron::dataIO
 {
@@ -52,6 +51,8 @@ namespace armarx::aron::dataIO
         virtual void writePrimitive(const std::string&) = 0;
         virtual void writePrimitive(bool) = 0;
 
+        virtual void writeNull() = 0;
+
         virtual void writeKey(const std::string&) = 0;
     };
 }
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 2b9379be1..5fff9e81c 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h
@@ -47,6 +47,7 @@ namespace armarx::aron::dataIO
         // Interface
         virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const = 0;
         virtual ElementTypename getNextElement() const = 0;
+        virtual bool hasNextElement() const = 0;
 
         // General implementation
         ElementTypename getElement() const
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 d3cefab09..22eabe145 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
@@ -188,8 +188,11 @@ namespace armarx::aron::dataIO::reader
         auto token = stack.top();
         if (token->hasKey(k))
         {
-            token->setCurrentKey(k);
-            return true;
+            if (token->hasNextElement())
+            {
+                token->setCurrentKey(k);
+                return true;
+            }
         }
         return false;
     }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReaderToken.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReaderToken.h
index 4b85fe772..7f4bf59d7 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReaderToken.h
@@ -96,6 +96,27 @@ namespace armarx::aron::dataIO::reader
             }
         }
 
+        virtual bool hasNextElement() const override
+        {
+            switch (descriptor)
+            {
+                case data::Descriptor::eDict:
+                {
+                    datanavigator::DictNavigatorPtr casted = datanavigator::DictNavigator::DynamicCast(element);
+                    datanavigator::NavigatorPtr ret = casted->getElement(getCurrentKey());
+                    return (bool) ret;
+                }
+                case data::Descriptor::eList:
+                {
+                    datanavigator::ListNavigatorPtr casted = datanavigator::ListNavigator::DynamicCast(element);
+                    datanavigator::NavigatorPtr ret = casted->getElement(currentIndex);
+                    return (bool) ret;
+                }
+                default:
+                    throw error::DescriptorNotValidException("NavigatorReaderToken", "hasData", "Could not resove a type of a navigator. Allowed are only container types due to performance", descriptor);
+            }
+        }
+
     private:
 
     };
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 59a2351ac..43a308298 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
@@ -180,8 +180,11 @@ namespace armarx::aron::dataIO::reader
         auto token = stack.top();
         if (token->hasKey(k))
         {
-            token->setCurrentKey(k);
-            return true;
+            if (token->hasNextElement())
+            {
+                token->setCurrentKey(k);
+                return true;
+            }
         }
         return false;
     }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
index 04acd920b..29dccb820 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
@@ -133,7 +133,26 @@ namespace armarx::aron::dataIO::reader
                     return ret;
                 }
                 default:
-                    throw error::DescriptorNotValidException("NlohmannJSONReaderToken", "getNextElement", "Could not resove a type of a navigator. Allowed are only container types due to performance", descriptor);
+                    throw error::DescriptorNotValidException("NlohmannJSONReaderToken", "getNextElement", "Could not resove a type of a json. Allowed are only container types due to performance", descriptor);
+            }
+        }
+
+        virtual bool hasNextElement() const override
+        {
+            switch (descriptor)
+            {
+                case data::Descriptor::eDict:
+                {
+                    nlohmann::json ret = element[getCurrentKey()];
+                    return !ret.is_null();
+                }
+                case data::Descriptor::eList:
+                {
+                    nlohmann::json ret = element[currentIndex];
+                    return !ret.is_null();
+                }
+                default:
+                    throw error::DescriptorNotValidException("NlohmannJSONReaderToken", "hasData", "Could not resove a type of a json. Allowed are only container types due to performance", descriptor);
             }
         }
 
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.cpp
index 15f57ecf5..633d62ea3 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.cpp
@@ -29,7 +29,6 @@
 #include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h>
 
 
-
 namespace armarx::aron::dataIO::writer
 {
 
@@ -157,6 +156,13 @@ namespace armarx::aron::dataIO::writer
         token->addElement(aron);
     }
 
+    void NavigatorWriter::writeNull()
+    {
+        Path path = generatePath();
+        NavigatorWriterTokenPtr token = stack.top();
+        token->addElement(nullptr);
+    }
+
     void NavigatorWriter::writeKey(const std::string& k)
     {
         auto token = stack.top();
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.h b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.h
index 3467d630a..483883b85 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.h
@@ -30,6 +30,7 @@
 // ArmarX
 #include <RobotAPI/libraries/aron/core/Concepts.h>
 #include <RobotAPI/libraries/aron/core/navigator/data/Navigator.h>
+#include <RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.h>
 #include <RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriterToken.h>
 
 namespace armarx::aron::dataIO::writer
@@ -57,6 +58,8 @@ namespace armarx::aron::dataIO::writer
         virtual void writePrimitive(const std::string&) override;
         virtual void writePrimitive(const bool) override;
 
+        virtual void writeNull() override;
+
         virtual void writeKey(const std::string&) override;
 
         datanavigator::NavigatorPtr getResult() const
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriterToken.h b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriterToken.h
index 8f10dd89e..7e8a53a77 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriterToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriterToken.h
@@ -47,6 +47,8 @@ namespace armarx::aron::dataIO::writer
         NavigatorWriterToken() = delete;
         NavigatorWriterToken(const data::Descriptor desc, const datanavigator::NavigatorPtr& d)
         {
+            ARMARX_CHECK_NOT_NULL(d);
+
             descriptor = desc;
             element = d;
         }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
index b768c5da0..9e5517b65 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
@@ -124,6 +124,12 @@ namespace armarx::aron::dataIO::writer
         token->addElement(j);
     }
 
+    void NlohmannJSONWriter::writeNull()
+    {
+        auto token = stack.top();
+        token->addElement(nullptr);
+    }
+
     void NlohmannJSONWriter::writeKey(const std::string& k)
     {
         auto token = stack.top();
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.h b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.h
index f36fa55d5..44bf3c002 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.h
@@ -57,6 +57,8 @@ namespace armarx::aron::dataIO::writer
         virtual void writePrimitive(const std::string&) override;
         virtual void writePrimitive(const bool) override;
 
+        virtual void writeNull() override;
+
         virtual void writeKey(const std::string&) override;
 
         nlohmann::json getResult() const
diff --git a/source/RobotAPI/libraries/aron/core/navigator/NavigatorFactory.h b/source/RobotAPI/libraries/aron/core/navigator/NavigatorFactory.h
index c8d8ea651..4463de455 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/NavigatorFactory.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/NavigatorFactory.h
@@ -38,7 +38,7 @@
 
 namespace armarx::aron
 {
-    template <typename Input, typename Output> // requires ...
+    template <typename Input, typename Output, typename EnumT> // requires ...
     class NavigatorFactory :
         virtual public Factory<Input, Output>
     {
@@ -47,5 +47,6 @@ namespace armarx::aron
 
         virtual Output create(const Input&, const Path&) const = 0;
         virtual Output createSpecific(const Input&, const Path&) const = 0;
+        virtual Output createNull(const EnumT) const = 0;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.cpp
index 1adcdfff3..9215638ff 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.cpp
@@ -52,6 +52,60 @@ namespace armarx::aron::datanavigator
         return factory_iterator->second->createSpecific(aron, path);
     }
 
+    NavigatorPtr NavigatorFactory::createNull(const data::Descriptor desc) const
+    {
+        switch (desc)
+        {
+            case data::Descriptor::eDict:
+            {
+                datanavigator::DictNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            case data::Descriptor::eList:
+            {
+                datanavigator::ListNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            case data::Descriptor::eNDArray:
+            {
+                datanavigator::NDArrayNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            case data::Descriptor::eInt:
+            {
+                datanavigator::IntNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            case data::Descriptor::eLong:
+            {
+                datanavigator::LongNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            case data::Descriptor::eFloat:
+            {
+                datanavigator::FloatNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            case data::Descriptor::eDouble:
+            {
+                datanavigator::DoubleNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            case data::Descriptor::eString:
+            {
+                datanavigator::StringNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            case data::Descriptor::eBool:
+            {
+                datanavigator::BoolNavigatorPtr aron = nullptr;
+                return aron;
+            }
+            default:
+                throw error::DescriptorNotValidException("NavigatorFactory", "createNull", "Received invalid descriptor to create NULL.", desc);
+        }
+    }
+
     NavigatorPtr NavigatorFactory::createSpecific(const data::AronDataPtr&, const Path& p) const
     {
         throw error::AronException("NavigatorFactory", "createSpecific", "Called disallowed method of an NavigatorFactory. Use child class instead!", p);
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.h b/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.h
index 63d08c145..924db3652 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.h
@@ -40,12 +40,13 @@ namespace armarx::aron::datanavigator
     typedef std::shared_ptr<NavigatorFactory> NavigatorFactoryPtr;
 
     class NavigatorFactory :
-        virtual public Factory<data::AronDataPtr, datanavigator::NavigatorPtr>
+        virtual public armarx::aron::NavigatorFactory<data::AronDataPtr, datanavigator::NavigatorPtr, data::Descriptor>
     {
     public:
         NavigatorFactory() = default;
         virtual NavigatorPtr create(const data::AronDataPtr&, const Path&) const override;
         virtual NavigatorPtr createSpecific(const data::AronDataPtr&, const Path&) const override;
+        virtual NavigatorPtr createNull(const data::Descriptor) const override;
     };
 
     // Factories
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/container/Dict.cpp
index 67a2a6d81..e6bbba883 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/container/Dict.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/container/Dict.cpp
@@ -72,6 +72,10 @@ namespace armarx::aron::datanavigator
     {
         for (const auto& [key, nav] : childrenNavigators)
         {
+            if (!nav)
+            {
+                return (bool) other.getElement(key);
+            }
             if (not(other.hasElement(key)))
             {
                 return false;
@@ -150,8 +154,16 @@ namespace armarx::aron::datanavigator
 
     void DictNavigator::addElement(const std::string& key, const NavigatorPtr& data)
     {
-        this->childrenNavigators[key] = data;
-        this->aron->elements[key] = data->getResult();
+        if (data)
+        {
+            this->childrenNavigators[key] = data;
+            this->aron->elements[key] = data->getResult();
+        }
+        else
+        {
+            this->childrenNavigators[key] = nullptr;
+            this->aron->elements[key] = nullptr;
+        }
     }
 
     bool DictNavigator::hasElement(const std::string& key) const
@@ -196,11 +208,17 @@ namespace armarx::aron::datanavigator
         return "AronDict";
     }
 
+    // TODO
     typenavigator::NavigatorPtr DictNavigator::recalculateType() const
     {
         typenavigator::DictNavigatorPtr typenav = typenavigator::DictNavigatorPtr(new typenavigator::DictNavigator(getPath()));
         for (const auto& [key, nav] : childrenNavigators)
         {
+            if (!nav)
+            {
+                continue;
+            }
+
             if (typenav->getAcceptedType() == nullptr)
             {
                 typenav->setAcceptedType(nav->recalculateType());
@@ -230,6 +248,10 @@ namespace armarx::aron::datanavigator
                 typenavigator::ObjectNavigatorPtr objectTypeNav = typenavigator::ObjectNavigator::DynamicCast(type);
                 for (const auto& [key, nav] : childrenNavigators)
                 {
+                    if (!nav && !objectTypeNav->getMemberType(key)->isOptional())
+                    {
+                        return false;
+                    }
                     if (!nav->fullfillsType(objectTypeNav->getMemberType(key)))
                     {
                         return false;
@@ -242,6 +264,10 @@ namespace armarx::aron::datanavigator
                 typenavigator::DictNavigatorPtr dictTypeNav = typenavigator::DictNavigator::DynamicCast(type);
                 for (const auto& [_, nav] : childrenNavigators)
                 {
+                    if (!nav && !dictTypeNav->getAcceptedType()->isOptional())
+                    {
+                        return false;
+                    }
                     if (!nav->fullfillsType(dictTypeNav->getAcceptedType()))
                     {
                         return false;
@@ -288,6 +314,10 @@ namespace armarx::aron::datanavigator
         else
         {
             Path next = path.withDetachedFirstElement();
+            if (!childrenNavigators.at(el))
+            {
+                throw error::AronException("DictNavigator", "navigateAbsolute", "Could not navigate into a NULL member. Seems like the member is optional and not set.", next);
+            }
             return childrenNavigators.at(el)->navigateAbsolute(next);
         }
     }
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/container/List.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/container/List.cpp
index d2d5bee4a..c48e75a43 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/container/List.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/container/List.cpp
@@ -75,6 +75,10 @@ namespace armarx::aron::datanavigator
         unsigned int i = 0;
         for (const auto& nav : childrenNavigators)
         {
+            if (!nav)
+            {
+                return (bool) other.getElement(i);
+            }
             if (not(other.hasElement(i)))
             {
                 return false;
@@ -140,8 +144,16 @@ namespace armarx::aron::datanavigator
     // public member functions
     void ListNavigator::addElement(const NavigatorPtr& n)
     {
-        childrenNavigators.push_back(n);
-        aron->elements.push_back(n->getResult());
+        if (n)
+        {
+            childrenNavigators.push_back(n);
+            aron->elements.push_back(n->getResult());
+        }
+        else
+        {
+            childrenNavigators.push_back(nullptr);
+            aron->elements.push_back(nullptr);
+        }
     }
 
     bool ListNavigator::hasElement(unsigned int i) const
@@ -185,6 +197,7 @@ namespace armarx::aron::datanavigator
         return "AronList";
     }
 
+    // TODO
     typenavigator::NavigatorPtr ListNavigator::recalculateType() const
     {
         typenavigator::ListNavigatorPtr typenav = typenavigator::ListNavigatorPtr(new typenavigator::ListNavigator(getPath()));
@@ -221,6 +234,10 @@ namespace armarx::aron::datanavigator
                 typenavigator::ListNavigatorPtr listTypeNav = typenavigator::ListNavigator::DynamicCast(type);
                 for (const auto& nav : childrenNavigators)
                 {
+                    if (!nav && !listTypeNav->getAcceptedType()->isOptional())
+                    {
+                        return false;
+                    }
                     if (!nav->fullfillsType(listTypeNav->getAcceptedType()))
                     {
                         return false;
@@ -234,6 +251,10 @@ namespace armarx::aron::datanavigator
                 unsigned int i = 0;
                 for (const auto& nav : childrenNavigators)
                 {
+                    if (!nav && !tupleTypeNav->getAcceptedType(i)->isOptional())
+                    {
+                        return false;
+                    }
                     if (!nav->fullfillsType(tupleTypeNav->getAcceptedType(i)))
                     {
                         return false;
@@ -248,6 +269,14 @@ namespace armarx::aron::datanavigator
                 {
                     return false;
                 }
+                if (!childrenNavigators[0] && !pairTypeNav->getFirstAcceptedType()->isOptional())
+                {
+                    return false;
+                }
+                if (!childrenNavigators[1] && !pairTypeNav->getSecondAcceptedType()->isOptional())
+                {
+                    return false;
+                }
                 return childrenNavigators[0]->fullfillsType(pairTypeNav->getFirstAcceptedType()) && childrenNavigators[1]->fullfillsType(pairTypeNav->getSecondAcceptedType());
             }
             default:
@@ -284,6 +313,10 @@ namespace armarx::aron::datanavigator
         else
         {
             Path next = path.withDetachedFirstElement();
+            if (!childrenNavigators.at(i))
+            {
+                throw error::AronException("ListNavigator", "navigateAbsolute", "Could not navigate into a NULL member. Seems like the member is optional and not set.", next);
+            }
             return childrenNavigators.at(i)->navigateAbsolute(next);
         }
     }
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.cpp
index f0375363b..b1dd72b21 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.cpp
@@ -51,6 +51,11 @@ namespace armarx::aron::typenavigator
         return factory_iterator->second->createSpecific(aron, path);
     }
 
+    typenavigator::NavigatorPtr NavigatorFactory::createNull(const type::Descriptor) const
+    {
+        return nullptr;
+    }
+
     NavigatorPtr NavigatorFactory::createSpecific(const type::AronTypePtr&, const Path& p) const
     {
         throw error::AronException("NavigatorFactory", "createSpecific", "Called disallowed method of an NavigatorFactory. Use child class instead!", p);
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.h b/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.h
index 7e443cc3c..88783e884 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.h
@@ -40,12 +40,13 @@ namespace armarx::aron::typenavigator
     typedef std::shared_ptr<NavigatorFactory> NavigatorFactoryPtr;
 
     class NavigatorFactory :
-        virtual public armarx::aron::NavigatorFactory<type::AronTypePtr, typenavigator::NavigatorPtr>
+        virtual public armarx::aron::NavigatorFactory<type::AronTypePtr, typenavigator::NavigatorPtr, type::Descriptor>
     {
     public:
         NavigatorFactory() = default;
         virtual typenavigator::NavigatorPtr create(const type::AronTypePtr&, const Path&) const override;
         virtual typenavigator::NavigatorPtr createSpecific(const type::AronTypePtr&, const Path&) const override;
+        virtual typenavigator::NavigatorPtr createNull(const type::Descriptor) const override;
     };
 
     // Factories
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.cpp
index e2b8c7158..f4c471c4c 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/ndarray/NDArray.cpp
@@ -30,7 +30,7 @@ namespace armarx::aron::typenavigator
     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, ""))
+        type(new type::AronNDArray(false, {}, ""))
     {
     }
 
@@ -58,7 +58,7 @@ namespace armarx::aron::typenavigator
 
     unsigned int NDArrayNavigator::getElementSize() const
     {
-        return type->elementSize;
+        return 0; //type->elementSize;
     }
 
     void NDArrayNavigator::setTypename(const std::string& s)
@@ -78,7 +78,7 @@ namespace armarx::aron::typenavigator
 
     void NDArrayNavigator::setElementSize(unsigned int i)
     {
-        type->elementSize = i;
+        //type->elementSize = i;
     }
 
     // static methods
@@ -113,7 +113,7 @@ namespace armarx::aron::typenavigator
 
     std::string NDArrayNavigator::getName() const
     {
-        return "AronPoseType";
+        return "AronNDArrayType";
     }
 
     void NDArrayNavigator::setOptional(bool v)
-- 
GitLab