From 18cb67f1065f0cf658d214a59ffb3703a0e71d55 Mon Sep 17 00:00:00 2001
From: Fabian Peller-Konrad <fabian.peller-konrad@kit.edu>
Date: Tue, 7 Dec 2021 10:28:41 +0100
Subject: [PATCH] aron type visitor and converter updates

---
 .../converter/json/NLohmannJSONConverter.cpp  |  15 +-
 .../converter/json/NLohmannJSONConverter.h    |  28 +-
 .../libraries/aron/core/CMakeLists.txt        |   8 +
 .../RobotAPI/libraries/aron/core/Descriptor.h |  41 +++
 .../aron/core/data/converter/Converter.h      |  15 +-
 .../libraries/aron/core/data/rw/Reader.h      |   3 +
 .../libraries/aron/core/data/rw/Writer.h      |   3 +
 .../aron/core/data/variant/Variant.h          |   3 +
 .../aron/core/data/visitor/RecursiveVisitor.h | 184 ++++++------
 .../aron/core/data/visitor/Visitor.h          | 171 +++++------
 .../data/visitor/variant/VariantVisitor.cpp   | 272 ++++++++++--------
 .../data/visitor/variant/VariantVisitor.h     |  99 +++----
 .../aron/core/type/converter/Converter.cpp    |  30 ++
 .../aron/core/type/converter/Converter.h      | 263 +++++++++++++++++
 .../nlohmannJSON/NlohmannJSONConverter.cpp    |  30 ++
 .../nlohmannJSON/NlohmannJSONConverter.h      |  56 ++++
 .../converter/variant/VariantConverter.cpp    |  30 ++
 .../type/converter/variant/VariantConverter.h |  57 ++++
 .../libraries/aron/core/type/rw/Reader.h      |  24 +-
 .../libraries/aron/core/type/rw/Writer.h      |  12 +-
 .../nlohmannJSON/NlohmannJSONReader.cpp       |   6 +-
 .../reader/nlohmannJSON/NlohmannJSONReader.h  |  44 +--
 .../type/rw/reader/variant/VariantReader.cpp  |  45 +--
 .../type/rw/reader/variant/VariantReader.h    |  48 ++--
 .../writer/nlohmannJSON/NlohmannJSONWriter.h  |  42 +--
 .../type/rw/writer/variant/VariantWriter.h    |  48 ++--
 .../aron/core/type/variant/Variant.h          |   3 +
 .../nlohmannJSON/NlohmannJSONVisitor.cpp      |   4 +-
 .../nlohmannJSON/NlohmannJSONVisitor.h        |   4 +-
 .../type/visitor/variant/VariantVisitor.cpp   |   5 +-
 30 files changed, 1122 insertions(+), 471 deletions(-)
 create mode 100644 source/RobotAPI/libraries/aron/core/type/converter/Converter.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/type/converter/Converter.h
 create mode 100644 source/RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.h
 create mode 100644 source/RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.cpp
 create mode 100644 source/RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.h

diff --git a/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.cpp b/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.cpp
index e984e760b..8eb3599fa 100644
--- a/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.cpp
+++ b/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.cpp
@@ -12,10 +12,21 @@ namespace armarx::aron::converter
     void AronNlohmannJSONConverter::ConvertToNlohmannJSON(const aron::data::VariantPtr& aron, nlohmann::json& j)
     {
         aron::data::writer::NlohmannJSONWriter dataWriter;
-        j = aron::data::readAndWrite<Variant2NlohmannJSONConverterHelper>(aron);
+        j = aron::data::readAndWrite<DataVariant2NlohmannJSONConverterHelper>(aron);
     }
 
+    nlohmann::json AronNlohmannJSONConverter::ConvertToNlohmannJSON(const type::VariantPtr& aron)
+    {
+        nlohmann::json j;
+        ConvertToNlohmannJSON(aron, j);
+        return j;
+    }
 
+    void AronNlohmannJSONConverter::ConvertToNlohmannJSON(const aron::type::VariantPtr& aron, nlohmann::json& j)
+    {
+        aron::type::writer::NlohmannJSONWriter typeWriter;
+        j = aron::type::readAndWrite<TypeVariant2NlohmannJSONConverterHelper>(aron);
+    }
 
     data::DictPtr AronNlohmannJSONConverter::ConvertFromNlohmannJSONObject(const nlohmann::json& j)
     {
@@ -29,6 +40,6 @@ namespace armarx::aron::converter
     void AronNlohmannJSONConverter::ConvertFromNlohmannJSON(aron::data::VariantPtr& a, const nlohmann::json& e, const aron::type::VariantPtr& expectedStructure)
     {
         aron::data::writer::NlohmannJSONWriter dataWriter;
-        a = aron::data::readAndWrite<NlohmannJSON2VariantConverterHelper>(e);
+        a = aron::data::readAndWrite<NlohmannJSON2DataVariantConverterHelper>(e);
     }
 }
diff --git a/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h b/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h
index da90be690..1dc529348 100644
--- a/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h
+++ b/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h
@@ -15,6 +15,13 @@
 #include <RobotAPI/libraries/aron/core/data/rw/reader/nlohmannJSON/NlohmannJSONReader.h>
 #include <RobotAPI/libraries/aron/core/data/rw/writer/nlohmannJSON/NlohmannJSONWriter.h>
 
+#include <RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.h>
+#include <RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.h>
+#include <RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.h>
+#include <RobotAPI/libraries/aron/core/type/rw/writer/variant/VariantWriter.h>
+#include <RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.h>
+#include <RobotAPI/libraries/aron/core/type/rw/writer/nlohmannJSON/NlohmannJSONWriter.h>
+
 // JSON
 #include <SimoxUtility/json/json.hpp>
 
@@ -23,13 +30,23 @@ namespace armarx::aron::converter
     class AronNlohmannJSONConverter
     {
     private:
-        struct Variant2NlohmannJSONConverterHelper :
-                public data::VariantConverter<data::writer::NlohmannJSONWriter, Variant2NlohmannJSONConverterHelper>
+        struct DataVariant2NlohmannJSONConverterHelper :
+                public data::VariantConverter<data::writer::NlohmannJSONWriter, DataVariant2NlohmannJSONConverterHelper>
+        {
+        };
+
+        struct NlohmannJSON2DataVariantConverterHelper :
+                public data::NlohmannJSONConverter<data::writer::VariantWriter, NlohmannJSON2DataVariantConverterHelper>
         {
         };
 
-        struct NlohmannJSON2VariantConverterHelper :
-                public data::NlohmannJSONConverter<data::writer::VariantWriter, NlohmannJSON2VariantConverterHelper>
+        struct TypeVariant2NlohmannJSONConverterHelper :
+                public type::VariantConverter<type::writer::NlohmannJSONWriter, TypeVariant2NlohmannJSONConverterHelper>
+        {
+        };
+
+        struct NlohmannJSON2TypeVariantConverterHelper :
+                public type::NlohmannJSONConverter<type::writer::VariantWriter, NlohmannJSON2TypeVariantConverterHelper>
         {
         };
 
@@ -39,6 +56,9 @@ namespace armarx::aron::converter
         static nlohmann::json ConvertToNlohmannJSON(const data::VariantPtr&);
         static void ConvertToNlohmannJSON(const data::VariantPtr&, nlohmann::json&);
 
+        static nlohmann::json ConvertToNlohmannJSON(const type::VariantPtr&);
+        static void ConvertToNlohmannJSON(const type::VariantPtr&, nlohmann::json&);
+
         static data::DictPtr ConvertFromNlohmannJSONObject(const nlohmann::json&);
         static void ConvertFromNlohmannJSON(data::VariantPtr&, const nlohmann::json&, const aron::type::VariantPtr& = nullptr);
     };
diff --git a/source/RobotAPI/libraries/aron/core/CMakeLists.txt b/source/RobotAPI/libraries/aron/core/CMakeLists.txt
index 2bd9f9c91..3e173f52e 100644
--- a/source/RobotAPI/libraries/aron/core/CMakeLists.txt
+++ b/source/RobotAPI/libraries/aron/core/CMakeLists.txt
@@ -93,6 +93,10 @@ set(LIB_FILES
     data/converter/variant/VariantConverter.cpp
     data/converter/nlohmannJSON/NlohmannJSONConverter.cpp
 
+    type/converter/Converter.cpp
+    type/converter/variant/VariantConverter.cpp
+    type/converter/nlohmannJSON/NlohmannJSONConverter.cpp
+
     typereader/xml/Data.cpp
     typereader/xml/Factory.cpp
     typereader/xml/Reader.cpp
@@ -224,6 +228,10 @@ set(LIB_HEADERS
     data/converter/variant/VariantConverter.h
     data/converter/nlohmannJSON/NlohmannJSONConverter.h
 
+    type/converter/Converter.h
+    type/converter/variant/VariantConverter.h
+    type/converter/nlohmannJSON/NlohmannJSONConverter.h
+
     typereader/helper/GenerateInfo.h
     typereader/helper/GenerateTypeInfo.h
     typereader/helper/GenerateIntEnumInfo.h
diff --git a/source/RobotAPI/libraries/aron/core/Descriptor.h b/source/RobotAPI/libraries/aron/core/Descriptor.h
index f6a8dfdfc..ba1b70b4d 100644
--- a/source/RobotAPI/libraries/aron/core/Descriptor.h
+++ b/source/RobotAPI/libraries/aron/core/Descriptor.h
@@ -311,4 +311,45 @@ namespace armarx::aron::data
     {
         return defaultconversion::typeinfo::TypeId2Descriptor.at(typeid(t).hash_code());
     }
+
+    namespace defaultconversion
+    {
+        const std::map<Descriptor, aron::type::Descriptor> Data2TypeDescriptor = {
+            {Descriptor::eList, aron::type::Descriptor::eList},
+            {Descriptor::eDict, aron::type::Descriptor::eDict},
+            {Descriptor::eNDArray, aron::type::Descriptor::eNDArray},
+            {Descriptor::eInt, aron::type::Descriptor::eInt},
+            {Descriptor::eFloat, aron::type::Descriptor::eFloat},
+            {Descriptor::eLong, aron::type::Descriptor::eLong},
+            {Descriptor::eDouble, aron::type::Descriptor::eDouble},
+            {Descriptor::eString, aron::type::Descriptor::eString},
+            {Descriptor::eBool, aron::type::Descriptor::eBool},
+            {Descriptor::eUnknown, aron::type::Descriptor::eUnknown}
+        };
+
+        const std::map<aron::type::Descriptor, Descriptor> Type2DataDescriptor = {
+            {aron::type::Descriptor::eList, Descriptor::eList},
+            {aron::type::Descriptor::eObject, Descriptor::eDict},
+            {aron::type::Descriptor::eTuple, Descriptor::eList},
+            {aron::type::Descriptor::ePair, Descriptor::eList},
+            {aron::type::Descriptor::eDict, Descriptor::eDict},
+            {aron::type::Descriptor::eNDArray, Descriptor::eNDArray},
+            {aron::type::Descriptor::eMatrix, Descriptor::eNDArray},
+            {aron::type::Descriptor::eQuaternion, Descriptor::eNDArray},
+            {aron::type::Descriptor::ePointCloud, Descriptor::eNDArray},
+            {aron::type::Descriptor::ePosition, Descriptor::eNDArray},
+            {aron::type::Descriptor::eOrientation, Descriptor::eNDArray},
+            {aron::type::Descriptor::ePose, Descriptor::eNDArray},
+            {aron::type::Descriptor::eImage, Descriptor::eNDArray},
+            {aron::type::Descriptor::eIntEnum, Descriptor::eInt},
+            {aron::type::Descriptor::eInt, Descriptor::eInt},
+            {aron::type::Descriptor::eLong, Descriptor::eLong},
+            {aron::type::Descriptor::eFloat, Descriptor::eFloat},
+            {aron::type::Descriptor::eDouble, Descriptor::eDouble},
+            {aron::type::Descriptor::eString, Descriptor::eString},
+            {aron::type::Descriptor::eBool, Descriptor::eBool},
+            {aron::type::Descriptor::eTime, Descriptor::eLong},
+            {aron::type::Descriptor::eUnknown,  Descriptor::eUnknown},
+        };
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/core/data/converter/Converter.h b/source/RobotAPI/libraries/aron/core/data/converter/Converter.h
index c538c61f3..f0573af75 100644
--- a/source/RobotAPI/libraries/aron/core/data/converter/Converter.h
+++ b/source/RobotAPI/libraries/aron/core/data/converter/Converter.h
@@ -29,15 +29,27 @@
 
 namespace armarx::aron::data
 {
-    // prototype
+    // prototypes
+    template <class ReaderImplementation, class WriterImplementation, class DerivedT>
+    requires isReader<ReaderImplementation> && isWriter<WriterImplementation>
+    struct Converter;
+
+    template <class T>
+    concept isConverter = std::is_base_of<Converter<typename T::ReaderType, typename T::WriterType, typename T::This>, T>::value;
+
     template <class ConverterImplementation>
+    requires isConverter<ConverterImplementation>
     typename ConverterImplementation::WriterReturnType readAndWrite(typename ConverterImplementation::ReaderInputType& o);
 
     /// Converter struct providing the needed methods.
     /// WriterImplementation is a writer class, TODO: add concepts
     template <class ReaderImplementation, class WriterImplementation, class DerivedT>
+    requires isReader<ReaderImplementation> && isWriter<WriterImplementation>
     struct Converter : virtual public Visitor<typename ReaderImplementation::InputType>
     {
+        using WriterType = WriterImplementation;
+        using ReaderType = ReaderImplementation;
+        using This = DerivedT;
         using WriterReturnType = typename WriterImplementation::ReturnType;
         using ReaderInputType = typename ReaderImplementation::InputType;
         using ReaderInputTypeNonConst = typename ReaderImplementation::InputTypeNonConst;
@@ -130,6 +142,7 @@ namespace armarx::aron::data
     /// the function to read from a variant and write to a writer T
     /// returns the returntype of T
     template <class ConverterImplementation>
+    requires isConverter<ConverterImplementation>
     typename ConverterImplementation::WriterReturnType readAndWrite(typename ConverterImplementation::ReaderInputType& o)
     {
         ConverterImplementation v;
diff --git a/source/RobotAPI/libraries/aron/core/data/rw/Reader.h b/source/RobotAPI/libraries/aron/core/data/rw/Reader.h
index 141cba9b8..d3642c157 100644
--- a/source/RobotAPI/libraries/aron/core/data/rw/Reader.h
+++ b/source/RobotAPI/libraries/aron/core/data/rw/Reader.h
@@ -89,4 +89,7 @@ namespace armarx::aron::data
             return readBool(input, i);
         }
     };
+
+    template <class T>
+    concept isReader = std::is_base_of<ReaderInterface<typename T::InputType>, T>::value;
 }
diff --git a/source/RobotAPI/libraries/aron/core/data/rw/Writer.h b/source/RobotAPI/libraries/aron/core/data/rw/Writer.h
index 7482b13b6..edd43903f 100644
--- a/source/RobotAPI/libraries/aron/core/data/rw/Writer.h
+++ b/source/RobotAPI/libraries/aron/core/data/rw/Writer.h
@@ -86,4 +86,7 @@ namespace armarx::aron::data
             return writeBool(i);
         }
     };
+
+    template <class T>
+    concept isWriter = std::is_base_of<WriterInterface<typename T::ReturnType>, T>::value;
 }
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/Variant.h b/source/RobotAPI/libraries/aron/core/data/variant/Variant.h
index 00f5aa6ff..aee8c55fc 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/Variant.h
+++ b/source/RobotAPI/libraries/aron/core/data/variant/Variant.h
@@ -151,4 +151,7 @@ namespace armarx::aron::data
     private:
         static const VariantFactoryPtr FACTORY;
     };
+
+    template <class T>
+    concept isVariant = std::is_base_of<Variant, T>::value;
 }
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h b/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
index 628316850..df9896b90 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
@@ -30,10 +30,104 @@
 
 namespace armarx::aron::data
 {
+    /**
+     * @see type/visitor/RecursiveVisitor.h
+     */
+    template <class T>
+    struct RecursiveVisitor : virtual public VisitorBase<T>
+    {
+        using Input = typename VisitorBase<T>::Input;
+        using InputNonConst = typename std::remove_const<Input>::type;
+
+        using MapElements = std::map<std::string, InputNonConst>;
+        using ListElements = std::vector<InputNonConst>;
+
+        virtual MapElements getDictElements(Input&) = 0;
+        virtual ListElements getListElements(Input&) = 0;
+
+        virtual void visitDictOnEnter(Input& element) {};
+        virtual void visitDictOnExit(Input& element) {};
+        virtual void visitListOnEnter(Input& element) {};
+        virtual void visitListOnExit(Input& element) {};
+
+        virtual void visitNDArray(Input& element) {};
+        virtual void visitInt(Input& element) {};
+        virtual void visitLong(Input& element) {};
+        virtual void visitFloat(Input& element) {};
+        virtual void visitDouble(Input& element) {};
+        virtual void visitBool(Input& element) {};
+        virtual void visitString(Input& element) {};
+        virtual void visitUnknown(Input& element) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
+        virtual ~RecursiveVisitor() = default;
+    };
+
+    /**
+     * @see type/visitor/RecursiveVisitor.h
+     */
+    template <class T1, class T2>
+    struct RecursiveTypedVisitor : virtual public TypedVisitorBase<T1, T2>
+    {
+        using DataInput = typename TypedVisitorBase<T1, T2>::DataInput;
+        using TypeInput = typename TypedVisitorBase<T1, T2>::TypeInput;
+
+        using TypeInputNonConst = typename std::remove_const<TypeInput>::type;
+        using DataInputNonConst = typename std::remove_const<DataInput>::type;
+
+        using MapElements = std::map<std::string, std::pair<DataInputNonConst, TypeInputNonConst>>;
+        using ListElements = std::vector<std::pair<DataInputNonConst, TypeInputNonConst>>;
+        using PairElements = std::pair<std::pair<DataInputNonConst, TypeInputNonConst>, std::pair<DataInputNonConst, TypeInputNonConst>>;
+        using TupleElements = std::vector<std::pair<DataInputNonConst, TypeInputNonConst>>;
+
+        virtual MapElements getObjectElements(DataInput&, TypeInput&) = 0;
+        virtual MapElements getDictElements(DataInput&, TypeInput&) = 0;
+        virtual ListElements getListElements(DataInput&, TypeInput&) = 0;
+        virtual PairElements getPairElements(DataInput&, TypeInput&) = 0;
+        virtual TupleElements getTupleElements(DataInput&, TypeInput&) = 0;
+
+        virtual void visitObjectOnEnter(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitObjectOnExit(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitDictOnEnter(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitDictOnExit(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPairOnEnter(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPairOnExit(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitTupleOnEnter(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitTupleOnExit(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitListOnEnter(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitListOnExit(DataInput& elementData, TypeInput& elementType) {};
+
+        virtual void visitMatrix(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitNDArray(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitQuaternion(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitOrientation(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPosition(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPose(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitImage(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPointCloud(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitIntEnum(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitInt(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitLong(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitFloat(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitDouble(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitBool(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitString(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitTime(DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitUnknown(DataInput& elementData, TypeInput& elementType) {
+            throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor.");
+        }
+        virtual ~RecursiveTypedVisitor() = default;
+    };
+
+    template <class T, class Data>
+    concept isRecursiveVisitor = std::is_base_of<RecursiveVisitor<Data>, T>::value;
+
+    template <class T, class Data, class Type>
+    concept isRecursiveTypedVisitor = std::is_base_of<RecursiveTypedVisitor<Data, Type>, T>::value;
+
     /**
      * @see type/visitor/RecursiveVisitor.h
      */
     template <class RecursiveVisitorImplementation>
+    requires isRecursiveVisitor<RecursiveVisitorImplementation, typename RecursiveVisitorImplementation::Input>
     void visitRecursive(RecursiveVisitorImplementation& v, typename RecursiveVisitorImplementation::Input& o)
     {
         data::Descriptor descriptor = v.getDescriptor(o);
@@ -85,9 +179,10 @@ namespace armarx::aron::data
      * @see data/visitor/Visitor.h
      */
     template <class RecursiveVisitorImplementation>
+    requires isRecursiveTypedVisitor<RecursiveVisitorImplementation, typename RecursiveVisitorImplementation::DataInput, typename RecursiveVisitorImplementation::TypeInput>
     void visitRecursive(RecursiveVisitorImplementation& v, typename RecursiveVisitorImplementation::DataInput& o, typename RecursiveVisitorImplementation::TypeInput& t)
     {
-        type::Descriptor descriptor = v.getDescriptor(t);
+        type::Descriptor descriptor = v.getDescriptor(o, t);
         switch (descriptor)
         {
             case type::Descriptor::eList:
@@ -181,91 +276,4 @@ namespace armarx::aron::data
                 return v.visitUnknown(o, t);
         }
     }
-
-    /**
-     * @see type/visitor/RecursiveVisitor.h
-     */
-    template <class T>
-    struct RecursiveVisitor : virtual public VisitorBase<T>
-    {
-        using Input = typename VisitorBase<T>::Input;
-        using InputNonConst = typename std::remove_const<Input>::type;
-
-        using MapElements = std::map<std::string, InputNonConst>;
-        using ListElements = std::vector<InputNonConst>;
-
-        virtual MapElements getDictElements(Input&) = 0;
-        virtual ListElements getListElements(Input&) = 0;
-
-        virtual void visitDictOnEnter(Input& element) {};
-        virtual void visitDictOnExit(Input& element) {};
-        virtual void visitListOnEnter(Input& element) {};
-        virtual void visitListOnExit(Input& element) {};
-
-        virtual void visitNDArray(Input& element) {};
-        virtual void visitInt(Input& element) {};
-        virtual void visitLong(Input& element) {};
-        virtual void visitFloat(Input& element) {};
-        virtual void visitDouble(Input& element) {};
-        virtual void visitBool(Input& element) {};
-        virtual void visitString(Input& element) {};
-        virtual void visitUnknown(Input& element) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
-        virtual ~RecursiveVisitor() = default;
-    };
-
-    /**
-     * @see type/visitor/RecursiveVisitor.h
-     */
-    template <class T1, class T2>
-    struct RecursiveTypedVisitor : virtual public TypedVisitorBase<T1, T2>
-    {
-        using DataInput = typename TypedVisitorBase<T1, T2>::DataInput;
-        using TypeInput = typename TypedVisitorBase<T1, T2>::TypeInput;
-
-        using TypeInputNonConst = typename std::remove_const<TypeInput>::type;
-        using DataInputNonConst = typename std::remove_const<DataInput>::type;
-
-        using MapElements = std::map<std::string, std::pair<DataInputNonConst, TypeInputNonConst>>;
-        using ListElements = std::vector<std::pair<DataInputNonConst, TypeInputNonConst>>;
-        using PairElements = std::pair<std::pair<DataInputNonConst, TypeInputNonConst>, std::pair<DataInputNonConst, TypeInputNonConst>>;
-        using TupleElements = std::vector<std::pair<DataInputNonConst, TypeInputNonConst>>;
-
-        virtual MapElements getObjectElements(DataInput&, TypeInput&) = 0;
-        virtual MapElements getDictElements(DataInput&, TypeInput&) = 0;
-        virtual ListElements getListElements(DataInput&, TypeInput&) = 0;
-        virtual PairElements getPairElements(DataInput&, TypeInput&) = 0;
-        virtual TupleElements getTupleElements(DataInput&, TypeInput&) = 0;
-
-        virtual void visitObjectOnEnter(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitObjectOnExit(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitDictOnEnter(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitDictOnExit(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitPairOnEnter(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitPairOnExit(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitTupleOnEnter(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitTupleOnExit(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitListOnEnter(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitListOnExit(DataInput& elementData, TypeInput& elementType) {};
-
-        virtual void visitMatrix(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitNDArray(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitQuaternion(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitOrientation(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitPosition(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitPose(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitImage(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitPointCloud(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitIntEnum(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitInt(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitLong(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitFloat(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitDouble(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitBool(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitString(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitTime(DataInput& elementData, TypeInput& elementType) {};
-        virtual void visitUnknown(DataInput& elementData, TypeInput& elementType) {
-            throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor.");
-        }
-        virtual ~RecursiveTypedVisitor() = default;
-    };
 }
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/Visitor.h b/source/RobotAPI/libraries/aron/core/data/visitor/Visitor.h
index f2de6fd42..dc9ae66d4 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/Visitor.h
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/Visitor.h
@@ -32,10 +32,98 @@
 
 namespace armarx::aron::data
 {
+    /**
+     * @see type/visitor/Visitor.h
+     */
+    template <class T>
+    struct VisitorBase
+    {
+        using Input = T;
+
+        virtual data::Descriptor getDescriptor(Input&) = 0;
+        virtual ~VisitorBase() = default;
+    };
+
+    /**
+     * @see type/visitor/Visitor.h
+     */
+    template <class T1, class T2>
+    struct TypedVisitorBase
+    {
+        using DataInput = T1;
+        using TypeInput = T2;
+
+        virtual type::Descriptor getDescriptor(DataInput&, TypeInput&) = 0;
+        virtual ~TypedVisitorBase() = default;
+    };
+
+    /**
+     * @see type/visitor/Visitor.h
+     */
+    template <class T>
+    struct Visitor : virtual public VisitorBase<T>
+    {
+        using Input = typename VisitorBase<T>::Input;
+
+        virtual void visitDict(Input&) {};
+        virtual void visitList(Input&) {};
+        virtual void visitNDArray(Input&) {};
+        virtual void visitInt(Input&) {};
+        virtual void visitLong(Input&) {};
+        virtual void visitFloat(Input&) {};
+        virtual void visitDouble(Input&) {};
+        virtual void visitBool(Input&) {};
+        virtual void visitString(Input&) {};
+        virtual void visitUnknown(Input&) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
+        virtual ~Visitor() = default;
+    };
+
+    /**
+     * @see type/visitor/Visitor.h
+     */
+    template <class T1, class T2>
+    struct TypedVisitor : virtual public TypedVisitorBase<T1, T2>
+    {
+        using DataInput = typename TypedVisitorBase<T1, T2>::DataInput;
+        using TypeInput = typename TypedVisitorBase<T1, T2>::TypeInput;
+
+        virtual void visitObject(DataInput&, TypeInput&) {};
+        virtual void visitDict(DataInput&, TypeInput&) {};
+        virtual void visitPair(DataInput&, TypeInput&) {};
+        virtual void visitTuple(DataInput&, TypeInput&) {};
+        virtual void visitList(DataInput&, TypeInput&) {};
+        virtual void visitMatrix(DataInput&, TypeInput&) {};
+        virtual void visitNDArray(DataInput&, TypeInput&) {};
+        virtual void visitQuaternion(DataInput&, TypeInput&) {};
+        virtual void visitOrientation(DataInput&, TypeInput&) {};
+        virtual void visitPosition(DataInput&, TypeInput&) {};
+        virtual void visitPose(DataInput&, TypeInput&) {};
+        virtual void visitImage(DataInput&, TypeInput&) {};
+        virtual void visitPointCloud(DataInput&, TypeInput&) {};
+        virtual void visitIntEnum(DataInput&, TypeInput&) {};
+        virtual void visitInt(DataInput&, TypeInput&) {};
+        virtual void visitLong(DataInput&, TypeInput&) {};
+        virtual void visitFloat(DataInput&, TypeInput&) {};
+        virtual void visitDouble(DataInput&, TypeInput&) {};
+        virtual void visitBool(DataInput&, TypeInput&) {};
+        virtual void visitString(DataInput&, TypeInput&) {};
+        virtual void visitTime(DataInput&, TypeInput&) {};
+        virtual void visitUnknown(DataInput&, TypeInput&) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
+        virtual ~TypedVisitor() = default;
+    };
+
+    template <class T, class Data>
+    concept isVisitor = std::is_base_of<Visitor<Data>, T>::value;
+
+    template <class T, class Data, class Type>
+    concept isTypedVisitor = std::is_base_of<TypedVisitor<Data, Type>, T>::value;
+
+
     /**
      * @see type/visitor/Visitor.h
      */
     template <class VisitorImplementation>
+    requires isVisitor<VisitorImplementation, typename VisitorImplementation::Input>
     void visit(VisitorImplementation& v, typename VisitorImplementation::Input& o)
     {
         auto descriptor = v.getDescriptor(o);
@@ -70,9 +158,10 @@ namespace armarx::aron::data
      * Does NOT check if the data and type representation match!
      */
     template <class VisitorImplementation>
+    requires isTypedVisitor<VisitorImplementation, typename VisitorImplementation::DataInput, typename VisitorImplementation::TypeInput>
     void visit(VisitorImplementation& v, typename VisitorImplementation::DataInput& o, typename VisitorImplementation::TypeInput& t)
     {
-        auto descriptor = v.getDescriptor(t);
+        auto descriptor = v.getDescriptor(o, t);
         switch (descriptor)
         {
         case type::Descriptor::eObject:
@@ -121,84 +210,4 @@ namespace armarx::aron::data
             return v.visitUnknown(o, t);
         }
     }
-
-    /**
-     * @see type/visitor/Visitor.h
-     */
-    template <class T>
-    struct VisitorBase
-    {
-        using Input = T;
-
-        virtual data::Descriptor getDescriptor(Input&) = 0;
-        virtual ~VisitorBase() = default;
-    };
-
-    /**
-     * @see type/visitor/Visitor.h
-     */
-    template <class T1, class T2>
-    struct TypedVisitorBase
-    {
-        using DataInput = T1;
-        using TypeInput = T2;
-
-        virtual type::Descriptor getDescriptor(TypeInput&) = 0;
-        virtual ~TypedVisitorBase() = default;
-    };
-
-    /**
-     * @see type/visitor/Visitor.h
-     */
-    template <class T>
-    struct Visitor : virtual public VisitorBase<T>
-    {
-        using Input = typename VisitorBase<T>::Input;
-
-        virtual void visitDict(Input&) {};
-        virtual void visitList(Input&) {};
-        virtual void visitNDArray(Input&) {};
-        virtual void visitInt(Input&) {};
-        virtual void visitLong(Input&) {};
-        virtual void visitFloat(Input&) {};
-        virtual void visitDouble(Input&) {};
-        virtual void visitBool(Input&) {};
-        virtual void visitString(Input&) {};
-        virtual void visitUnknown(Input&) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
-        virtual ~Visitor() = default;
-    };
-
-    /**
-     * @see type/visitor/Visitor.h
-     */
-    template <class T1, class T2>
-    struct TypedVisitor : virtual public TypedVisitorBase<T1, T2>
-    {
-        using DataInput = typename TypedVisitorBase<T1, T2>::DataInput;
-        using TypeInput = typename TypedVisitorBase<T1, T2>::TypeInput;
-
-        virtual void visitObject(DataInput&, TypeInput&) {};
-        virtual void visitDict(DataInput&, TypeInput&) {};
-        virtual void visitPair(DataInput&, TypeInput&) {};
-        virtual void visitTuple(DataInput&, TypeInput&) {};
-        virtual void visitList(DataInput&, TypeInput&) {};
-        virtual void visitMatrix(DataInput&, TypeInput&) {};
-        virtual void visitNDArray(DataInput&, TypeInput&) {};
-        virtual void visitQuaternion(DataInput&, TypeInput&) {};
-        virtual void visitOrientation(DataInput&, TypeInput&) {};
-        virtual void visitPosition(DataInput&, TypeInput&) {};
-        virtual void visitPose(DataInput&, TypeInput&) {};
-        virtual void visitImage(DataInput&, TypeInput&) {};
-        virtual void visitPointCloud(DataInput&, TypeInput&) {};
-        virtual void visitIntEnum(DataInput&, TypeInput&) {};
-        virtual void visitInt(DataInput&, TypeInput&) {};
-        virtual void visitLong(DataInput&, TypeInput&) {};
-        virtual void visitFloat(DataInput&, TypeInput&) {};
-        virtual void visitDouble(DataInput&, TypeInput&) {};
-        virtual void visitBool(DataInput&, TypeInput&) {};
-        virtual void visitString(DataInput&, TypeInput&) {};
-        virtual void visitTime(DataInput&, TypeInput&) {};
-        virtual void visitUnknown(DataInput&, TypeInput&) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
-        virtual ~TypedVisitor() = default;
-    };
 }
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.cpp b/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.cpp
index 778cc6439..a91f1ac11 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.cpp
@@ -114,179 +114,190 @@ namespace armarx::aron::data
     /****************************************************************************
      * ConstTypedVariantVisitor
      ***************************************************************************/
-    type::Descriptor ConstTypedVariantVisitor::getDescriptor(TypeInput& n)
+    type::Descriptor ConstTypedVariantVisitor::GetDescriptor(DataInput& i, TypeInput& j)
     {
-        return type::ConstVariantVisitor::GetDescriptor(n);
+        auto t_desc = type::ConstVariantVisitor::GetDescriptor(j);
+        if (t_desc == type::Descriptor::eUnknown)
+        {
+            auto d_desc = ConstVariantVisitor::GetDescriptor(i);
+            t_desc = aron::data::defaultconversion::Data2TypeDescriptor.at(d_desc);
+        }
+        return t_desc;
+    }
+
+    type::Descriptor ConstTypedVariantVisitor::getDescriptor(DataInput& i, TypeInput& n)
+    {
+        return GetDescriptor(i, n);
     }
 
     void ConstTypedVariantVisitor::visitObject(DataInput& i, TypeInput& j)
     {
         auto d = data::Dict::DynamicCastAndCheck(i);
         auto t = type::Object::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitDict(DataInput& i, TypeInput& j)
     {
         auto d = data::Dict::DynamicCastAndCheck(i);
         auto t = type::Dict::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitPair(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::Pair::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitTuple(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::Tuple::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitList(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::List::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitMatrix(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Matrix::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitNDArray(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::NDArray::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitQuaternion(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Quaternion::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitOrientation(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Orientation::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitPosition(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Position::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitPose(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Pose::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitImage(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Image::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitPointCloud(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::PointCloud::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitIntEnum(DataInput& i, TypeInput& j)
     {
         auto d = data::Int::DynamicCastAndCheck(i);
         auto t = type::IntEnum::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitInt(DataInput& i, TypeInput& j)
     {
         auto d = data::Int::DynamicCastAndCheck(i);
         auto t = type::Int::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitLong(DataInput& i, TypeInput& j)
     {
         auto d = data::Long::DynamicCastAndCheck(i);
         auto t = type::Long::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitFloat(DataInput& i, TypeInput& j)
     {
         auto d = data::Float::DynamicCastAndCheck(i);
         auto t = type::Float::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitDouble(DataInput& i, TypeInput& j)
     {
         auto d = data::Double::DynamicCastAndCheck(i);
         auto t = type::Double::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitBool(DataInput& i, TypeInput& j)
     {
         auto d = data::Bool::DynamicCastAndCheck(i);
         auto t = type::Bool::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitString(DataInput& i, TypeInput& j)
     {
         auto d = data::String::DynamicCastAndCheck(i);
         auto t = type::String::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void ConstTypedVariantVisitor::visitTime(DataInput& i, TypeInput& j)
     {
         auto d = data::Long::DynamicCastAndCheck(i);
         auto t = type::Time::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
-    }
-
-    void ConstTypedVariantVisitor::visitAronVariant(const data::DictPtr&, const type::Object&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::DictPtr&, const type::Dict&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::ListPtr&, const type::List&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::ListPtr&, const type::Pair&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::ListPtr&, const type::Tuple&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Matrix&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::NDArray&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Quaternion&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Orientation&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Position&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Pose&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::PointCloud&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Image&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::IntPtr&, const type::IntEnum&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::IntPtr&, const type::Int&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::LongPtr&, const type::Long&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::LongPtr&, const type::Time&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::FloatPtr&, const type::Float&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::DoublePtr&, const type::Double&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::BoolPtr&, const type::Bool&) {}
-    void ConstTypedVariantVisitor::visitAronVariant(const data::StringPtr&, const type::String&) {}
+        visitAronVariant(d, t);
+    }
+
+    void ConstTypedVariantVisitor::visitAronVariant(const data::DictPtr&, const type::ObjectPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::DictPtr&, const type::DictPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::ListPtr&, const type::ListPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::ListPtr&, const type::PairPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::ListPtr&, const type::TuplePtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::MatrixPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::NDArrayPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::QuaternionPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::OrientationPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::PositionPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::PosePtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::PointCloudPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::ImagePtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::IntPtr&, const type::IntEnumPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::IntPtr&, const type::IntPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::LongPtr&, const type::LongPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::LongPtr&, const type::TimePtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::FloatPtr&, const type::FloatPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::DoublePtr&, const type::DoublePtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::BoolPtr&, const type::BoolPtr&) {}
+    void ConstTypedVariantVisitor::visitAronVariant(const data::StringPtr&, const type::StringPtr&) {}
 
 
 
@@ -500,9 +511,9 @@ namespace armarx::aron::data
     /****************************************************************************
      * RecursiveConstTypedVariantVisitor
      ***************************************************************************/
-    type::Descriptor RecursiveConstTypedVariantVisitor::getDescriptor(TypeInput& n)
+    type::Descriptor RecursiveConstTypedVariantVisitor::getDescriptor(DataInput& o, TypeInput& n)
     {
-        return type::ConstVariantVisitor::GetDescriptor(n);
+        return ConstTypedVariantVisitor::GetDescriptor(o, n);
     }
 
     RecursiveConstTypedVariantVisitor::MapElements
@@ -511,10 +522,16 @@ namespace armarx::aron::data
         std::map<std::string, std::pair<data::VariantPtr, type::VariantPtr>> ret;
         auto x = data::Dict::DynamicCastAndCheck(o);
         auto y = type::Object::DynamicCastAndCheck(t);
-        for (const auto& [key, e] : x->getElements())
+
+        ARMARX_CHECK_NOT_NULL(y);
+
+        if (x)
         {
-            auto ct = y->getMemberType(key);
-            ret.insert({key, {e, ct}});
+            for (const auto& [key, e] : x->getElements())
+            {
+                auto ct = y->getMemberType(key);
+                ret.insert({key, {e, ct}});
+            }
         }
         return ret;
     }
@@ -525,11 +542,15 @@ namespace armarx::aron::data
         std::map<std::string, std::pair<data::VariantPtr, type::VariantPtr>> ret;
         auto x = data::Dict::DynamicCastAndCheck(o);
         auto y = type::Dict::DynamicCastAndCheck(t);
-        auto ac = y->getAcceptedType();
 
-        for (const auto& [key, e] : x->getElements())
+        auto ac = y ? y->getAcceptedType() : nullptr;
+
+        if (x)
         {
-            ret.insert({key, {e, ac}});
+            for (const auto& [key, e] : x->getElements())
+            {
+                ret.insert({key, {e, ac}});
+            }
         }
         return ret;
     }
@@ -540,11 +561,15 @@ namespace armarx::aron::data
         std::vector<std::pair<data::VariantPtr, type::VariantPtr>> ret;
         auto x = data::List::DynamicCastAndCheck(o);
         auto y = type::List::DynamicCastAndCheck(t);
-        auto ac = y->getAcceptedType();
 
-        for (const auto& e : x->getElements())
+        auto ac = y ? y->getAcceptedType() : nullptr;
+
+        if (x)
         {
-            ret.push_back({e, ac});
+            for (const auto& e : x->getElements())
+            {
+                ret.push_back({e, ac});
+            }
         }
         return ret;
     }
@@ -555,11 +580,17 @@ namespace armarx::aron::data
         auto x = data::List::DynamicCastAndCheck(o);
         auto y = type::Pair::DynamicCastAndCheck(t);
 
-        auto e0 = x->getElement(0);
-        auto ac0 = y->getFirstAcceptedType();
-        auto e1 = x->getElement(1);
-        auto ac1 = y->getSecondAcceptedType();
-        return {{e0, ac0}, {e1, ac1}};
+        ARMARX_CHECK_NOT_NULL(y);
+
+        if (x)
+        {
+            auto e0 = x->getElement(0);
+            auto ac0 = y->getFirstAcceptedType();
+            auto e1 = x->getElement(1);
+            auto ac1 = y->getSecondAcceptedType();
+            return {{e0, ac0}, {e1, ac1}};
+        }
+        return {};
     }
 
     RecursiveConstTypedVariantVisitor::TupleElements
@@ -569,11 +600,16 @@ namespace armarx::aron::data
         auto x = data::List::DynamicCastAndCheck(o);
         auto y = type::Tuple::DynamicCastAndCheck(t);
 
-        unsigned int i = 0;
-        for (const auto& e : x->getElements())
+        ARMARX_CHECK_NOT_NULL(y);
+
+        if (x)
         {
-            auto ac = y->getAcceptedType(i++);
-            ret.push_back({e, ac});
+            unsigned int i = 0;
+            for (const auto& e : x->getElements())
+            {
+                auto ac = y->getAcceptedType(i++);
+                ret.push_back({e, ac});
+            }
         }
         return ret;
     }
@@ -612,210 +648,210 @@ namespace armarx::aron::data
     {
         auto d = data::Dict::DynamicCastAndCheck(i);
         auto t = type::Object::DynamicCastAndCheck(j);
-        visitAronVariantOnEnter(d, *t);
+        visitAronVariantOnEnter(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitDictOnEnter(DataInput& i, TypeInput& j)
     {
         auto d = data::Dict::DynamicCastAndCheck(i);
         auto t = type::Dict::DynamicCastAndCheck(j);
-        visitAronVariantOnEnter(d, *t);
+        visitAronVariantOnEnter(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitPairOnEnter(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::Pair::DynamicCastAndCheck(j);
-        visitAronVariantOnEnter(d, *t);
+        visitAronVariantOnEnter(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitTupleOnEnter(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::Tuple::DynamicCastAndCheck(j);
-        visitAronVariantOnEnter(d, *t);
+        visitAronVariantOnEnter(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitListOnEnter(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::List::DynamicCastAndCheck(j);
-        visitAronVariantOnEnter(d, *t);
+        visitAronVariantOnEnter(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitObjectOnExit(DataInput& i, TypeInput& j)
     {
         auto d = data::Dict::DynamicCastAndCheck(i);
         auto t = type::Object::DynamicCastAndCheck(j);
-        visitAronVariantOnExit(d, *t);
+        visitAronVariantOnExit(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitDictOnExit(DataInput& i, TypeInput& j)
     {
         auto d = data::Dict::DynamicCastAndCheck(i);
         auto t = type::Dict::DynamicCastAndCheck(j);
-        visitAronVariantOnExit(d, *t);
+        visitAronVariantOnExit(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitPairOnExit(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::Pair::DynamicCastAndCheck(j);
-        visitAronVariantOnExit(d, *t);
+        visitAronVariantOnExit(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitTupleOnExit(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::Tuple::DynamicCastAndCheck(j);
-        visitAronVariantOnExit(d, *t);
+        visitAronVariantOnExit(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitListOnExit(DataInput& i, TypeInput& j)
     {
         auto d = data::List::DynamicCastAndCheck(i);
         auto t = type::List::DynamicCastAndCheck(j);
-        visitAronVariantOnExit(d, *t);
+        visitAronVariantOnExit(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitMatrix(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Matrix::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitNDArray(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::NDArray::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitQuaternion(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Quaternion::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitOrientation(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Orientation::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitPosition(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Position::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitPose(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Pose::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitImage(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::Image::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitPointCloud(DataInput& i, TypeInput& j)
     {
         auto d = data::NDArray::DynamicCastAndCheck(i);
         auto t = type::PointCloud::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitIntEnum(DataInput& i, TypeInput& j)
     {
         auto d = data::Int::DynamicCastAndCheck(i);
         auto t = type::IntEnum::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitInt(DataInput& i, TypeInput& j)
     {
         auto d = data::Int::DynamicCastAndCheck(i);
         auto t = type::Int::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitLong(DataInput& i, TypeInput& j)
     {
         auto d = data::Long::DynamicCastAndCheck(i);
         auto t = type::Long::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitFloat(DataInput& i, TypeInput& j)
     {
         auto d = data::Float::DynamicCastAndCheck(i);
         auto t = type::Float::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitDouble(DataInput& i, TypeInput& j)
     {
         auto d = data::Double::DynamicCastAndCheck(i);
         auto t = type::Double::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitBool(DataInput& i, TypeInput& j)
     {
         auto d = data::Bool::DynamicCastAndCheck(i);
         auto t = type::Bool::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitString(DataInput& i, TypeInput& j)
     {
         auto d = data::String::DynamicCastAndCheck(i);
         auto t = type::String::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
     void RecursiveConstTypedVariantVisitor::visitTime(DataInput& i, TypeInput& j)
     {
         auto d = data::Long::DynamicCastAndCheck(i);
         auto t = type::Time::DynamicCastAndCheck(j);
-        visitAronVariant(d, *t);
+        visitAronVariant(d, t);
     }
 
 
     // see above
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::DictPtr&, const type::Object&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::DictPtr&, const type::Dict&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::ListPtr&, const type::List&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::ListPtr&, const type::Pair&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::ListPtr&, const type::Tuple&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::DictPtr&, const type::Object&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::DictPtr&, const type::Dict&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::ListPtr&, const type::List&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::ListPtr&, const type::Pair&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::ListPtr&, const type::Tuple&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Matrix&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::NDArray&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Quaternion&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Orientation&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Position&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Pose&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::PointCloud&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::Image&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::IntPtr&, const type::IntEnum&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::IntPtr&, const type::Int&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::LongPtr&, const type::Long&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::LongPtr&, const type::Time&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::FloatPtr&, const type::Float&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::DoublePtr&, const type::Double&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::BoolPtr&, const type::Bool&) {}
-    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::StringPtr&, const type::String&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::DictPtr&, const type::ObjectPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::DictPtr&, const type::DictPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::ListPtr&, const type::ListPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::ListPtr&, const type::PairPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnEnter(const data::ListPtr&, const type::TuplePtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::DictPtr&, const type::ObjectPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::DictPtr&, const type::DictPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::ListPtr&, const type::ListPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::ListPtr&, const type::PairPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariantOnExit(const data::ListPtr&, const type::TuplePtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::MatrixPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::NDArrayPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::QuaternionPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::OrientationPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::PositionPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::PosePtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::PointCloudPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::NDArrayPtr&, const type::ImagePtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::IntPtr&, const type::IntEnumPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::IntPtr&, const type::IntPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::LongPtr&, const type::LongPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::LongPtr&, const type::TimePtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::FloatPtr&, const type::FloatPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::DoublePtr&, const type::DoublePtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::BoolPtr&, const type::BoolPtr&) {}
+    void RecursiveConstTypedVariantVisitor::visitAronVariant(const data::StringPtr&, const type::StringPtr&) {}
 }
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h b/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h
index e1ffd36fa..8a8cc2a90 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h
@@ -71,7 +71,8 @@ namespace armarx::aron::data
      */
     struct ConstTypedVariantVisitor : virtual public TypedVisitor<const data::VariantPtr, const type::VariantPtr>
     {
-        type::Descriptor getDescriptor(TypeInput& n) override;
+        static type::Descriptor GetDescriptor(DataInput& i, TypeInput& j);
+        type::Descriptor getDescriptor(DataInput& i, TypeInput& j) override;
         virtual ~ConstTypedVariantVisitor() = default;
 
         // see above
@@ -98,27 +99,27 @@ namespace armarx::aron::data
         void visitTime(DataInput&, TypeInput&) override;
 
         // see above
-        virtual void visitAronVariant(const data::DictPtr&, const type::Object&);
-        virtual void visitAronVariant(const data::DictPtr&, const type::Dict&);
-        virtual void visitAronVariant(const data::ListPtr&, const type::List&);
-        virtual void visitAronVariant(const data::ListPtr&, const type::Pair&);
-        virtual void visitAronVariant(const data::ListPtr&, const type::Tuple&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Matrix&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::NDArray&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Quaternion&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Orientation&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Position&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Pose&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::PointCloud&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Image&);
-        virtual void visitAronVariant(const data::IntPtr&, const type::IntEnum&);
-        virtual void visitAronVariant(const data::IntPtr&, const type::Int&);
-        virtual void visitAronVariant(const data::LongPtr&, const type::Long&);
-        virtual void visitAronVariant(const data::LongPtr&, const type::Time&);
-        virtual void visitAronVariant(const data::FloatPtr&, const type::Float&);
-        virtual void visitAronVariant(const data::DoublePtr&, const type::Double&);
-        virtual void visitAronVariant(const data::BoolPtr&, const type::Bool&);
-        virtual void visitAronVariant(const data::StringPtr&, const type::String&);
+        virtual void visitAronVariant(const data::DictPtr&, const type::ObjectPtr&);
+        virtual void visitAronVariant(const data::DictPtr&, const type::DictPtr&);
+        virtual void visitAronVariant(const data::ListPtr&, const type::ListPtr&);
+        virtual void visitAronVariant(const data::ListPtr&, const type::PairPtr&);
+        virtual void visitAronVariant(const data::ListPtr&, const type::TuplePtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::MatrixPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::NDArrayPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::QuaternionPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::OrientationPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::PositionPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::PosePtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::PointCloudPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::ImagePtr&);
+        virtual void visitAronVariant(const data::IntPtr&, const type::IntEnumPtr&);
+        virtual void visitAronVariant(const data::IntPtr&, const type::IntPtr&);
+        virtual void visitAronVariant(const data::LongPtr&, const type::LongPtr&);
+        virtual void visitAronVariant(const data::LongPtr&, const type::TimePtr&);
+        virtual void visitAronVariant(const data::FloatPtr&, const type::FloatPtr&);
+        virtual void visitAronVariant(const data::DoublePtr&, const type::DoublePtr&);
+        virtual void visitAronVariant(const data::BoolPtr&, const type::BoolPtr&);
+        virtual void visitAronVariant(const data::StringPtr&, const type::StringPtr&);
     };
 
     /**
@@ -198,7 +199,7 @@ namespace armarx::aron::data
      */
     struct RecursiveConstTypedVariantVisitor : virtual public RecursiveTypedVisitor<const data::VariantPtr, const type::VariantPtr>
     {
-        type::Descriptor getDescriptor(TypeInput& n) override;
+        type::Descriptor getDescriptor(DataInput& o, TypeInput& n) override;
         static MapElements GetObjectElements(DataInput& o, TypeInput& t);
         static MapElements GetDictElements(DataInput& o, TypeInput& t);
         static ListElements GetListElements(DataInput& o, TypeInput& t);
@@ -241,31 +242,31 @@ namespace armarx::aron::data
         void visitTime(DataInput&, TypeInput&) override;
 
         // see above
-        virtual void visitAronVariantOnEnter(const data::DictPtr&, const type::Object&);
-        virtual void visitAronVariantOnEnter(const data::DictPtr&, const type::Dict&);
-        virtual void visitAronVariantOnEnter(const data::ListPtr&, const type::List&);
-        virtual void visitAronVariantOnEnter(const data::ListPtr&, const type::Pair&);
-        virtual void visitAronVariantOnEnter(const data::ListPtr&, const type::Tuple&);
-        virtual void visitAronVariantOnExit(const data::DictPtr&, const type::Object&);
-        virtual void visitAronVariantOnExit(const data::DictPtr&, const type::Dict&);
-        virtual void visitAronVariantOnExit(const data::ListPtr&, const type::List&);
-        virtual void visitAronVariantOnExit(const data::ListPtr&, const type::Pair&);
-        virtual void visitAronVariantOnExit(const data::ListPtr&, const type::Tuple&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Matrix&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::NDArray&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Quaternion&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Orientation&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Position&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Pose&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::PointCloud&);
-        virtual void visitAronVariant(const data::NDArrayPtr&, const type::Image&);
-        virtual void visitAronVariant(const data::IntPtr&, const type::IntEnum&);
-        virtual void visitAronVariant(const data::IntPtr&, const type::Int&);
-        virtual void visitAronVariant(const data::LongPtr&, const type::Long&);
-        virtual void visitAronVariant(const data::LongPtr&, const type::Time&);
-        virtual void visitAronVariant(const data::FloatPtr&, const type::Float&);
-        virtual void visitAronVariant(const data::DoublePtr&, const type::Double&);
-        virtual void visitAronVariant(const data::BoolPtr&, const type::Bool&);
-        virtual void visitAronVariant(const data::StringPtr&, const type::String&);
+        virtual void visitAronVariantOnEnter(const data::DictPtr&, const type::ObjectPtr&);
+        virtual void visitAronVariantOnEnter(const data::DictPtr&, const type::DictPtr&);
+        virtual void visitAronVariantOnEnter(const data::ListPtr&, const type::ListPtr&);
+        virtual void visitAronVariantOnEnter(const data::ListPtr&, const type::PairPtr&);
+        virtual void visitAronVariantOnEnter(const data::ListPtr&, const type::TuplePtr&);
+        virtual void visitAronVariantOnExit(const data::DictPtr&, const type::ObjectPtr&);
+        virtual void visitAronVariantOnExit(const data::DictPtr&, const type::DictPtr&);
+        virtual void visitAronVariantOnExit(const data::ListPtr&, const type::ListPtr&);
+        virtual void visitAronVariantOnExit(const data::ListPtr&, const type::PairPtr&);
+        virtual void visitAronVariantOnExit(const data::ListPtr&, const type::TuplePtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::MatrixPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::NDArrayPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::QuaternionPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::OrientationPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::PositionPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::PosePtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::PointCloudPtr&);
+        virtual void visitAronVariant(const data::NDArrayPtr&, const type::ImagePtr&);
+        virtual void visitAronVariant(const data::IntPtr&, const type::IntEnumPtr&);
+        virtual void visitAronVariant(const data::IntPtr&, const type::IntPtr&);
+        virtual void visitAronVariant(const data::LongPtr&, const type::LongPtr&);
+        virtual void visitAronVariant(const data::LongPtr&, const type::TimePtr&);
+        virtual void visitAronVariant(const data::FloatPtr&, const type::FloatPtr&);
+        virtual void visitAronVariant(const data::DoublePtr&, const type::DoublePtr&);
+        virtual void visitAronVariant(const data::BoolPtr&, const type::BoolPtr&);
+        virtual void visitAronVariant(const data::StringPtr&, const type::StringPtr&);
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/type/converter/Converter.cpp b/source/RobotAPI/libraries/aron/core/type/converter/Converter.cpp
new file mode 100644
index 000000000..a359f2b46
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/type/converter/Converter.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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 "Converter.h"
+
+namespace armarx::aron::data::converter
+{
+
+}
diff --git a/source/RobotAPI/libraries/aron/core/type/converter/Converter.h b/source/RobotAPI/libraries/aron/core/type/converter/Converter.h
new file mode 100644
index 000000000..a983de628
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/type/converter/Converter.h
@@ -0,0 +1,263 @@
+/*
+ * 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
+
+#include "../visitor/Visitor.h"
+#include "../rw/Reader.h"
+#include "../rw/Writer.h"
+
+namespace armarx::aron::type
+{
+    // prototypes
+    template <class ReaderImplementation, class WriterImplementation, class DerivedT>
+    requires isReader<ReaderImplementation> && isWriter<WriterImplementation>
+    struct Converter;
+
+    template <class T>
+    concept isConverter = std::is_base_of<Converter<typename T::ReaderType, typename T::WriterType, typename T::This>, T>::value;
+
+    template <class ConverterImplementation>
+    requires isConverter<ConverterImplementation>
+    typename ConverterImplementation::WriterReturnType readAndWrite(typename ConverterImplementation::ReaderInputType& o);
+
+    /// Converter struct providing the needed methods.
+    /// WriterImplementation is a writer class, TODO: add concepts
+    template <class ReaderImplementation, class WriterImplementation, class DerivedT>
+    requires isReader<ReaderImplementation> && isWriter<WriterImplementation>
+    struct Converter : virtual public Visitor<typename ReaderImplementation::InputType>
+    {
+        using WriterType = WriterImplementation;
+        using ReaderType = ReaderImplementation;
+        using This = DerivedT;
+        using WriterReturnType = typename WriterImplementation::ReturnType;
+        using ReaderInputType = typename ReaderImplementation::InputType;
+        using ReaderInputTypeNonConst = typename ReaderImplementation::InputTypeNonConst;
+
+        ReaderImplementation r;
+        WriterImplementation w;
+        WriterReturnType last_returned;
+
+        virtual ~Converter() = default;
+
+        void visitObject(ReaderInputType& o) final
+        {
+            std::map<std::string, ReaderInputTypeNonConst> elementsOfInput;
+            std::string name;
+            type::Maybe maybe;
+            std::map<std::string, WriterReturnType> elementsReturn;
+            r.readObject(o, name, elementsOfInput, maybe);
+            for (const auto& [key, value] : elementsOfInput)
+            {
+                auto converted = readAndWrite<DerivedT>(value);
+                elementsReturn.insert({key, converted});
+            }
+
+            last_returned = w.writeObject(name, maybe, elementsReturn);
+        }
+
+        void visitDict(ReaderInputType& o) final
+        {
+            ReaderInputTypeNonConst acceptedType;
+            type::Maybe maybe;
+            r.readDict(o, acceptedType, maybe);
+
+            auto converted = readAndWrite<DerivedT>(acceptedType);
+
+            last_returned = w.writeDict(maybe, converted);
+        };
+
+        void visitList(ReaderInputType& o) final
+        {
+            ReaderInputTypeNonConst acceptedType;
+            type::Maybe maybe;
+            r.readList(o, acceptedType, maybe);
+
+            auto converted = readAndWrite<DerivedT>(acceptedType);
+
+            last_returned = w.writeList(maybe, converted);
+        };
+
+        void visitPair(ReaderInputType& o) final
+        {
+            ReaderInputTypeNonConst acceptedType1;
+            ReaderInputTypeNonConst acceptedType2;
+            type::Maybe maybe;
+            r.readPair(o, acceptedType1, acceptedType2, maybe);
+
+            auto converted1 = readAndWrite<DerivedT>(acceptedType1);
+            auto converted2 = readAndWrite<DerivedT>(acceptedType2);
+
+            last_returned = w.writePair(maybe, converted1, converted2);
+        };
+
+        void visitTuple(ReaderInputType& o) final
+        {
+            std::vector<ReaderInputTypeNonConst> acceptedTypes;
+            std::vector<WriterReturnType> elementsReturn;
+            type::Maybe maybe;
+            r.readTuple(o, acceptedTypes, maybe);
+
+            for (const auto& el : acceptedTypes)
+            {
+                auto converted = readAndWrite<DerivedT>(el);
+                elementsReturn.push_back(converted);
+            }
+
+            last_returned = w.writeTuple(maybe, elementsReturn);
+        };
+
+        void visitNDArray(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            type::ndarray::ElementType type;
+            int ndim;
+            r.readNDArray(o, ndim, type, maybe);
+            last_returned = w.writeNDArray(ndim, type, maybe);
+        };
+
+        void visitMatrix(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            type::matrix::ElementType type;
+            int rows;
+            int cols;
+            r.readMatrix(o, rows, cols, type, maybe);
+            last_returned = w.writeMatrix(rows, cols, type, maybe);
+        };
+
+        void visitOrientation(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readOrientation(o, maybe);
+            last_returned = w.writeOrientation(maybe);
+        };
+
+        void visitQuaternion(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            type::quaternion::ElementType type;
+            r.readQuaternion(o, type, maybe);
+            last_returned = w.writeQuaternion(type, maybe);
+        };
+
+        void visitPosition(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readPosition(o, maybe);
+            last_returned = w.writePosition(maybe);
+        };
+
+        void visitPose(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readPose(o, maybe);
+            last_returned = w.writePose(maybe);
+        };
+
+        void visitImage(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            type::image::PixelType type;
+            r.readImage(o, type, maybe);
+            last_returned = w.writeImage(type, maybe);
+        };
+
+        void visitPointCloud(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            type::pointcloud::VoxelType type;
+            r.readPointCloud(o, type, maybe);
+            last_returned = w.writePointCloud(type, maybe);
+        };
+
+        void visitIntEnum(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            std::string name;
+            std::map<std::string, int> values;
+            r.readIntEnum(o, name, values, maybe);
+            last_returned = w.writeIntEnum(name, values, maybe);
+        };
+
+        void visitInt(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readInt(o, maybe);
+            last_returned = w.writeInt(maybe);
+        };
+
+        void visitLong(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readLong(o, maybe);
+            last_returned = w.writeLong(maybe);
+        };
+
+        void visitFloat(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readFloat(o, maybe);
+            last_returned = w.writeFloat(maybe);
+        };
+
+        void visitDouble(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readDouble(o, maybe);
+            last_returned = w.writeDouble(maybe);
+        };
+
+        void visitBool(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readBool(o, maybe);
+            last_returned = w.writeBool(maybe);
+        };
+
+        void visitString(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readString(o, maybe);
+            last_returned = w.writeString(maybe);
+        };
+
+        void visitTime(ReaderInputType& o) final
+        {
+            type::Maybe maybe;
+            r.readTime(o, maybe);
+            last_returned = w.writeTime(maybe);
+        };
+    };
+
+    /// the function to read from a variant and write to a writer T
+    /// returns the returntype of T
+    template <class ConverterImplementation>
+    requires isConverter<ConverterImplementation>
+    typename ConverterImplementation::WriterReturnType readAndWrite(typename ConverterImplementation::ReaderInputType& o)
+    {
+        ConverterImplementation v;
+        type::visit(v, o);
+        return v.last_returned;
+    }
+}
diff --git a/source/RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.cpp b/source/RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.cpp
new file mode 100644
index 000000000..6fdd176be
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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 "NlohmannJSONConverter.h"
+
+namespace armarx::aron::data::converter
+{
+
+}
diff --git a/source/RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.h b/source/RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.h
new file mode 100644
index 000000000..dd59bbd3f
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/type/converter/nlohmannJSON/NlohmannJSONConverter.h
@@ -0,0 +1,56 @@
+/*
+ * 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
+
+#include "../Converter.h"
+#include "../../visitor/nlohmannJSON/NlohmannJSONVisitor.h"
+#include "../../rw/reader/nlohmannJSON/NlohmannJSONReader.h"
+
+namespace armarx::aron::type
+{
+    /// Converter struct providing the needed call operators.
+    /// WriterImplementation is a writer class, TODO: add concept
+    template <class WriterImplementation, class DerivedT>
+    struct NlohmannJSONConverter :
+            virtual public Converter<aron::type::reader::NlohmannJSONReader, WriterImplementation, DerivedT>
+    {
+        using Base = Converter<aron::type::reader::NlohmannJSONReader, WriterImplementation, DerivedT>;
+
+        virtual ~NlohmannJSONConverter() = default;
+
+        type::Descriptor getDescriptor(typename Base::ReaderInputType& n) final
+        {
+            return ConstNlohmannJSONVisitor::GetDescriptor(n);
+        }
+
+        void visitUnknown(typename Base::ReaderInputType& o) final
+        {
+            if (!this->r.readNull(o))
+            {
+                throw error::AronException(__PRETTY_FUNCTION__, "A visitor got data but the enum is unknown.");
+            }
+            this->w.writeNull();
+        }
+    };
+}
diff --git a/source/RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.cpp b/source/RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.cpp
new file mode 100644
index 000000000..b4cc04ee1
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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 "VariantConverter.h"
+
+namespace armarx::aron::data::converter
+{
+
+}
diff --git a/source/RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.h b/source/RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.h
new file mode 100644
index 000000000..69a563dc1
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/core/type/converter/variant/VariantConverter.h
@@ -0,0 +1,57 @@
+/*
+ * 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
+
+#include "../Converter.h"
+#include "../../visitor/variant/VariantVisitor.h"
+#include "../../rw/reader/variant/VariantReader.h"
+
+
+namespace armarx::aron::type
+{
+    /// Converter struct providing the needed call operators.
+    /// WriterImplementation is a writer class, TODO: add concept
+    template <class WriterImplementation, class DerivedT>
+    struct VariantConverter :
+            virtual public Converter<aron::type::reader::VariantReader, WriterImplementation, DerivedT>
+    {
+        using Base = Converter<aron::type::reader::VariantReader, WriterImplementation, DerivedT>;
+
+        virtual ~VariantConverter() = default;
+
+        type::Descriptor getDescriptor(typename Base::ReaderInputType& n) final
+        {
+            return ConstVariantVisitor::GetDescriptor(n);
+        }
+
+        virtual void visitUnknown(typename Base::ReaderInputType& o) final
+        {
+            if (!this->r.readNull(o))
+            {
+                throw error::AronException(__PRETTY_FUNCTION__, "A visitor got type but the enum is unknown.");
+            }
+            this->w.writeNull();
+        }
+    };
+}
diff --git a/source/RobotAPI/libraries/aron/core/type/rw/Reader.h b/source/RobotAPI/libraries/aron/core/type/rw/Reader.h
index 00dfea092..61d457807 100644
--- a/source/RobotAPI/libraries/aron/core/type/rw/Reader.h
+++ b/source/RobotAPI/libraries/aron/core/type/rw/Reader.h
@@ -34,27 +34,29 @@ namespace armarx::aron::type
     /**
      * @brief The ReaderInterface class. It defines the interface to extract information from an aron representation
      */
-    template <class InputType>
+    template <class I>
     class ReaderInterface
     {
     public:
+        using InputType = I;
+        using InputTypeNonConst = typename std::remove_const<InputType>::type;
 
         virtual ~ReaderInterface() = default;
 
         /// Extract information from an Object type
-        virtual void readObject(const InputType& input, std::string& name, std::map<std::string, InputType>& memberTypes, type::Maybe& maybe) = 0;
+        virtual void readObject(const InputType& input, std::string& name, std::map<std::string, InputTypeNonConst>& memberTypes, type::Maybe& maybe) = 0;
 
         /// Extract information from a list type
-        virtual void readList(const InputType& input, InputType& acceptedType, type::Maybe& maybe) = 0;
+        virtual void readList(const InputType& input, InputTypeNonConst& acceptedType, type::Maybe& maybe) = 0;
 
         /// Extract information from a dict type
-        virtual void readDict(const InputType& input, InputType& acceptedType, type::Maybe& maybe) = 0;
+        virtual void readDict(const InputType& input, InputTypeNonConst& acceptedType, type::Maybe& maybe) = 0;
 
         /// Extract information from a tuple type
-        virtual void readTuple(const InputType& input, std::vector<InputType>& acceptedTypes, type::Maybe& maybe) = 0;
+        virtual void readTuple(const InputType& input, std::vector<InputTypeNonConst>& acceptedTypes, type::Maybe& maybe) = 0;
 
         /// Extract information from a pair type
-        virtual void readPair(const InputType& input, std::pair<InputType, InputType>& acceptedTypes, type::Maybe& maybe) = 0;
+        virtual void readPair(const InputType& input, InputTypeNonConst& acceptedTypes1, InputTypeNonConst& acceptedTypes2, type::Maybe& maybe) = 0;
 
         /// Extract information from a ndarray type
         virtual void readNDArray(const InputType& input, int& ndim, type::ndarray::ElementType& type, type::Maybe& maybe) = 0;
@@ -103,5 +105,15 @@ namespace armarx::aron::type
 
         /// Extract information from an time type
         virtual void readTime(const InputType& input, type::Maybe& maybe) = 0;
+
+        /// Check if input is null
+        virtual bool readNull(InputType& input) // defaulted implementation
+        {
+            InputType nil = {};
+            return input == nil;
+        }
     };
+
+    template <class T>
+    concept isReader = std::is_base_of<ReaderInterface<typename T::InputType>, T>::value;
 }
diff --git a/source/RobotAPI/libraries/aron/core/type/rw/Writer.h b/source/RobotAPI/libraries/aron/core/type/rw/Writer.h
index e0f0620a4..256aba2d3 100644
--- a/source/RobotAPI/libraries/aron/core/type/rw/Writer.h
+++ b/source/RobotAPI/libraries/aron/core/type/rw/Writer.h
@@ -34,10 +34,11 @@ namespace armarx::aron::type
     /**
      * @brief The WriterInterface class. It defines the interface to construct aron representations (e.g. variant or nlohmann::json)
      */
-    template <class ReturnType>
+    template <class R>
     class WriterInterface
     {
     public:
+        using ReturnType = R;
 
         virtual ~WriterInterface() = default;
 
@@ -103,5 +104,14 @@ namespace armarx::aron::type
 
         /// Construct a time from the params
         virtual ReturnType writeTime(const type::Maybe maybe) = 0;
+
+        /// write a null
+        virtual ReturnType writeNull() // defaulted implementation
+        {
+            return {};
+        }
     };
+
+    template <class T>
+    concept isWriter = std::is_base_of<WriterInterface<typename T::ReturnType>, T>::value;
 }
diff --git a/source/RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.cpp b/source/RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.cpp
index 0ffd1fe1e..eefe1e62e 100644
--- a/source/RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.cpp
@@ -76,14 +76,14 @@ namespace armarx::aron::type::reader
         acceptedTypes = input[rw::json::constantes::ACCEPTED_TYPE_SLUG].get<std::vector<nlohmann::json>>();
     }
 
-    void NlohmannJSONReader::readPair(const nlohmann::json& input, std::pair<nlohmann::json, nlohmann::json>& acceptedTypes, type::Maybe& maybe)
+    void NlohmannJSONReader::readPair(const nlohmann::json& input, nlohmann::json& acceptedType1, nlohmann::json& acceptedType2, type::Maybe& maybe)
     {
         checkInputForCorrectType(input, rw::json::constantes::PAIR_TYPENAME_SLUG);
 
         maybe = rw::json::conversion::String2Maybe.at(input[rw::json::constantes::MAYBE_SLUG]);
         auto list = input[rw::json::constantes::ACCEPTED_TYPE_SLUG].get<std::vector<nlohmann::json>>();
-        acceptedTypes.first = list[0];
-        acceptedTypes.second = list[1];
+        acceptedType1 = list[0];
+        acceptedType2 = list[1];
     }
 
     void NlohmannJSONReader::readNDArray(const nlohmann::json& input, int& ndim, type::ndarray::ElementType& type, type::Maybe& maybe)
diff --git a/source/RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.h b/source/RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.h
index 45b0a7950..555aa43e8 100644
--- a/source/RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.h
+++ b/source/RobotAPI/libraries/aron/core/type/rw/reader/nlohmannJSON/NlohmannJSONReader.h
@@ -33,35 +33,35 @@
 namespace armarx::aron::type::reader
 {
     class NlohmannJSONReader :
-        public ReaderInterface<nlohmann::json>
+        public ReaderInterface<const nlohmann::json>
     {
     public:
         // constructors
         NlohmannJSONReader() = default;
 
-        void readObject(const nlohmann::json& input, std::string& name, std::map<std::string, nlohmann::json>& memberTypes, type::Maybe& maybe) override;
-        void readList(const nlohmann::json& input, nlohmann::json& acceptedType, type::Maybe& maybe) override;
-        void readDict(const nlohmann::json& input, nlohmann::json& acceptedType, type::Maybe& maybe) override;
-        void readTuple(const nlohmann::json& input, std::vector<nlohmann::json>& acceptedTypes, type::Maybe& maybe) override;
-        void readPair(const nlohmann::json& input, std::pair<nlohmann::json, nlohmann::json>& acceptedTypes, type::Maybe& maybe) override;
+        void readObject(InputType& input, std::string& name, std::map<std::string, InputTypeNonConst>& memberTypes, type::Maybe& maybe) override;
+        void readList(InputType& input, InputTypeNonConst& acceptedType, type::Maybe& maybe) override;
+        void readDict(InputType& input, InputTypeNonConst& acceptedType, type::Maybe& maybe) override;
+        void readTuple(InputType& input, std::vector<InputTypeNonConst>& acceptedTypes, type::Maybe& maybe) override;
+        void readPair(InputType& input, InputTypeNonConst& acceptedType1, InputTypeNonConst& acceptedType2, type::Maybe& maybe) override;
 
-        void readNDArray(const nlohmann::json& input, int& ndim, type::ndarray::ElementType& type, type::Maybe& maybe) override;
-        void readMatrix(const nlohmann::json& input, int& rows, int& cols, type::matrix::ElementType& type, type::Maybe& maybe) override;
-        void readQuaternion(const nlohmann::json& input, type::quaternion::ElementType& type, type::Maybe& maybe) override;
-        void readPointCloud(const nlohmann::json& input, type::pointcloud::VoxelType& type, type::Maybe& maybe) override;
-        void readImage(const nlohmann::json& input, type::image::PixelType& type, type::Maybe& maybe) override;
-        void readPosition(const nlohmann::json& input, type::Maybe& maybe) override;
-        void readOrientation(const nlohmann::json& input, type::Maybe& maybe) override;
-        void readPose(const nlohmann::json& input, type::Maybe& maybe) override;
+        void readNDArray(InputType& input, int& ndim, type::ndarray::ElementType& type, type::Maybe& maybe) override;
+        void readMatrix(InputType& input, int& rows, int& cols, type::matrix::ElementType& type, type::Maybe& maybe) override;
+        void readQuaternion(InputType& input, type::quaternion::ElementType& type, type::Maybe& maybe) override;
+        void readPointCloud(InputType& input, type::pointcloud::VoxelType& type, type::Maybe& maybe) override;
+        void readImage(InputType& input, type::image::PixelType& type, type::Maybe& maybe) override;
+        void readPosition(InputType& input, type::Maybe& maybe) override;
+        void readOrientation(InputType& input, type::Maybe& maybe) override;
+        void readPose(InputType& input, type::Maybe& maybe) override;
 
-        void readIntEnum(const nlohmann::json& input, std::string& name, std::map<std::string, int>& acceptedValues, type::Maybe& maybe) override;
+        void readIntEnum(InputType& input, std::string& name, std::map<std::string, int>& acceptedValues, type::Maybe& maybe) override;
 
-        void readInt(const nlohmann::json& input, type::Maybe& maybe) override;
-        void readLong(const nlohmann::json& input, type::Maybe& maybe) override;
-        void readFloat(const nlohmann::json& input, type::Maybe& maybe) override;
-        void readDouble(const nlohmann::json& input, type::Maybe& maybe) override;
-        void readString(const nlohmann::json& input, type::Maybe& maybe) override;
-        void readBool(const nlohmann::json& input, type::Maybe& maybe) override;
-        void readTime(const nlohmann::json& input, type::Maybe& maybe) override;
+        void readInt(InputType& input, type::Maybe& maybe) override;
+        void readLong(InputType& input, type::Maybe& maybe) override;
+        void readFloat(InputType& input, type::Maybe& maybe) override;
+        void readDouble(InputType& input, type::Maybe& maybe) override;
+        void readString(InputType& input, type::Maybe& maybe) override;
+        void readBool(InputType& input, type::Maybe& maybe) override;
+        void readTime(InputType& input, type::Maybe& maybe) override;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.cpp b/source/RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.cpp
index 1be314139..2568a1543 100644
--- a/source/RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.cpp
@@ -32,7 +32,7 @@
 
 namespace armarx::aron::type::reader
 {
-    void NavigatorReader::readObject(const aron::type::VariantPtr& input, std::string& name, std::map<std::string, aron::type::VariantPtr>& memberTypes, type::Maybe& maybe)
+    void VariantReader::readObject(const aron::type::VariantPtr& input, std::string& name, std::map<std::string, aron::type::VariantPtr>& memberTypes, type::Maybe& maybe)
     {
         auto o = type::Object::DynamicCastAndCheck(input);
 
@@ -40,7 +40,7 @@ namespace armarx::aron::type::reader
         maybe = o->getMaybe();
         memberTypes = o->getMemberTypes();
     }
-    void NavigatorReader::readList(const aron::type::VariantPtr& input, aron::type::VariantPtr& acceptedType, type::Maybe& maybe)
+    void VariantReader::readList(const aron::type::VariantPtr& input, aron::type::VariantPtr& acceptedType, type::Maybe& maybe)
     {
         auto o = type::List::DynamicCastAndCheck(input);
 
@@ -48,7 +48,7 @@ namespace armarx::aron::type::reader
         acceptedType = o->getAcceptedType();
     }
 
-    void NavigatorReader::readDict(const aron::type::VariantPtr& input, aron::type::VariantPtr& acceptedType, type::Maybe& maybe)
+    void VariantReader::readDict(const aron::type::VariantPtr& input, aron::type::VariantPtr& acceptedType, type::Maybe& maybe)
     {
         auto o = type::Dict::DynamicCastAndCheck(input);
 
@@ -56,7 +56,7 @@ namespace armarx::aron::type::reader
         acceptedType = o->getAcceptedType();
     }
 
-    void NavigatorReader::readTuple(const aron::type::VariantPtr& input, std::vector<aron::type::VariantPtr>& acceptedTypes, type::Maybe& maybe)
+    void VariantReader::readTuple(const aron::type::VariantPtr& input, std::vector<aron::type::VariantPtr>& acceptedTypes, type::Maybe& maybe)
     {
         auto o = type::Tuple::DynamicCastAndCheck(input);
 
@@ -64,15 +64,16 @@ namespace armarx::aron::type::reader
         acceptedTypes = o->getAcceptedTypes();
     }
 
-    void NavigatorReader::readPair(const aron::type::VariantPtr& input, std::pair<aron::type::VariantPtr, aron::type::VariantPtr>& acceptedTypes, type::Maybe& maybe)
+    void VariantReader::readPair(const aron::type::VariantPtr& input, aron::type::VariantPtr& acceptedType1, aron::type::VariantPtr& acceptedType2, type::Maybe& maybe)
     {
         auto o = type::Pair::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
-        acceptedTypes = o->getAcceptedTypes();
+        acceptedType1 = o->getAcceptedTypes().first;
+        acceptedType2 = o->getAcceptedTypes().second;
     }
 
-    void NavigatorReader::readNDArray(const aron::type::VariantPtr& input, int& ndim, type::ndarray::ElementType& type, type::Maybe& maybe)
+    void VariantReader::readNDArray(const aron::type::VariantPtr& input, int& ndim, type::ndarray::ElementType& type, type::Maybe& maybe)
     {
         auto o = type::NDArray::DynamicCastAndCheck(input);
 
@@ -81,7 +82,7 @@ namespace armarx::aron::type::reader
         type = o->getElementType();
     }
 
-    void NavigatorReader::readMatrix(const aron::type::VariantPtr& input, int& rows, int& cols, type::matrix::ElementType& type, type::Maybe& maybe)
+    void VariantReader::readMatrix(const aron::type::VariantPtr& input, int& rows, int& cols, type::matrix::ElementType& type, type::Maybe& maybe)
     {
         auto o = type::Matrix::DynamicCastAndCheck(input);
 
@@ -91,7 +92,7 @@ namespace armarx::aron::type::reader
         type = o->getElementType();
     }
 
-    void NavigatorReader::readQuaternion(const aron::type::VariantPtr& input, type::quaternion::ElementType& type, type::Maybe& maybe)
+    void VariantReader::readQuaternion(const aron::type::VariantPtr& input, type::quaternion::ElementType& type, type::Maybe& maybe)
     {
         auto o = type::Quaternion::DynamicCastAndCheck(input);
 
@@ -99,7 +100,7 @@ namespace armarx::aron::type::reader
         type = o->getElementType();
     }
 
-    void NavigatorReader::readPointCloud(const aron::type::VariantPtr& input, type::pointcloud::VoxelType& type, type::Maybe& maybe)
+    void VariantReader::readPointCloud(const aron::type::VariantPtr& input, type::pointcloud::VoxelType& type, type::Maybe& maybe)
     {
         auto o = type::PointCloud::DynamicCastAndCheck(input);
 
@@ -107,7 +108,7 @@ namespace armarx::aron::type::reader
         type = o->getVoxelType();
     }
 
-    void NavigatorReader::readImage(const aron::type::VariantPtr& input, type::image::PixelType& type, type::Maybe& maybe)
+    void VariantReader::readImage(const aron::type::VariantPtr& input, type::image::PixelType& type, type::Maybe& maybe)
     {
         auto o = type::Image::DynamicCastAndCheck(input);
 
@@ -115,28 +116,28 @@ namespace armarx::aron::type::reader
         type = o->getPixelType();
     }
 
-    void NavigatorReader::readPosition(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readPosition(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Position::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readOrientation(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readOrientation(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Orientation::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readPose(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readPose(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Pose::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readIntEnum(const aron::type::VariantPtr& input, std::string& name, std::map<std::string, int>& acceptedValues, type::Maybe& maybe)
+    void VariantReader::readIntEnum(const aron::type::VariantPtr& input, std::string& name, std::map<std::string, int>& acceptedValues, type::Maybe& maybe)
     {
         auto o = type::IntEnum::DynamicCastAndCheck(input);
 
@@ -145,49 +146,49 @@ namespace armarx::aron::type::reader
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readInt(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readInt(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Int::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readLong(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readLong(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Long::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readFloat(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readFloat(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Float::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readDouble(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readDouble(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Double::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readString(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readString(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::String::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readBool(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readBool(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Bool::DynamicCastAndCheck(input);
 
         maybe = o->getMaybe();
     }
 
-    void NavigatorReader::readTime(const aron::type::VariantPtr& input, type::Maybe& maybe)
+    void VariantReader::readTime(const aron::type::VariantPtr& input, type::Maybe& maybe)
     {
         auto o = type::Time::DynamicCastAndCheck(input);
 
diff --git a/source/RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.h b/source/RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.h
index 3a453e6a1..6ce41ec96 100644
--- a/source/RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.h
+++ b/source/RobotAPI/libraries/aron/core/type/rw/reader/variant/VariantReader.h
@@ -33,36 +33,36 @@
 
 namespace armarx::aron::type::reader
 {
-    class NavigatorReader :
-        public ReaderInterface<aron::type::VariantPtr>
+    class VariantReader :
+        public ReaderInterface<const aron::type::VariantPtr>
     {
     public:
         // constructors
-        NavigatorReader() = default;
+        VariantReader() = default;
 
-        void readObject(const aron::type::VariantPtr& input, std::string& name, std::map<std::string, aron::type::VariantPtr>& memberTypes, type::Maybe& maybe) override;
-        void readList(const aron::type::VariantPtr& input, aron::type::VariantPtr& acceptedType, type::Maybe& maybe) override;
-        void readDict(const aron::type::VariantPtr& input, aron::type::VariantPtr& acceptedType, type::Maybe& maybe) override;
-        void readTuple(const aron::type::VariantPtr& input, std::vector<aron::type::VariantPtr>& acceptedTypes, type::Maybe& maybe) override;
-        void readPair(const aron::type::VariantPtr& input, std::pair<aron::type::VariantPtr, aron::type::VariantPtr>& acceptedTypes, type::Maybe& maybe) override;
+        void readObject(InputType& input, std::string& name, std::map<std::string, InputTypeNonConst>& memberTypes, type::Maybe& maybe) override;
+        void readList(InputType& input, InputTypeNonConst& acceptedType, type::Maybe& maybe) override;
+        void readDict(InputType& input, InputTypeNonConst& acceptedType, type::Maybe& maybe) override;
+        void readTuple(InputType& input, std::vector<InputTypeNonConst>& acceptedTypes, type::Maybe& maybe) override;
+        void readPair(InputType& input, InputTypeNonConst& acceptedType1, InputTypeNonConst& acceptedType2, type::Maybe& maybe) override;
 
-        void readNDArray(const aron::type::VariantPtr& input, int& ndim, type::ndarray::ElementType& type, type::Maybe& maybe) override;
-        void readMatrix(const aron::type::VariantPtr& input, int& rows, int& cols, type::matrix::ElementType& type, type::Maybe& maybe) override;
-        void readQuaternion(const aron::type::VariantPtr& input, type::quaternion::ElementType& type, type::Maybe& maybe) override;
-        void readPointCloud(const aron::type::VariantPtr& input, type::pointcloud::VoxelType& type, type::Maybe& maybe) override;
-        void readImage(const aron::type::VariantPtr& input, type::image::PixelType& type, type::Maybe& maybe) override;
-        void readPosition(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
-        void readOrientation(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
-        void readPose(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
+        void readNDArray(InputType& input, int& ndim, type::ndarray::ElementType& type, type::Maybe& maybe) override;
+        void readMatrix(InputType& input, int& rows, int& cols, type::matrix::ElementType& type, type::Maybe& maybe) override;
+        void readQuaternion(InputType& input, type::quaternion::ElementType& type, type::Maybe& maybe) override;
+        void readPointCloud(InputType& input, type::pointcloud::VoxelType& type, type::Maybe& maybe) override;
+        void readImage(InputType& input, type::image::PixelType& type, type::Maybe& maybe) override;
+        void readPosition(InputType& input, type::Maybe& maybe) override;
+        void readOrientation(InputType& input, type::Maybe& maybe) override;
+        void readPose(InputType& input, type::Maybe& maybe) override;
 
-        void readIntEnum(const aron::type::VariantPtr& input, std::string& name, std::map<std::string, int>& acceptedValues, type::Maybe& maybe) override;
+        void readIntEnum(InputType& input, std::string& name, std::map<std::string, int>& acceptedValues, type::Maybe& maybe) override;
 
-        void readInt(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
-        void readLong(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
-        void readFloat(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
-        void readDouble(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
-        void readString(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
-        void readBool(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
-        void readTime(const aron::type::VariantPtr& input, type::Maybe& maybe) override;
+        void readInt(InputType& input, type::Maybe& maybe) override;
+        void readLong(InputType& input, type::Maybe& maybe) override;
+        void readFloat(InputType& input, type::Maybe& maybe) override;
+        void readDouble(InputType& input, type::Maybe& maybe) override;
+        void readString(InputType& input, type::Maybe& maybe) override;
+        void readBool(InputType& input, type::Maybe& maybe) override;
+        void readTime(InputType& input, type::Maybe& maybe) override;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/type/rw/writer/nlohmannJSON/NlohmannJSONWriter.h b/source/RobotAPI/libraries/aron/core/type/rw/writer/nlohmannJSON/NlohmannJSONWriter.h
index c52035d64..0733514e9 100644
--- a/source/RobotAPI/libraries/aron/core/type/rw/writer/nlohmannJSON/NlohmannJSONWriter.h
+++ b/source/RobotAPI/libraries/aron/core/type/rw/writer/nlohmannJSON/NlohmannJSONWriter.h
@@ -39,29 +39,29 @@ namespace armarx::aron::type::writer
     public:
         NlohmannJSONWriter() = default;
 
-        virtual nlohmann::json writeObject(const std::string& name, const type::Maybe maybe, const std::map<std::string, nlohmann::json>& memberTypes, const std::optional<nlohmann::json>& extends = std::nullopt) override;
-        virtual nlohmann::json writeList(const type::Maybe maybe, const nlohmann::json& acceptedType) override;
-        virtual nlohmann::json writeDict(const type::Maybe maybe, const nlohmann::json& acceptedType) override;
-        virtual nlohmann::json writePair(const type::Maybe maybe, const nlohmann::json& acceptedType1, const nlohmann::json& acceptedType2) override;
-        virtual nlohmann::json writeTuple(const type::Maybe maybe, const std::vector<nlohmann::json>& acceptedTypes) override;
+        virtual ReturnType writeObject(const std::string& name, const type::Maybe maybe, const std::map<std::string, ReturnType>& memberTypes, const std::optional<ReturnType>& extends = std::nullopt) override;
+        virtual ReturnType writeList(const type::Maybe maybe, const ReturnType& acceptedType) override;
+        virtual ReturnType writeDict(const type::Maybe maybe, const ReturnType& acceptedType) override;
+        virtual ReturnType writePair(const type::Maybe maybe, const ReturnType& acceptedType1, const ReturnType& acceptedType2) override;
+        virtual ReturnType writeTuple(const type::Maybe maybe, const std::vector<ReturnType>& acceptedTypes) override;
 
-        virtual nlohmann::json writeNDArray(const int ndim, const type::ndarray::ElementType, const type::Maybe maybe) override;
-        virtual nlohmann::json writeMatrix(const int rows, const int cols, const type::matrix::ElementType type, const type::Maybe maybe) override;
-        virtual nlohmann::json writeQuaternion(const type::quaternion::ElementType, const type::Maybe maybe) override;
-        virtual nlohmann::json writeImage(const type::image::PixelType, const type::Maybe maybe) override;
-        virtual nlohmann::json writePointCloud(const type::pointcloud::VoxelType, const type::Maybe maybe) override;
-        virtual nlohmann::json writePosition(const type::Maybe maybe) override;
-        virtual nlohmann::json writeOrientation(const type::Maybe maybe) override;
-        virtual nlohmann::json writePose(const type::Maybe maybe) override;
+        virtual ReturnType writeNDArray(const int ndim, const type::ndarray::ElementType, const type::Maybe maybe) override;
+        virtual ReturnType writeMatrix(const int rows, const int cols, const type::matrix::ElementType type, const type::Maybe maybe) override;
+        virtual ReturnType writeQuaternion(const type::quaternion::ElementType, const type::Maybe maybe) override;
+        virtual ReturnType writeImage(const type::image::PixelType, const type::Maybe maybe) override;
+        virtual ReturnType writePointCloud(const type::pointcloud::VoxelType, const type::Maybe maybe) override;
+        virtual ReturnType writePosition(const type::Maybe maybe) override;
+        virtual ReturnType writeOrientation(const type::Maybe maybe) override;
+        virtual ReturnType writePose(const type::Maybe maybe) override;
 
-        virtual nlohmann::json writeIntEnum(const std::string& name, const std::map<std::string, int>& acceptedValues, const type::Maybe maybe) override;
+        virtual ReturnType writeIntEnum(const std::string& name, const std::map<std::string, int>& acceptedValues, const type::Maybe maybe) override;
 
-        virtual nlohmann::json writeInt(const type::Maybe maybe) override;
-        virtual nlohmann::json writeLong(const type::Maybe maybe) override;
-        virtual nlohmann::json writeFloat(const type::Maybe maybe) override;
-        virtual nlohmann::json writeDouble(const type::Maybe maybe) override;
-        virtual nlohmann::json writeString(const type::Maybe maybe) override;
-        virtual nlohmann::json writeBool(const type::Maybe maybe) override;
-        virtual nlohmann::json writeTime(const type::Maybe maybe) override;
+        virtual ReturnType writeInt(const type::Maybe maybe) override;
+        virtual ReturnType writeLong(const type::Maybe maybe) override;
+        virtual ReturnType writeFloat(const type::Maybe maybe) override;
+        virtual ReturnType writeDouble(const type::Maybe maybe) override;
+        virtual ReturnType writeString(const type::Maybe maybe) override;
+        virtual ReturnType writeBool(const type::Maybe maybe) override;
+        virtual ReturnType writeTime(const type::Maybe maybe) override;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/type/rw/writer/variant/VariantWriter.h b/source/RobotAPI/libraries/aron/core/type/rw/writer/variant/VariantWriter.h
index c2f105629..3a17a435e 100644
--- a/source/RobotAPI/libraries/aron/core/type/rw/writer/variant/VariantWriter.h
+++ b/source/RobotAPI/libraries/aron/core/type/rw/writer/variant/VariantWriter.h
@@ -35,29 +35,29 @@ namespace armarx::aron::type::writer
     public:
         VariantWriter() = default;
 
-        virtual aron::type::VariantPtr writeObject(const std::string& name, const type::Maybe maybe, const std::map<std::string, aron::type::VariantPtr>& memberTypes, const std::optional<aron::type::VariantPtr>& extends = std::nullopt) override;
-        virtual aron::type::VariantPtr writeList(const type::Maybe maybe, const aron::type::VariantPtr& acceptedType) override;
-        virtual aron::type::VariantPtr writeDict(const type::Maybe maybe, const aron::type::VariantPtr& acceptedType) override;
-        virtual aron::type::VariantPtr writePair(const type::Maybe maybe, const aron::type::VariantPtr& acceptedType1, const aron::type::VariantPtr& acceptedType2) override;
-        virtual aron::type::VariantPtr writeTuple(const type::Maybe maybe, const std::vector<aron::type::VariantPtr>& acceptedTypes) override;
-
-        virtual aron::type::VariantPtr writeNDArray(const int ndim, const type::ndarray::ElementType, const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeMatrix(const int rows, const int cols, const type::matrix::ElementType type, const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeQuaternion(const type::quaternion::ElementType, const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeImage(const type::image::PixelType, const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writePointCloud(const type::pointcloud::VoxelType, const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writePosition(const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeOrientation(const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writePose(const type::Maybe maybe) override;
-
-        virtual aron::type::VariantPtr writeIntEnum(const std::string& name, const std::map<std::string, int>& acceptedValues, const type::Maybe maybe) override;
-
-        virtual aron::type::VariantPtr writeInt(const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeLong(const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeFloat(const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeDouble(const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeString(const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeBool(const type::Maybe maybe) override;
-        virtual aron::type::VariantPtr writeTime(const type::Maybe maybe) override;
+        virtual ReturnType writeObject(const std::string& name, const type::Maybe maybe, const std::map<std::string, ReturnType>& memberTypes, const std::optional<ReturnType>& extends = std::nullopt) override;
+        virtual ReturnType writeList(const type::Maybe maybe, const ReturnType& acceptedType) override;
+        virtual ReturnType writeDict(const type::Maybe maybe, const ReturnType& acceptedType) override;
+        virtual ReturnType writePair(const type::Maybe maybe, const ReturnType& acceptedType1, const ReturnType& acceptedType2) override;
+        virtual ReturnType writeTuple(const type::Maybe maybe, const std::vector<ReturnType>& acceptedTypes) override;
+
+        virtual ReturnType writeNDArray(const int ndim, const type::ndarray::ElementType, const type::Maybe maybe) override;
+        virtual ReturnType writeMatrix(const int rows, const int cols, const type::matrix::ElementType type, const type::Maybe maybe) override;
+        virtual ReturnType writeQuaternion(const type::quaternion::ElementType, const type::Maybe maybe) override;
+        virtual ReturnType writeImage(const type::image::PixelType, const type::Maybe maybe) override;
+        virtual ReturnType writePointCloud(const type::pointcloud::VoxelType, const type::Maybe maybe) override;
+        virtual ReturnType writePosition(const type::Maybe maybe) override;
+        virtual ReturnType writeOrientation(const type::Maybe maybe) override;
+        virtual ReturnType writePose(const type::Maybe maybe) override;
+
+        virtual ReturnType writeIntEnum(const std::string& name, const std::map<std::string, int>& acceptedValues, const type::Maybe maybe) override;
+
+        virtual ReturnType writeInt(const type::Maybe maybe) override;
+        virtual ReturnType writeLong(const type::Maybe maybe) override;
+        virtual ReturnType writeFloat(const type::Maybe maybe) override;
+        virtual ReturnType writeDouble(const type::Maybe maybe) override;
+        virtual ReturnType writeString(const type::Maybe maybe) override;
+        virtual ReturnType writeBool(const type::Maybe maybe) override;
+        virtual ReturnType writeTime(const type::Maybe maybe) override;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/type/variant/Variant.h b/source/RobotAPI/libraries/aron/core/type/variant/Variant.h
index 3b189122e..faaf06cdc 100644
--- a/source/RobotAPI/libraries/aron/core/type/variant/Variant.h
+++ b/source/RobotAPI/libraries/aron/core/type/variant/Variant.h
@@ -135,4 +135,7 @@ namespace armarx::aron::type
     private:
         static const VariantFactoryPtr FACTORY;
     };
+
+    template <class T>
+    concept isVariant = std::is_base_of<Variant, T>::value;
 }
diff --git a/source/RobotAPI/libraries/aron/core/type/visitor/nlohmannJSON/NlohmannJSONVisitor.cpp b/source/RobotAPI/libraries/aron/core/type/visitor/nlohmannJSON/NlohmannJSONVisitor.cpp
index b99a9228c..528fe3577 100644
--- a/source/RobotAPI/libraries/aron/core/type/visitor/nlohmannJSON/NlohmannJSONVisitor.cpp
+++ b/source/RobotAPI/libraries/aron/core/type/visitor/nlohmannJSON/NlohmannJSONVisitor.cpp
@@ -26,13 +26,13 @@
 
 namespace armarx::aron::type
 {
-    type::Descriptor NlohmannJSONVisitor::GetDescriptor(Input& n)
+    type::Descriptor ConstNlohmannJSONVisitor::GetDescriptor(Input& n)
     {
         std::string t = n[armarx::aron::type::rw::json::constantes::TYPE_SLUG];
         return armarx::aron::type::rw::json::conversion::String2Descriptor.at(t);
     }
 
-    type::Descriptor NlohmannJSONVisitor::getDescriptor(Input& n)
+    type::Descriptor ConstNlohmannJSONVisitor::getDescriptor(Input& n)
     {
         return GetDescriptor(n);
     }
diff --git a/source/RobotAPI/libraries/aron/core/type/visitor/nlohmannJSON/NlohmannJSONVisitor.h b/source/RobotAPI/libraries/aron/core/type/visitor/nlohmannJSON/NlohmannJSONVisitor.h
index 9618654d0..b56b4ab1c 100644
--- a/source/RobotAPI/libraries/aron/core/type/visitor/nlohmannJSON/NlohmannJSONVisitor.h
+++ b/source/RobotAPI/libraries/aron/core/type/visitor/nlohmannJSON/NlohmannJSONVisitor.h
@@ -38,11 +38,11 @@ namespace armarx::aron::type
     /**
      * @brief The NlohmannJSONVisitor struct. Already implements the method to get the descriptor of a nlohmann::json
      */
-    struct NlohmannJSONVisitor : virtual public Visitor<const nlohmann::json>
+    struct ConstNlohmannJSONVisitor : virtual public Visitor<const nlohmann::json>
     {
         static type::Descriptor GetDescriptor(Input& n);
         type::Descriptor getDescriptor(Input& n) override;
-        virtual ~NlohmannJSONVisitor() = default;
+        virtual ~ConstNlohmannJSONVisitor() = default;
     };
 
     // TODO
diff --git a/source/RobotAPI/libraries/aron/core/type/visitor/variant/VariantVisitor.cpp b/source/RobotAPI/libraries/aron/core/type/visitor/variant/VariantVisitor.cpp
index a6fa9e7dc..ae5b60e7f 100644
--- a/source/RobotAPI/libraries/aron/core/type/visitor/variant/VariantVisitor.cpp
+++ b/source/RobotAPI/libraries/aron/core/type/visitor/variant/VariantVisitor.cpp
@@ -33,6 +33,10 @@ namespace armarx::aron::type
      ***************************************************************************/
     type::Descriptor ConstVariantVisitor::GetDescriptor(Input& n)
     {
+        if (!n)
+        {
+            return type::Descriptor::eUnknown;
+        }
         return n->getDescriptor();
     }
 
@@ -41,7 +45,6 @@ namespace armarx::aron::type
         return GetDescriptor(n);
     }
 
-
     /****************************************************************************
      * RecursiveVariantVisitor
      ***************************************************************************/
-- 
GitLab