diff --git a/Modules/Core/include/mitkAnnotationProperty.h b/Modules/Core/include/mitkAnnotationProperty.h
index 310a432405..9c03069090 100644
--- a/Modules/Core/include/mitkAnnotationProperty.h
+++ b/Modules/Core/include/mitkAnnotationProperty.h
@@ -1,79 +1,83 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkAnnotationProperty_h
 #define mitkAnnotationProperty_h
 
 #include "mitkBaseProperty.h"
 #include "mitkNumericTypes.h"
 #include <MitkCoreExports.h>
 
 #include <itkConfigure.h>
 
 #include <string>
 
 namespace mitk
 {
   /**
    * \brief Property for annotations
    * \ingroup DataManagement
    */
   class MITKCORE_EXPORT AnnotationProperty : public BaseProperty
   {
   public:
     mitkClassMacro(AnnotationProperty, BaseProperty);
 
     typedef std::string ValueType;
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self)
       mitkNewMacro2Param(AnnotationProperty, const char *, const Point3D &);
     mitkNewMacro2Param(AnnotationProperty, const std::string &, const Point3D &);
     mitkNewMacro4Param(AnnotationProperty, const char *, ScalarType, ScalarType, ScalarType);
     mitkNewMacro4Param(AnnotationProperty, const std::string &, ScalarType, ScalarType, ScalarType);
 
     itkGetStringMacro(Label);
     itkSetStringMacro(Label);
 
     const Point3D &GetPosition() const;
     void SetPosition(const Point3D &position);
 
     std::string GetValueAsString() const override;
+
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     virtual BaseProperty &operator=(const BaseProperty &other) { return Superclass::operator=(other); }
     using BaseProperty::operator=;
 
   protected:
     std::string m_Label;
     Point3D m_Position;
 
     AnnotationProperty();
     AnnotationProperty(const char *label, const Point3D &position);
     AnnotationProperty(const std::string &label, const Point3D &position);
     AnnotationProperty(const char *label, ScalarType x, ScalarType y, ScalarType z);
     AnnotationProperty(const std::string &label, ScalarType x, ScalarType y, ScalarType z);
 
     AnnotationProperty(const AnnotationProperty &other);
 
   private:
     // purposely not implemented
     AnnotationProperty &operator=(const AnnotationProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkBaseProperty.h b/Modules/Core/include/mitkBaseProperty.h
index a0f02b6da6..f99c775f5d 100644
--- a/Modules/Core/include/mitkBaseProperty.h
+++ b/Modules/Core/include/mitkBaseProperty.h
@@ -1,102 +1,115 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkBaseProperty_h
 #define mitkBaseProperty_h
 
 #include <MitkCoreExports.h>
 #include <itkObjectFactory.h>
 #include <mitkCommon.h>
 #include <string>
-#include <nlohmann/json.hpp>
+#include <nlohmann/json_fwd.hpp>
 
 namespace mitk
 {
   /*! \brief Abstract base class for properties
 
     \ingroup DataManagement
 
       Base class for properties. Properties are arbitrary additional information
       (to define a new type of information you have to define a subclass of
       BaseProperty) that can be added to a PropertyList.
       Concrete subclasses of BaseProperty should define Set-/Get-methods to assess
       the property value, which should be stored by value (not by reference).
       Subclasses must implement an operator==(const BaseProperty& property), which
       is used by PropertyList to check whether a property has been changed.
   */
   class MITKCORE_EXPORT BaseProperty : public itk::Object
   {
   public:
     mitkClassMacroItkParent(BaseProperty, itk::Object);
     itkCloneMacro(Self);
 
       /*! @brief Subclasses must implement IsEqual(const BaseProperty&) to support comparison.
 
           operator== which is used by PropertyList to check whether a property has been changed.
       */
       bool
       operator==(const BaseProperty &property) const;
 
     /*! @brief Assigns property to this BaseProperty instance.
 
         Subclasses must implement Assign(const BaseProperty&) and call the superclass
         Assign method for proper handling of polymorphic assignments. The assignment
         operator of the subclass should be disabled and the baseclass operator should
         be made visible using "using" statements.
     */
     BaseProperty &operator=(const BaseProperty &property);
 
     /*! @brief Assigns property to this BaseProperty instance.
 
         This method is identical to the assignment operator, except for the return type.
         It allows to directly check if the assignment was successful.
     */
     bool AssignProperty(const BaseProperty &property);
 
     virtual std::string GetValueAsString() const;
 
-    virtual void ToJSON(nlohmann::json& j) const = 0;
-    virtual void FromJSON(const nlohmann::json& j) = 0;
+    /** \brief Serialize property value(s) to JSON.
+     *
+     * Rely on exceptions for error handling when implementing serialization.
+     *
+     * \return False if not serializable by design, true otherwise.
+     */
+    virtual bool ToJSON(nlohmann::json& j) const = 0;
+
+    /** \brief Deserialize property value(s) from JSON.
+    *
+    * Rely on exceptions for error handling when implementing deserialization.
+    *
+    * \return False if not deserializable by design, true otherwise.
+    */
+    virtual bool FromJSON(const nlohmann::json& j) = 0;
 
     /**
      * @brief Default return value if a property which can not be returned as string
      */
     static const std::string VALUE_CANNOT_BE_CONVERTED_TO_STRING;
 
   protected:
     BaseProperty();
     BaseProperty(const BaseProperty &other);
 
     ~BaseProperty() override;
 
   private:
     /*!
       Override this method in subclasses to implement a meaningful comparison. The property
       argument is guaranteed to be castable to the type of the implementing subclass.
     */
     virtual bool IsEqual(const BaseProperty &property) const = 0;
 
     /*!
       Override this method in subclasses to implement a meaningful assignment. The property
       argument is guaranteed to be castable to the type of the implementing subclass.
 
       @warning This is not yet exception aware/safe and if this method returns false,
                this property's state might be undefined.
 
       @return True if the argument could be assigned to this property.
      */
     virtual bool Assign(const BaseProperty &) = 0;
   };
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkClippingProperty.h b/Modules/Core/include/mitkClippingProperty.h
index 87bdc056b1..9e3f532572 100644
--- a/Modules/Core/include/mitkClippingProperty.h
+++ b/Modules/Core/include/mitkClippingProperty.h
@@ -1,87 +1,90 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkClippingProperty_h
 #define mitkClippingProperty_h
 
 #include "mitkBaseProperty.h"
 #include "mitkNumericTypes.h"
 #include <MitkCoreExports.h>
 
 #include <itkConfigure.h>
 
 #include <string>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /**
    * \brief Property for clipping datasets; currently only
    * clipping planes are possible
    * \ingroup DataManagement
    */
   class MITKCORE_EXPORT ClippingProperty : public BaseProperty
   {
   public:
     mitkClassMacro(ClippingProperty, BaseProperty);
 
     typedef std::string ValueType;
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self)
       mitkNewMacro2Param(ClippingProperty, const Point3D &, const Vector3D &);
 
     bool GetClippingEnabled() const;
     void SetClippingEnabled(bool enabled);
 
     const Point3D &GetOrigin() const;
     void SetOrigin(const Point3D &origin);
 
     const Vector3D &GetNormal() const;
     void SetNormal(const Vector3D &normal);
 
     std::string GetValueAsString() const override;
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     using BaseProperty::operator=;
 
   protected:
     bool m_ClippingEnabled;
 
     Point3D m_Origin;
     Vector3D m_Normal;
 
     ClippingProperty();
     ClippingProperty(const ClippingProperty &other);
     ClippingProperty(const Point3D &origin, const Vector3D &normal);
 
   private:
     // purposely not implemented
     ClippingProperty &operator=(const ClippingProperty &);
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
 
     itk::LightObject::Pointer InternalClone() const override;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkColorProperty.h b/Modules/Core/include/mitkColorProperty.h
index a90567c2b1..c4a3ae0be4 100644
--- a/Modules/Core/include/mitkColorProperty.h
+++ b/Modules/Core/include/mitkColorProperty.h
@@ -1,118 +1,118 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkColorProperty_h
 #define mitkColorProperty_h
 
 #include "mitkBaseProperty.h"
 #include <MitkCoreExports.h>
 #include <itkRGBPixel.h>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /**
    * @brief Color Standard RGB color typedef (float)
    *
    * Standard RGB color typedef to get rid of template argument (float).
    * Color range is from 0.0f to 1.0f for each component.
    *
    * @ingroup Property
    */
   typedef itk::RGBPixel<float> Color;
 
   /**
    * @brief The ColorProperty class RGB color property
    * @ingroup DataManagement
    *
    * @note If you want to apply the mitk::ColorProperty to an mitk::Image
    * make sure to set the mitk::RenderingModeProperty to a mode which
    * supports color (e.g. LEVELWINDOW_COLOR). For an example how to use
    * the mitk::ColorProperty see mitkImageVtkMapper2DColorTest.cpp in
    * Core/Code/Rendering.
    */
   class MITKCORE_EXPORT ColorProperty : public BaseProperty
   {
   protected:
     mitk::Color m_Color;
 
     ColorProperty();
 
     ColorProperty(const ColorProperty &other);
 
     ColorProperty(const float red, const float green, const float blue);
 
     ColorProperty(const float color[3]);
 
     ColorProperty(const mitk::Color &color);
 
   public:
     mitkClassMacro(ColorProperty, BaseProperty);
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self) mitkNewMacro1Param(ColorProperty, const float *);
     mitkNewMacro1Param(ColorProperty, const mitk::Color &);
     mitkNewMacro3Param(ColorProperty, const float, const float, const float);
 
     typedef mitk::Color ValueType;
 
     const mitk::Color &GetColor() const;
     const mitk::Color &GetValue() const;
     std::string GetValueAsString() const override;
     void SetColor(const mitk::Color &color);
     void SetValue(const mitk::Color &color);
     void SetColor(float red, float green, float blue);
 
-    void ToJSON(nlohmann::json &j) const override;
-    void FromJSON(const nlohmann::json &j) override;
+    bool ToJSON(nlohmann::json &j) const override;
+    bool FromJSON(const nlohmann::json &j) override;
 
     using BaseProperty::operator=;
 
   private:
     // purposely not implemented
     ColorProperty &operator=(const ColorProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 namespace itk
 {
   template <typename TComponent>
   void to_json(nlohmann::json& j, const RGBPixel<TComponent>& c)
   {
     j = nlohmann::json::array();
 
     for (size_t i = 0; i < 3; ++i)
       j.push_back(c[i]);
   }
 
   template <typename TComponent>
   void from_json(const nlohmann::json& j, RGBPixel<TComponent>& c)
   {
     for (size_t i = 0; i < 3; ++i)
       j.at(i).get_to(c[i]);
   }
 } // namespace itk
 
 #endif
diff --git a/Modules/Core/include/mitkEnumerationProperty.h b/Modules/Core/include/mitkEnumerationProperty.h
index 3d5b827542..8ec695d872 100644
--- a/Modules/Core/include/mitkEnumerationProperty.h
+++ b/Modules/Core/include/mitkEnumerationProperty.h
@@ -1,197 +1,197 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkEnumerationProperty_h
 #define mitkEnumerationProperty_h
 
 #include <mitkBaseProperty.h>
 
 #include <map>
 #include <string>
 
 #ifdef _MSC_VER
 #  pragma warning(push)
 #  pragma warning(disable: 4522) // "multiple assignment operators specified"
 #endif
 
 namespace mitk
 {
   /**
    * This class may be used to store properties similar to enumeration values.
    * Each enumeration value is identified by an id and a name. Note that both
    * name and id must be unique. Add enumeration values before you use the
    * Get/SetValue methods.
    *
    * To use this class, create a subclass that adds the possible enumeration
    * values in its constructor. You should override AddEnum() as protected so
    * that the user isn't able to add invalid enumeration values.
    *
    * As example see mitk::VtkRepresentationProperty or
    * mitk::VtkInterpolationProperty.
    *
    * @ingroup DataManagement
    */
   class MITKCORE_EXPORT EnumerationProperty : public BaseProperty
   {
   public:
     mitkClassMacro(EnumerationProperty, BaseProperty);
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self);
 
     /**
      * Represents the unique id which is assigned to each enumeration name.
      */
     typedef unsigned int IdType;
 
     /**
      * Type used to store a mapping from enumeration id to enumeration name.
      */
     typedef std::map<IdType, std::string> EnumIdsContainerType;
 
     /**
      * Type used to store a mapping from enumeration name to enumeration id.
      */
     typedef std::map<std::string, IdType> EnumStringsContainerType;
 
     /**
      * Type used for iterators over all defined enumeration values.
      */
     typedef EnumIdsContainerType::const_iterator EnumConstIterator;
 
     /**
      * Adds an enumeration value into the enumeration. The name and id provided
      * must be unique. This is checked while adding the new enumeration value.
      * If it is not unique, false is returned. If addition was successful, true
      * is returned.
      * @param name The unique name of the enumeration value
      * @param id The unique id of the enumeration value
      * @returns True, if the name/id combination was successfully added to the
      * enumeration values. Otherwise false.
      */
     virtual bool AddEnum(const std::string &name, const IdType &id);
 
     /**
      * Sets the current value of the enumeration.
      * @param name The name of the enumeration value to set
      * @returns True if the value was successfully set. Otherwise false.
      */
     virtual bool SetValue(const std::string &name);
 
     /**
      * Sets the current value of the enumeration.
      * @param id The id of the enumeration value to set
      * @returns True, if the value was successfully set. Otherwise false.
      */
     virtual bool SetValue(const IdType &id);
 
     /**
      * Returns the id of the current enumeration value. If it was not set so far,
      * the return value is unspecified.
      */
     virtual IdType GetValueAsId() const;
 
     /**
      * Returns the name of the current enumeration value. If it was not set so far,
      * the return value is unspecified.
      */
     std::string GetValueAsString() const override;
 
     /**
      * Clears all enumerations including the current one.
      */
     virtual void Clear();
 
     /**
      * Determines the number of enumeration values.
      */
     virtual EnumIdsContainerType::size_type Size() const;
 
     /**
      * Provides access to the set of enumeration values. The name can be
      * accessed with iterator->second, the id via iterator->first.
      * @returns An iterator over all enumeration values.
      */
     virtual EnumConstIterator Begin() const;
 
     /**
      * Specifies the end of the range of enumeration values.
      * @returns An iterator pointing past the last enumeration values.
      */
     virtual EnumConstIterator End() const;
 
     /**
      * Returns the name for the given id.
      * @param id The id for which the name should be determined.
      *        If the id is invalid, the return value is unspecified.
      * @returns The name of the determined enumeration value.
      */
     virtual std::string GetEnumString(const IdType &id) const;
 
     /**
      * Returns the id for the given name.
      * @param name The enumeration name for which the id should be determined.
      *        If the name is invalid, the return value is unspecified.
      * @returns The id of the determined enumeration value.
      */
     virtual IdType GetEnumId(const std::string &name) const;
 
     /**
      * Determines if a given id is valid.
      * @param id The id to check
      * @returns True if the given id is valid. Otherwise false.
      */
     virtual bool IsValidEnumerationValue(const IdType &id) const;
 
     /**
      * Determines if a given name is valid.
      * @param name The name to check
      * @returns True if the given name is valid. Otherwise false.
      */
     virtual bool IsValidEnumerationValue(const std::string &name) const;
 
     const EnumIdsContainerType &GetEnumIds() const;
     const EnumStringsContainerType &GetEnumStrings() const;
 
     EnumIdsContainerType &GetEnumIds();
     EnumStringsContainerType &GetEnumStrings();
 
-    void ToJSON(nlohmann::json& j) const override;
-    void FromJSON(const nlohmann::json& j) override;
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
 
     using BaseProperty::operator=;
     EnumerationProperty & operator=(const EnumerationProperty &) = delete;
 
   protected:
     /**
      * Default constructor. The current value of the enumeration is undefined.
      */
     EnumerationProperty();
 
     EnumerationProperty(const EnumerationProperty &);
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
 
     mitkCloneMacro(Self);
 
   private:
     IdType m_CurrentValue;
     EnumIdsContainerType m_IdMap;
     EnumStringsContainerType m_NameMap;
   };
 }
 
 #ifdef _MSC_VER
 #  pragma warning(pop)
 #endif
 
 #endif
diff --git a/Modules/Core/include/mitkGenericProperty.h b/Modules/Core/include/mitkGenericProperty.h
index dad7c897da..1f2cecc561 100644
--- a/Modules/Core/include/mitkGenericProperty.h
+++ b/Modules/Core/include/mitkGenericProperty.h
@@ -1,152 +1,154 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkGenericProperty_h
 #define mitkGenericProperty_h
 
 #include <sstream>
 #include <cstdlib>
 #include <string>
 
 #include "mitkBaseProperty.h"
 #include "mitkNumericTypes.h"
 #include <MitkCoreExports.h>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /*!
     @ brief Template class for generating properties for int, float, bool, etc.
 
     This class template can be instantiated for all classes/internal types that fulfills
     these requirements:
       - an operator<< so that the properties value can be put into a std::stringstream
       - an operator== so that two properties can be checked for equality
 
     Note: you must use the macro mitkSpecializeGenericProperty to provide specializations
     for concrete types (e.g. BoolProperty). Please see mitkProperties.h for examples. If you
     don't use the mitkSpecializeGenericProperty Macro, GetNameOfClass() returns a wrong name.
 
   */
   template <typename T>
   class MITK_EXPORT GenericProperty : public BaseProperty
   {
   public:
     mitkClassMacro(GenericProperty, BaseProperty);
     mitkNewMacro1Param(GenericProperty<T>, T);
     itkCloneMacro(Self);
 
       typedef T ValueType;
 
     itkSetMacro(Value, T);
     itkGetConstMacro(Value, T);
 
     std::string GetValueAsString() const override
     {
       std::stringstream myStr;
       myStr << GetValue();
       return myStr.str();
     }
 
-    void ToJSON(nlohmann::json& j) const override
+    bool ToJSON(nlohmann::json& j) const override
     {
       j = this->GetValue();
+      return true;
     }
 
-    void FromJSON(const nlohmann::json& j) override
+    bool FromJSON(const nlohmann::json& j) override
     {
       this->SetValue(j.get<T>());
+      return true;
     }
 
     using BaseProperty::operator=;
 
   protected:
     GenericProperty() {}
     GenericProperty(T x) : m_Value(x) {}
     GenericProperty(const GenericProperty &other) : BaseProperty(other), m_Value(other.m_Value) {}
     T m_Value;
 
   private:
     // purposely not implemented
     GenericProperty &operator=(const GenericProperty &);
 
     itk::LightObject::Pointer InternalClone() const override
     {
       itk::LightObject::Pointer result(new Self(*this));
       result->UnRegister();
       return result;
     }
 
     bool IsEqual(const BaseProperty &other) const override
     {
       return (this->m_Value == static_cast<const Self &>(other).m_Value);
     }
 
     bool Assign(const BaseProperty &other) override
     {
       this->m_Value = static_cast<const Self &>(other).m_Value;
       return true;
     }
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 /**
  * Generates a specialized subclass of mitk::GenericProperty.
  * This way, GetNameOfClass() returns the value provided by PropertyName.
  * Please see mitkProperties.h for examples.
  * @param PropertyName the name of the subclass of GenericProperty
  * @param Type the value type of the GenericProperty
  * @param Export the export macro for DLL usage
  */
 #define mitkDeclareGenericProperty(PropertyName, Type, Export)                                                         \
                                                                                                                        \
   class Export PropertyName : public GenericProperty<Type>                                                             \
                                                                                                                        \
   {                                                                                                                    \
   public:                                                                                                              \
     mitkClassMacro(PropertyName, GenericProperty<Type>);                                                               \
     itkFactorylessNewMacro(Self);                                                                                      \
     itkCloneMacro(Self);                                                                                               \
     mitkNewMacro1Param(PropertyName, Type);                                                                            \
                                                                                                                        \
     using BaseProperty::operator=;                                                                                     \
                                                                                                                        \
   protected:                                                                                                           \
     PropertyName();                                                                                                    \
     PropertyName(const PropertyName &);                                                                                \
     PropertyName(Type x);                                                                                              \
                                                                                                                        \
   private:                                                                                                             \
     itk::LightObject::Pointer InternalClone() const override;                                                          \
   };
 
 #define mitkDefineGenericProperty(PropertyName, Type, DefaultValue)                                                    \
   mitk::PropertyName::PropertyName() : Superclass(DefaultValue) {}                                                     \
   mitk::PropertyName::PropertyName(const PropertyName &other) : GenericProperty<Type>(other) {}                        \
   mitk::PropertyName::PropertyName(Type x) : Superclass(x) {}                                                          \
   itk::LightObject::Pointer mitk::PropertyName::InternalClone() const                                                  \
   {                                                                                                                    \
     itk::LightObject::Pointer result(new Self(*this));                                                                 \
     result->UnRegister();                                                                                              \
     return result;                                                                                                     \
   }
 
 #endif
diff --git a/Modules/Core/include/mitkGroupTagProperty.h b/Modules/Core/include/mitkGroupTagProperty.h
index e83ff9b0e5..9d17596bc1 100644
--- a/Modules/Core/include/mitkGroupTagProperty.h
+++ b/Modules/Core/include/mitkGroupTagProperty.h
@@ -1,62 +1,65 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkGroupTagProperty_h
 #define mitkGroupTagProperty_h
 
 #include <mitkBaseProperty.h>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /*! @brief Property class that has no value.
 
     @ingroup DataManagement
 
       The GroupTag property is used to tag a datatree node to show, that it is member of a
       group of datatree nodes. This can be used to build groups of datatreenodes without the
       need to contain them in a specific hiearchic order in the datatree
   */
   class MITKCORE_EXPORT GroupTagProperty : public BaseProperty
   {
   public:
     mitkClassMacro(GroupTagProperty, BaseProperty);
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self);
 
-      using BaseProperty::operator=;
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
+    using BaseProperty::operator=;
 
   protected:
     GroupTagProperty();
     GroupTagProperty(const GroupTagProperty &);
 
   private:
     // purposely not implemented
     GroupTagProperty &operator=(const GroupTagProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkLevelWindow.h b/Modules/Core/include/mitkLevelWindow.h
index f81f33c200..3b0c2006ad 100644
--- a/Modules/Core/include/mitkLevelWindow.h
+++ b/Modules/Core/include/mitkLevelWindow.h
@@ -1,263 +1,268 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 #ifndef mitkLevelWindow_h
 #define mitkLevelWindow_h
 
 #include "mitkNumericTypes.h"
 #include <MitkCoreExports.h>
+#include <nlohmann/json_fwd.hpp>
 
 namespace mitk
 {
   class Image;
 
   /**
   * @brief The LevelWindow class Class to store level/window values.
   *
   * Current min and max value are stored in m_LowerWindowBound and m_UpperWindowBound.
   * m_DefaultLevel amd m_DefaultWindow store the initial Level/Window values for the image.
   * m_DefaultRangeMin and m_DefaultRangeMax store the initial minrange and maxrange for the image.
   *
   * The finite maximum and minimum of valid value range is stored in m_RangeMin and m_RangeMax.
   * If deduced from an image by default the minimum or maximum of it statistics is used. If one
   * of these values are infinite the 2nd extrimum (which is guaranteed to be finite), will be used.
   *
   * See documentation of SetAuto for information on how the level window is initialized from an image.
   *
   * @ingroup DataManagement
   *
   * @note If you want to apply the mitk::LevelWindow to an mitk::Image, make sure
   * to use the mitk::LevelWindowProperty and set the mitk::RenderingModeProperty
   * to a mode which supports level window (e.g. LEVELWINDOW_COLOR).
   * Make sure to check the documentation of the mitk::RenderingModeProperty. For a
   * code example how to use the mitk::LevelWindowProperty check the
   * mitkImageVtkMapper2DLevelWindowTest.cpp in Core/Code/Testing.
   */
   class MITKCORE_EXPORT LevelWindow
   {
   public:
     LevelWindow(ScalarType level = 127.5, ScalarType window = 255.0);
     LevelWindow(const mitk::LevelWindow &levWin);
     virtual ~LevelWindow();
 
     /*!
     * \brief method that returns the level value, i.e. the center of
     * the current grey value interval
     */
     ScalarType GetLevel() const;
 
     /*!
     * \brief returns the current window size, i.e the range size of the current grey value interval
     */
     ScalarType GetWindow() const;
 
     /*!
     * \brief method returns the default level value for the image
     */
     ScalarType GetDefaultLevel() const;
 
     /*!
     * \brief returns the default window size for the image
     */
     ScalarType GetDefaultWindow() const;
 
     /*!
     * \brief Resets the level and the window value to the default values
     */
     void ResetDefaultLevelWindow();
 
     /*!
     * Returns the minimum Value of the window
     */
     ScalarType GetLowerWindowBound() const;
 
     /*!
     * Returns the upper window bound value of the window
     */
     ScalarType GetUpperWindowBound() const;
 
     /*!
     * To set the level and the window value
     */
     void SetLevelWindow(ScalarType level, ScalarType window, bool expandRangesIfNecessary = true);
 
     /*!
     * Set the lower and upper bound of the window, restricted to the range from -10^300 to 10^300. Higher/lower values are clamped to these boundaries.
     */
     void SetWindowBounds(ScalarType lowerBound, ScalarType upperBound, bool expandRangesIfNecessary = true);
 
     /*!
     * sets the window to its maximum Size in scaleRange
     */
     void SetToMaxWindowSize();
 
     /*!
     * Set the range minimum and maximum value
     */
     void SetRangeMinMax(ScalarType min, ScalarType max);
 
     /*!
     * Get the range minimum value
     */
     ScalarType GetRangeMin() const;
 
     /*!
     * Get the range maximum value
     */
     ScalarType GetRangeMax() const;
 
     /*!
     * Get the default range minimum value
     */
     ScalarType GetDefaultLowerBound() const;
 
     /*!
     * Get the default range maximum value
     */
     ScalarType GetDefaultUpperBound() const;
 
     /*!
     * \brief the default min and max range for image will be reset
     */
     void ResetDefaultRangeMinMax();
 
     /**!
     * \brief returns the size of the grey value range
     */
     ScalarType GetRange() const;
 
     /*!
     * set the default level and window value
     */
     void SetDefaultLevelWindow(ScalarType level, ScalarType window);
 
     /*!
     * set the default Boundaries
     */
     void SetDefaultBoundaries(ScalarType low, ScalarType up);
 
     /**!
     * \brief sets level/window to optimize the contrast of the given Image
     */
     void SetAuto(const Image *image,
                  bool tryPicTags = true,
                  bool guessByCentralSlice = true,
                  unsigned selectedComponent = 0);
 
     /**!
     * \brief sets level/window to the min/max greyvalues of the given Image
     */
     void SetToImageRange(const Image *image);
 
     /**
     * If a level window is set to fixed, the set and get methods won't accept
     * modifications to the level window settings anymore. This behaviour can
     * be turned of by setting fixed to false;
     */
     void SetFixed(bool fixed);
 
     /**
     * Returns whether the level window settings are fixed (@see SetFixed(bool)) or not
     */
     bool GetFixed() const;
 
     /**
     * Returns whether the level window settings are fixed (@see SetFixed(bool)) or not
     */
     bool IsFixed() const;
 
     /*!
     * \brief equality operator implementation that allows to compare two level windows
     */
     virtual bool operator==(const LevelWindow &levWin) const;
 
     /*!
     * \brief non equality operator implementation that allows to compare two level windows
     */
     virtual bool operator!=(const LevelWindow &levWin) const;
 
     /*!
     * \brief implementation necessary because operator made
     *  private in itk::Object
     */
     virtual LevelWindow &operator=(const LevelWindow &levWin);
 
     /*!
     * \brief Shows if floating values are accepted
     */
     bool IsFloatingValues() const;
 
     /*!
     * \brief Sets the floating image value
     */
     void SetFloatingValues(bool value);
 
   protected:
     /*!
     * lower bound of current window
     */
     ScalarType m_LowerWindowBound;
 
     /*!
     * upper bound of current window
     */
     ScalarType m_UpperWindowBound;
 
     /*!
     * minimum gray value of the window
     */
     ScalarType m_RangeMin;
 
     /*!
     * maximum gray value of the window
     */
     ScalarType m_RangeMax;
 
     /*!
     * default minimum gray value of the window
     */
     ScalarType m_DefaultLowerBound;
 
     /*!
     * default maximum gray value of the window
     */
     ScalarType m_DefaultUpperBound;
 
     /*!
     * Image with floating values
     */
     bool m_IsFloatingImage;
 
     /*!
     * Defines whether the level window settings may be changed after
     * initialization or not.
     */
     bool m_Fixed;
 
     /*!
     * confidence tests
     *
     * if m_LowerWindowBound > m_UpperWindowBound, then the values for m_LowerWindowBound and m_UpperWindowBound will be
     * exchanged
     *
     * if m_LowerWindowBound < m_RangeMin, m_LowerWindowBound will be set to m_RangeMin. m_UpperWindowBound will be
     * decreased the same as m_LowerWindowBound will be increased, but minimum value for m_UpperWindowBound is also
     * m_RangeMin.
     *
     * if m_UpperWindowBound > m_RangeMax, m_UpperWindowBound will be set to m_RangeMax. m_LowerWindowBound will be
     * increased the same as m_UpperWindowBound will be decreased, but maximum value for m_LowerWindowBound is also
     * m_RangeMax.
     *
     */
     inline void EnsureConsistency();
   };
+
+  MITKCORE_EXPORT void to_json(nlohmann::json& j, const LevelWindow& lw);
+  MITKCORE_EXPORT void from_json(const nlohmann::json& j, LevelWindow& lw);
+
 } // namespace mitk
 #endif
diff --git a/Modules/Core/include/mitkLevelWindowProperty.h b/Modules/Core/include/mitkLevelWindowProperty.h
index 4c4325de22..30209a6f26 100755
--- a/Modules/Core/include/mitkLevelWindowProperty.h
+++ b/Modules/Core/include/mitkLevelWindowProperty.h
@@ -1,85 +1,88 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 #ifndef mitkLevelWindowProperty_h
 #define mitkLevelWindowProperty_h
 
 #include "mitkBaseProperty.h"
 #include "mitkLevelWindow.h"
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /**
    * @brief The LevelWindowProperty class Property for the mitk::LevelWindow
    *
    * @ingroup DataManagement
    *
    * @note If you want to apply the mitk::LevelWindowProperty to an mitk::Image,
    * make sure to set the mitk::RenderingModeProperty to a mode which supports
    * level window (e.g. LEVELWINDOW_COLOR). Make sure to check the documentation
    * of the mitk::RenderingModeProperty. For a code example how to use the
    * mitk::LevelWindowProperty check the mitkImageVtkMapper2DLevelWindowTest.cpp
    * in Core/Code/Testing.
    */
   class MITKCORE_EXPORT LevelWindowProperty : public BaseProperty
   {
   protected:
     LevelWindow m_LevWin;
 
     LevelWindowProperty();
 
     LevelWindowProperty(const LevelWindowProperty &other);
 
     LevelWindowProperty(const mitk::LevelWindow &levWin);
 
   public:
     mitkClassMacro(LevelWindowProperty, BaseProperty);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self) mitkNewMacro1Param(LevelWindowProperty, const mitk::LevelWindow &);
 
     typedef LevelWindow ValueType;
 
     ~LevelWindowProperty() override;
 
     const mitk::LevelWindow &GetLevelWindow() const;
     const mitk::LevelWindow &GetValue() const;
 
     void SetLevelWindow(const LevelWindow &levWin);
     void SetValue(const ValueType &levWin);
 
     std::string GetValueAsString() const override;
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     using BaseProperty::operator=;
 
   private:
     // purposely not implemented
     LevelWindowProperty &operator=(const LevelWindowProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkLookupTableProperty.h b/Modules/Core/include/mitkLookupTableProperty.h
index f753b288b3..3b72837858 100644
--- a/Modules/Core/include/mitkLookupTableProperty.h
+++ b/Modules/Core/include/mitkLookupTableProperty.h
@@ -1,87 +1,87 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 #ifndef mitkLookupTableProperty_h
 #define mitkLookupTableProperty_h
 
 #include "mitkBaseProperty.h"
 #include "mitkLookupTable.h"
 #include <MitkCoreExports.h>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /**
    * @brief The LookupTableProperty class Property to associate mitk::LookupTable
    * to an mitk::DataNode.
    * @ingroup DataManagement
    *
    * @note If you want to use this property to colorize an mitk::Image, make sure
    * to set the mitk::RenderingModeProperty to a mode which supports lookup tables
    * (e.g. LOOKUPTABLE_COLOR). Make sure to check the documentation of the
    * mitk::RenderingModeProperty. For a code example how to use the mitk::LookupTable
    * and this property check the mitkImageVtkMapper2DLookupTableTest.cpp in
    * Core/Code/Testing.
    */
   class MITKCORE_EXPORT LookupTableProperty : public BaseProperty
   {
   protected:
     LookupTable::Pointer m_LookupTable;
 
     LookupTableProperty();
 
     LookupTableProperty(const LookupTableProperty &);
 
     LookupTableProperty(const mitk::LookupTable::Pointer lut);
 
   public:
     typedef LookupTable::Pointer ValueType;
 
     mitkClassMacro(LookupTableProperty, BaseProperty);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self)
       mitkNewMacro1Param(LookupTableProperty, const mitk::LookupTable::Pointer);
 
     itkGetObjectMacro(LookupTable, LookupTable);
     ValueType GetValue() const;
 
     void SetLookupTable(const mitk::LookupTable::Pointer aLookupTable);
     void SetValue(const ValueType &);
 
     std::string GetValueAsString() const override;
 
-    void ToJSON(nlohmann::json& j) const override;
-    void FromJSON(const nlohmann::json& j) override;
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
 
     using BaseProperty::operator=;
 
   private:
     // purposely not implemented
     LookupTableProperty &operator=(const LookupTableProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkPoint.h b/Modules/Core/include/mitkPoint.h
index f8844cbae8..0f9c36682b 100644
--- a/Modules/Core/include/mitkPoint.h
+++ b/Modules/Core/include/mitkPoint.h
@@ -1,153 +1,153 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkPoint_h
 #define mitkPoint_h
 
 #include <itkPoint.h>
 
 #include <mitkArray.h>
 #include <mitkEqual.h>
 #include <mitkNumericConstants.h>
 
 #include <nlohmann/json.hpp>
 
 namespace mitk
 {
   //##Documentation
   //##@brief enumeration of the type a point can be
   enum PointSpecificationType
   {
     PTUNDEFINED = 0,
     PTSTART,
     PTCORNER,
     PTEDGE,
     PTEND
   };
 
   template <class TCoordRep, unsigned int NPointDimension = 3>
   class Point : public itk::Point<TCoordRep, NPointDimension>
   {
   public:
     /** Default constructor has nothing to do. */
     explicit Point<TCoordRep, NPointDimension>() : itk::Point<TCoordRep, NPointDimension>() {}
     /** Pass-through constructors for the Array base class. */
     template <typename TPointValueType>
     explicit Point(const Point<TPointValueType, NPointDimension> &r) : itk::Point<TCoordRep, NPointDimension>(r)
     {
     }
 
     template <typename TPointValueType>
     explicit Point(const TPointValueType r[NPointDimension]) : itk::Point<TCoordRep, NPointDimension>(r)
     {
     }
 
     template <typename TPointValueType>
     explicit Point(const TPointValueType &v) : itk::Point<TCoordRep, NPointDimension>(v)
     {
     }
 
     Point<TCoordRep, NPointDimension>(const mitk::Point<TCoordRep, NPointDimension> &r)
       : itk::Point<TCoordRep, NPointDimension>(r)
     {
     }
     Point<TCoordRep, NPointDimension>(const TCoordRep r[NPointDimension]) : itk::Point<TCoordRep, NPointDimension>(r) {}
     Point<TCoordRep, NPointDimension>(const TCoordRep &v) : itk::Point<TCoordRep, NPointDimension>(v) {}
     Point<TCoordRep, NPointDimension>(const itk::Point<TCoordRep, NPointDimension> &p)
       : itk::Point<TCoordRep, NPointDimension>(p)
     {
     }
 
     /**
      * Copies the elements from array array to this.
      * Note that this method will assign doubles to floats without complaining!
      *
      * @param array the array whose values shall be copied. Must overload [] operator.
      */
     template <typename ArrayType>
     void FillPoint(const ArrayType &array)
     {
       itk::FixedArray<TCoordRep, NPointDimension> *thisP =
         dynamic_cast<itk::FixedArray<TCoordRep, NPointDimension> *>(this);
       mitk::FillArray<ArrayType, TCoordRep, NPointDimension>(*thisP, array);
     }
 
     /**
      * Copies the values stored in this point into the array array.
      *
      * @param array the array which should store the values of this.
      */
     template <typename ArrayType>
     void ToArray(ArrayType array) const
     {
       mitk::ToArray<ArrayType, TCoordRep, NPointDimension>(array, *this);
     }
   };
 
   template <class TCoordRep, unsigned int NPointDimension>
   void to_json(nlohmann::json& j, const Point<TCoordRep, NPointDimension>& p)
   {
     j = nlohmann::json::array();
 
     for (size_t i = 0; i < NPointDimension; ++i)
       j.push_back(p[i]);
   }
 
   template <class TCoordRep, unsigned int NPointDimension>
   void from_json(const nlohmann::json& j, Point<TCoordRep, NPointDimension>& p)
   {
     for (size_t i = 0; i < NPointDimension; ++i)
-      p[i] = j.at(i).get<TCoordRep>();
+      j.at(i).get_to(p[i]);
   }
 
   typedef Point<ScalarType, 2> Point2D;
   typedef Point<ScalarType, 3> Point3D;
   typedef Point<ScalarType, 4> Point4D;
 
   typedef Point<int, 2> Point2I;
   typedef Point<int, 3> Point3I;
   typedef Point<int, 4> Point4I;
 
   /**
    * @ingroup MITKTestingAPI
    *
    * @param point1 Point to compare.
    * @param point2 Point to compare.
    * @param eps Tolerance for floating point comparison.
    * @param verbose Flag indicating detailed console output.
    * @return True if points are equal.
    */
   template <typename TCoordRep, unsigned int NPointDimension>
   inline bool Equal(const itk::Point<TCoordRep, NPointDimension> &point1,
                     const itk::Point<TCoordRep, NPointDimension> &point2,
                     TCoordRep eps = mitk::eps,
                     bool verbose = false)
   {
     bool isEqual = true;
     typename itk::Point<TCoordRep, NPointDimension>::VectorType diff = point1 - point2;
     for (unsigned int i = 0; i < NPointDimension; i++)
     {
       if (DifferenceBiggerOrEqualEps(diff[i], eps))
       {
         isEqual = false;
         break;
       }
     }
 
     ConditionalOutputOfDifference(point1, point2, eps, verbose, isEqual);
 
     return isEqual;
   }
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkSmartPointerProperty.h b/Modules/Core/include/mitkSmartPointerProperty.h
index aac5f37d69..ddf84f66b3 100644
--- a/Modules/Core/include/mitkSmartPointerProperty.h
+++ b/Modules/Core/include/mitkSmartPointerProperty.h
@@ -1,98 +1,101 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkSmartPointerProperty_h
 #define mitkSmartPointerProperty_h
 
 #include "mitkBaseProperty.h"
 #include "mitkUIDGenerator.h"
 #include <MitkCoreExports.h>
 
 #include <list>
 #include <map>
 #include <string>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   //##Documentation
   //## @brief Property containing a smart-pointer
   //## @ingroup DataManagement
   class MITKCORE_EXPORT SmartPointerProperty : public BaseProperty
   {
   public:
     mitkClassMacro(SmartPointerProperty, BaseProperty);
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self);
     mitkNewMacro1Param(SmartPointerProperty, itk::Object*);
 
     typedef itk::Object::Pointer ValueType;
 
     itk::Object::Pointer GetSmartPointer() const;
     ValueType GetValue() const;
 
     void SetSmartPointer(itk::Object *);
     void SetValue(const ValueType &);
 
     /// mainly for XML output
     std::string GetValueAsString() const override;
 
     static void PostProcessXMLReading();
 
     /// Return the number of SmartPointerProperties that reference the object given as parameter
     static unsigned int GetReferenceCountFor(itk::Object *);
     static std::string GetReferenceUIDFor(itk::Object *);
     static void RegisterPointerTarget(itk::Object *, const std::string uid);
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     using BaseProperty::operator=;
 
   protected:
     SmartPointerProperty(itk::Object * = nullptr);
     SmartPointerProperty(const SmartPointerProperty &);
 
     itk::Object::Pointer m_SmartPointer;
 
   private:
     // purposely not implemented
     SmartPointerProperty &operator=(const SmartPointerProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &) const override;
     bool Assign(const BaseProperty &) override;
 
     typedef std::map<itk::Object *, unsigned int> ReferenceCountMapType;
     typedef std::map<itk::Object *, std::string> ReferencesUIDMapType;
     typedef std::map<SmartPointerProperty *, std::string> ReadInSmartPointersMapType;
     typedef std::map<std::string, itk::Object *> ReadInTargetsMapType;
 
     /// for each itk::Object* count how many SmartPointerProperties point to it
     static ReferenceCountMapType m_ReferenceCount;
     static ReferencesUIDMapType m_ReferencesUID;
     static ReadInSmartPointersMapType m_ReadInInstances;
     static ReadInTargetsMapType m_ReadInTargets;
 
     /// to generate unique IDs for the objects pointed at (during XML writing)
     static UIDGenerator m_UIDGenerator;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkStringProperty.h b/Modules/Core/include/mitkStringProperty.h
index 574e426d70..41962df4e1 100644
--- a/Modules/Core/include/mitkStringProperty.h
+++ b/Modules/Core/include/mitkStringProperty.h
@@ -1,81 +1,81 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkStringProperty_h
 #define mitkStringProperty_h
 
 #include <itkConfigure.h>
 
 #include "mitkBaseProperty.h"
 #include <MitkCoreExports.h>
 
 #include <string>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /**
    * @brief Property for strings
    * @ingroup DataManagement
    */
   class MITKCORE_EXPORT StringProperty : public BaseProperty
   {
   protected:
     std::string m_Value;
 
     StringProperty(const char *string = nullptr);
     StringProperty(const std::string &s);
 
     StringProperty(const StringProperty &);
 
   public:
     mitkClassMacro(StringProperty, BaseProperty);
     typedef std::string ValueType;
 
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self);
     mitkNewMacro1Param(StringProperty, const char*);
     mitkNewMacro1Param(StringProperty, const std::string&);
 
     itkGetStringMacro(Value);
     itkSetStringMacro(Value);
 
     std::string GetValueAsString() const override;
 
-    void ToJSON(nlohmann::json& j) const override;
-    void FromJSON(const nlohmann::json& j) override;
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
 
     static const char *PATH;
 
     using BaseProperty::operator=;
 
   private:
     // purposely not implemented
     StringProperty &operator=(const StringProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkTemporoSpatialStringProperty.h b/Modules/Core/include/mitkTemporoSpatialStringProperty.h
index 595c8d1aca..8f6f090f93 100644
--- a/Modules/Core/include/mitkTemporoSpatialStringProperty.h
+++ b/Modules/Core/include/mitkTemporoSpatialStringProperty.h
@@ -1,136 +1,139 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkTemporoSpatialStringProperty_h
 #define mitkTemporoSpatialStringProperty_h
 
 #include <itkConfigure.h>
 
 #include "mitkBaseProperty.h"
 #include <MitkCoreExports.h>
 
 #include "mitkTimeGeometry.h"
 
 #include <string>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /**
    * @brief Property for time and space resolved string values
    * @ingroup DataManagement
    */
   class MITKCORE_EXPORT TemporoSpatialStringProperty : public BaseProperty
   {
   public:
     typedef ::itk::IndexValueType IndexValueType;
     typedef std::string ValueType;
 
     mitkClassMacro(TemporoSpatialStringProperty, BaseProperty);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self);
     mitkNewMacro1Param(TemporoSpatialStringProperty, const char*);
     mitkNewMacro1Param(TemporoSpatialStringProperty, const std::string &);
 
     /**Returns the value of the first time point in the first slice.
      * If now value is set it returns an empty string.*/
     ValueType GetValue() const;
     /**Returns the value of the passed time step and slice. If it does not exist and allowedClosed is true
      * it will look for the closest value. If nothing could be found an empty string will be returned.*/
     ValueType GetValue(const TimeStepType &timeStep,
                        const IndexValueType &zSlice,
                        bool allowCloseTime = false,
                        bool allowCloseSlice = false) const;
     ValueType GetValueBySlice(const IndexValueType &zSlice, bool allowClose = false) const;
     ValueType GetValueByTimeStep(const TimeStepType &timeStep, bool allowClose = false) const;
 
     bool HasValue() const;
     bool HasValue(const TimeStepType &timeStep,
                   const IndexValueType &zSlice,
                   bool allowCloseTime = false,
                   bool allowCloseSlice = false) const;
     bool HasValueBySlice(const IndexValueType &zSlice, bool allowClose = false) const;
     bool HasValueByTimeStep(const TimeStepType &timeStep, bool allowClose = false) const;
 
     /** return all slices stored for the specified timestep.*/
     std::vector<IndexValueType> GetAvailableSlices(const TimeStepType& timeStep) const;
     /** return all time steps stored for the specified slice.*/
     std::vector<TimeStepType> GetAvailableTimeSteps(const IndexValueType& slice) const;
     /** return all time steps stored in the property.*/
     std::vector<TimeStepType> GetAvailableTimeSteps() const;
     /** return all slices stored in the property. @remark not all time steps may contain all slices.*/
     std::vector<IndexValueType> GetAvailableSlices() const;
 
     void SetValue(const TimeStepType &timeStep, const IndexValueType &zSlice, const ValueType &value);
 
     void SetValue(const ValueType &value);
 
     std::string GetValueAsString() const override;
 
     /** Indicates of all values (all time steps, all slices) are the same, or if at least one value stored
     in the property is different. If IsUniform==true one can i.a. use GetValueAsString() without the loss of
     information to retrieve the stored value.*/
     bool IsUniform() const;
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     using BaseProperty::operator=;
 
   protected:
     typedef std::map<IndexValueType, std::string> SliceMapType;
     typedef std::map<TimeStepType, SliceMapType> TimeMapType;
 
     TimeMapType m_Values;
 
     TemporoSpatialStringProperty(const char *string = nullptr);
     TemporoSpatialStringProperty(const std::string &s);
 
     TemporoSpatialStringProperty(const TemporoSpatialStringProperty &);
 
     std::pair<bool, ValueType> CheckValue(const TimeStepType &timeStep,
                                           const IndexValueType &zSlice,
                                           bool allowCloseTime = false,
                                           bool allowCloseSlice = false) const;
 
   private:
     // purposely not implemented
     TemporoSpatialStringProperty &operator=(const TemporoSpatialStringProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
   namespace PropertyPersistenceSerialization
   {
     /** Serialization of a TemporoSpatialStringProperty into a JSON string.*/
-    MITKCORE_EXPORT::std::string serializeTemporoSpatialStringPropertyToJSON(const mitk::BaseProperty *prop);
+    MITKCORE_EXPORT std::string serializeTemporoSpatialStringPropertyToJSON(const mitk::BaseProperty *prop);
   }
 
   namespace PropertyPersistenceDeserialization
   {
     /**Deserialize a passed JSON string into a TemporoSpatialStringProperty.*/
     MITKCORE_EXPORT mitk::BaseProperty::Pointer deserializeJSONToTemporoSpatialStringProperty(const std::string &value);
   }
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkTransferFunctionProperty.h b/Modules/Core/include/mitkTransferFunctionProperty.h
index e8bf9439cc..fd3c20d736 100644
--- a/Modules/Core/include/mitkTransferFunctionProperty.h
+++ b/Modules/Core/include/mitkTransferFunctionProperty.h
@@ -1,79 +1,82 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 #ifndef mitkTransferFunctionProperty_h
 #define mitkTransferFunctionProperty_h
 
 #include "mitkBaseProperty.h"
 #include "mitkTransferFunction.h"
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   /**
    * @brief The TransferFunctionProperty class Property class for the mitk::TransferFunction.
    * @ingroup DataManagement
    *
    * @note If you want to use this property for an mitk::Image, make sure
    * to set the mitk::RenderingModeProperty to a mode which supports transfer
    * functions (e.g. COLORTRANSFERFUNCTION_COLOR). Make sure to check the
    * documentation of the mitk::RenderingModeProperty. For a code example how
    * to use the mitk::TransferFunction check the
    * mitkImageVtkMapper2DTransferFunctionTest.cpp in Core/Code/Testing.
    */
   class MITKCORE_EXPORT TransferFunctionProperty : public BaseProperty
   {
   public:
     typedef mitk::TransferFunction::Pointer ValueType;
 
     mitkClassMacro(TransferFunctionProperty, BaseProperty);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self)
       mitkNewMacro1Param(TransferFunctionProperty, mitk::TransferFunction::Pointer);
 
     itkSetMacro(Value, mitk::TransferFunction::Pointer);
     itkGetConstMacro(Value, mitk::TransferFunction::Pointer);
 
     std::string GetValueAsString() const override;
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     using BaseProperty::operator=;
 
   protected:
     mitk::TransferFunction::Pointer m_Value;
 
     TransferFunctionProperty();
     TransferFunctionProperty(const TransferFunctionProperty &other);
 
     TransferFunctionProperty(mitk::TransferFunction::Pointer value);
 
   private:
     // purposely not implemented
     TransferFunctionProperty &operator=(const TransferFunctionProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkVector.h b/Modules/Core/include/mitkVector.h
index ac111e18ee..6c5bc2ddaf 100644
--- a/Modules/Core/include/mitkVector.h
+++ b/Modules/Core/include/mitkVector.h
@@ -1,257 +1,257 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkVector_h
 #define mitkVector_h
 
 #include <itkVector.h>
 #include <vnl/vnl_vector.h>
 #include <vnl/vnl_vector_fixed.h>
 
 #include <mitkArray.h>
 #include <mitkEqual.h>
 #include <mitkExceptionMacro.h>
 #include <mitkNumericConstants.h>
 
 #include <nlohmann/json.hpp>
 
 namespace mitk
 {
   template <class TCoordRep, unsigned int NVectorDimension = 3>
   class Vector : public itk::Vector<TCoordRep, NVectorDimension>
   {
   public:
     /**
      * @brief Default constructor has nothing to do.
      */
     explicit Vector<TCoordRep, NVectorDimension>() : itk::Vector<TCoordRep, NVectorDimension>() {}
     /**
      * @brief Copy constructor.
      */
     explicit Vector<TCoordRep, NVectorDimension>(const mitk::Vector<TCoordRep, NVectorDimension> &r)
       : itk::Vector<TCoordRep, NVectorDimension>(r)
     {
     }
 
     /** Pass-through assignment operator for the Vector base class. */
     Vector<TCoordRep, NVectorDimension> & operator=(const Vector<TCoordRep, NVectorDimension> & r)
     {
       itk::Vector<TCoordRep, NVectorDimension>::operator=(r);
       return *this;
     }
 
     /**
      * @brief Constructor to convert from itk::Vector to mitk::Vector.
      */
     Vector<TCoordRep, NVectorDimension>(const itk::Vector<TCoordRep, NVectorDimension> &r)
       : itk::Vector<TCoordRep, NVectorDimension>(r)
     {
     }
 
     /**
      * @brief Constructor to convert an array to mitk::Vector
      * @param r the array.
      * @attention must have NVectorDimension valid arguments!
      */
     Vector<TCoordRep, NVectorDimension>(const TCoordRep r[NVectorDimension])
       : itk::Vector<TCoordRep, NVectorDimension>(r)
     {
     }
 
     /**
      * Constructor to initialize entire vector to one value.
      */
     Vector<TCoordRep, NVectorDimension>(const TCoordRep &v) : itk::Vector<TCoordRep, NVectorDimension>(v) {}
     /**
      * @brief Constructor for vnl_vectors.
      * @throws mitk::Exception if vnl_vector.size() != NVectorDimension.
      */
     Vector<TCoordRep, NVectorDimension>(const vnl_vector<TCoordRep> &vnlVector)
       : itk::Vector<TCoordRep, NVectorDimension>()
     {
       if (vnlVector.size() != NVectorDimension)
         mitkThrow() << "when constructing mitk::Vector from vnl_vector: sizes didn't match: mitk::Vector "
                     << NVectorDimension << "; vnl_vector " << vnlVector.size();
 
       for (unsigned int var = 0; (var < NVectorDimension) && (var < vnlVector.size()); ++var)
       {
         this->SetElement(var, vnlVector.get(var));
       }
     }
 
     /**
      * @brief Constructor for vnl_vector_fixed.
      */
     Vector<TCoordRep, NVectorDimension>(const vnl_vector_fixed<TCoordRep, NVectorDimension> &vnlVectorFixed)
       : itk::Vector<TCoordRep, NVectorDimension>()
     {
       for (unsigned int var = 0; var < NVectorDimension; ++var)
       {
         this->SetElement(var, vnlVectorFixed[var]);
       }
     };
 
     /**
      * Copies the elements from array array to this.
      * Note that this method will assign doubles to floats without complaining!
      *
      * @param array the array whose values shall be copied. Must overload [] operator.
      */
     template <typename ArrayType>
     void FillVector(const ArrayType &array)
     {
       itk::FixedArray<TCoordRep, NVectorDimension> *thisP =
         dynamic_cast<itk::FixedArray<TCoordRep, NVectorDimension> *>(this);
       mitk::FillArray<ArrayType, TCoordRep, NVectorDimension>(*thisP, array);
     }
 
     /**
      * Copies the values stored in this vector into the array array.d
      *
      * @param array the array which should store the values of this.
      */
     template <typename ArrayType>
     void ToArray(ArrayType array) const
     {
       mitk::ToArray<ArrayType, TCoordRep, NVectorDimension>(array, *this);
     }
 
     /**
      * @brief User defined conversion of mitk::Vector to vnl_vector.
      * Note: the conversion to mitk::Vector to vnl_vector_fixed has not been implemented since this
      * would collide with the conversion vnl_vector to vnl_vector_fixed provided by vnl.
      */
     operator vnl_vector<TCoordRep>() const { return this->GetVnlVector(); }
   }; // end mitk::Vector
 
   template <class TCoordRep, unsigned int NVectorDimension>
   void to_json(nlohmann::json &j, const Vector<TCoordRep, NVectorDimension> &v)
   {
     j = nlohmann::json::array();
 
     for (size_t i = 0; i < NVectorDimension; ++i)
       j.push_back(v[i]);
   }
 
   template <class TCoordRep, unsigned int NVectorDimension>
   void from_json(const nlohmann::json &j, Vector<TCoordRep, NVectorDimension> &v)
   {
     for (size_t i = 0; i < NVectorDimension; ++i)
-      v[i] = j.at(i).get<TCoordRep>();
+      j.at(i).get_to(v[i]);
   }
 
   // convenience typedefs for often used mitk::Vector representations.
 
   typedef Vector<ScalarType, 2> Vector2D;
   typedef Vector<ScalarType, 3> Vector3D;
   typedef Vector<ScalarType, 4> Vector4D;
 
   // other vector types used in MITK
   typedef vnl_vector<ScalarType> VnlVector;
 
   // The equal methods to compare vectors for equality are below:
 
   /**
    * @ingroup MITKTestingAPI
    *
    * @param vector1 Vector to compare.
    * @param vector2 Vector to compare.
    * @param eps Tolerance for floating point comparison.
    * @param verbose Flag indicating detailed console output.
    * @return True if vectors are equal.
    */
   template <typename TCoordRep, unsigned int NPointDimension>
   inline bool Equal(const itk::Vector<TCoordRep, NPointDimension> &vector1,
                     const itk::Vector<TCoordRep, NPointDimension> &vector2,
                     TCoordRep eps = mitk::eps,
                     bool verbose = false)
   {
     bool isEqual = true;
     typename itk::Vector<TCoordRep, NPointDimension>::VectorType diff = vector1 - vector2;
     for (unsigned int i = 0; i < NPointDimension; i++)
     {
       if (DifferenceBiggerOrEqualEps(diff[i], eps))
       {
         isEqual = false;
         break;
       }
     }
 
     ConditionalOutputOfDifference(vector1, vector2, eps, verbose, isEqual);
 
     return isEqual;
   }
 
   /**
    * @ingroup MITKTestingAPI
    *
    * @param vector1 Vector to compare.
    * @param vector2 Vector to compare.
    * @param eps Tolerance for floating point comparison.
    * @param verbose Flag indicating detailed console output.
    * @return True if vectors are equal.
    */
   inline bool Equal(const mitk::VnlVector &vector1,
                     const mitk::VnlVector &vector2,
                     ScalarType eps = mitk::eps,
                     bool verbose = false)
   {
     bool isEqual = true;
     mitk::VnlVector diff = vector1 - vector2;
     for (unsigned int i = 0; i < diff.size(); i++)
     {
       if (DifferenceBiggerOrEqualEps(diff[i], eps))
       {
         isEqual = false;
         break;
       }
     }
 
     ConditionalOutputOfDifference(vector1, vector2, eps, verbose, isEqual);
 
     return isEqual;
   }
 
   /**
    * @ingroup MITKTestingAPI
    *
    * @param vector1 Vector to compare.
    * @param vector2 Vector to compare.
    * @param eps Tolerance for floating point comparison.
    * @param verbose Flag indicating detailed console output.
    * @return True if vectors are equal.
    */
   template <typename TCoordRep, unsigned int NPointDimension>
   inline bool Equal(const vnl_vector_fixed<TCoordRep, NPointDimension> &vector1,
                     const vnl_vector_fixed<TCoordRep, NPointDimension> &vector2,
                     TCoordRep eps = mitk::eps,
                     bool verbose = false)
   {
     vnl_vector_fixed<TCoordRep, NPointDimension> diff = vector1 - vector2;
     bool isEqual = true;
     for (unsigned int i = 0; i < diff.size(); i++)
     {
       if (DifferenceBiggerOrEqualEps(diff[i], eps))
       {
         isEqual = false;
         break;
       }
     }
 
     ConditionalOutputOfDifference(vector1, vector2, eps, verbose, isEqual);
 
     return isEqual;
   }
 
 } // end namespace mitk
 
 #endif
diff --git a/Modules/Core/include/mitkVectorProperty.h b/Modules/Core/include/mitkVectorProperty.h
index be0b00f767..547a5d5caf 100644
--- a/Modules/Core/include/mitkVectorProperty.h
+++ b/Modules/Core/include/mitkVectorProperty.h
@@ -1,133 +1,136 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkVectorProperty_h
 #define mitkVectorProperty_h
 
 // MITK
 #include <MitkCoreExports.h>
 #include <mitkBaseProperty.h>
 
 // STL
 #include <vector>
 
 namespace mitk
 {
   /**
     \brief Helper for VectorProperty to determine a good ITK ClassName.
 
     This template is specialized for special instantiations that need
     a serializer of this VectorProperty.
   */
   template <typename D>
   struct VectorPropertyDataType
   {
     static const char *prefix() { return "Invalid"; }
   };
 
   /**
     \brief Providing a std::vector as property.
 
     Templated over the data type of the std::vector that is held
     by this class. Nothing special about data handling, setting and
     getting of std::vectors is implemented by-value.
 
     When checking the declaration of this class, you'll notice
     that it does not use the mitkClassMacro but instead writes all
     of its definition manually.
     This is in order to specifically override the GetNameOfClass()
     method without having to inherit again from the template (see
     comments in code).
   */
   template <typename DATATYPE>
   class MITKCORE_EXPORT VectorProperty : public BaseProperty
   {
   public:
     typedef std::vector<DATATYPE> VectorType;
 
     // Manually expand most of mitkClassMacro:
     //   mitkClassMacro(VectorProperty<DATATYPE>, mitk::BaseProperty);
     // This manual expansion is done to override explicitly
     // the GetNameOfClass() and GetStaticNameOfClass() methods
     typedef VectorProperty<DATATYPE> Self;
     typedef BaseProperty SuperClass;
     typedef itk::SmartPointer<Self> Pointer;
     typedef itk::SmartPointer<const Self> ConstPointer;
     std::vector<std::string> GetClassHierarchy() const override { return mitk::GetClassHierarchy<Self>(); }
     /// This function must return different
     /// strings in function of the template parameter!
     /// Serialization depends on this feature.
     static const char *GetStaticNameOfClass()
     {
       // concatenate a prefix dependent on the template type and our own classname
       static std::string nameOfClass = std::string(VectorPropertyDataType<DATATYPE>::prefix()) + "VectorProperty";
       return nameOfClass.c_str();
     }
 
     const char *GetNameOfClass() const override { return this->GetStaticNameOfClass(); }
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self);
 
       /// Returns the property value as a std::string.
       ///
       /// Since VectorProperty potentially holds many
       /// elements, it implements this function in a way
       /// that only the first and the last couple of
       /// elements really appear in the string.
       /// Missing central elements are indicated by
       /// an ellipsis ("...")
       std::string GetValueAsString() const override;
 
     /// returns a const reference to the contained vector
     virtual const VectorType &GetValue() const;
 
     /// sets the content vector
     virtual void SetValue(const VectorType &parameter_vector);
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
   private:
     /// purposely not implemented
     VectorProperty &operator=(const Self &);
 
     /// creates a copy of it self
     itk::LightObject::Pointer InternalClone() const override;
 
     /// compares two properties.
     bool IsEqual(const BaseProperty &an_other_property) const override;
 
     /// assigns the content of an_other_property to this
     bool Assign(const BaseProperty &an_other_property) override;
 
     /// property content
     VectorType m_PropertyContent;
   };
 
 /// This should be used in .h files.
 #define MITK_DECLARE_VECTOR_PROPERTY(TYPE, PREFIX)                                                                     \
                                                                                                                        \
   typedef VectorProperty<TYPE> PREFIX##VectorProperty;                                                                 \
                                                                                                                        \
   template <>                                                                                                          \
                                                                                                                        \
   struct VectorPropertyDataType<TYPE>                                                                                  \
   {                                                                                                                    \
     static const char *prefix() { return #PREFIX; }                                                                    \
   };
 
 /// This should be used in a .cpp file
 #define MITK_DEFINE_VECTOR_PROPERTY(TYPE) template class VectorProperty<TYPE>;
 
   MITK_DECLARE_VECTOR_PROPERTY(double, Double)
   MITK_DECLARE_VECTOR_PROPERTY(int, Int)
 
 } // namespace
 
 #endif
diff --git a/Modules/Core/include/mitkWeakPointerProperty.h b/Modules/Core/include/mitkWeakPointerProperty.h
index aba93c9c37..db11e06a19 100644
--- a/Modules/Core/include/mitkWeakPointerProperty.h
+++ b/Modules/Core/include/mitkWeakPointerProperty.h
@@ -1,78 +1,81 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkWeakPointerProperty_h
 #define mitkWeakPointerProperty_h
 
 #include "itkWeakPointer.h"
 #include "mitkBaseProperty.h"
 #include <MitkCoreExports.h>
 
 namespace mitk
 {
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable : 4522)
 #endif
 
   //##Documentation
   //## @brief Property containing a smart-pointer
   //##
   //## @ingroup DataManagement
   class MITKCORE_EXPORT WeakPointerProperty : public BaseProperty
   {
   public:
     mitkClassMacro(WeakPointerProperty, BaseProperty);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self);
     mitkNewMacro1Param(WeakPointerProperty, itk::Object*);
 
     ~WeakPointerProperty() override;
 
     typedef itk::WeakPointer<itk::Object> ValueType;
 
     ValueType GetWeakPointer() const;
     ValueType GetValue() const;
 
     void SetWeakPointer(itk::Object *pointer);
     void SetValue(const ValueType &value);
 
     std::string GetValueAsString() const override;
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     using BaseProperty::operator=;
 
   protected:
     itk::WeakPointer<itk::Object> m_WeakPointer;
 
     WeakPointerProperty(const WeakPointerProperty &);
 
     WeakPointerProperty(itk::Object *pointer = nullptr);
 
   private:
     // purposely not implemented
     WeakPointerProperty &operator=(const WeakPointerProperty &);
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty &property) const override;
     bool Assign(const BaseProperty &property) override;
   };
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Core/src/DataManagement/mitkAnnotationProperty.cpp b/Modules/Core/src/DataManagement/mitkAnnotationProperty.cpp
index 303e0c80f0..d3463856e3 100644
--- a/Modules/Core/src/DataManagement/mitkAnnotationProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkAnnotationProperty.cpp
@@ -1,98 +1,114 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkAnnotationProperty.h"
 
 mitk::AnnotationProperty::AnnotationProperty() : m_Position(0.0)
 {
 }
 
 mitk::AnnotationProperty::AnnotationProperty(const char *label, const Point3D &position)
   : m_Label(""), m_Position(position)
 {
   if (label != nullptr)
   {
     m_Label = label;
   }
 }
 
 mitk::AnnotationProperty::AnnotationProperty(const std::string &label, const Point3D &position)
   : m_Label(label), m_Position(position)
 {
 }
 
 mitk::AnnotationProperty::AnnotationProperty(const char *label, ScalarType x, ScalarType y, ScalarType z) : m_Label("")
 {
   if (label != nullptr)
   {
     m_Label = label;
   }
 
   m_Position[0] = x;
   m_Position[1] = y;
   m_Position[2] = z;
 }
 
 mitk::AnnotationProperty::AnnotationProperty(const std::string &label, ScalarType x, ScalarType y, ScalarType z)
   : m_Label(label)
 {
   m_Position[0] = x;
   m_Position[1] = y;
   m_Position[2] = z;
 }
 
 mitk::AnnotationProperty::AnnotationProperty(const mitk::AnnotationProperty &other)
   : BaseProperty(other), m_Label(other.m_Label), m_Position(other.m_Position)
 {
 }
 
 const mitk::Point3D &mitk::AnnotationProperty::GetPosition() const
 {
   return m_Position;
 }
 
 void mitk::AnnotationProperty::SetPosition(const mitk::Point3D &position)
 {
   if (m_Position != position)
   {
     m_Position = position;
     this->Modified();
   }
 }
 
 bool mitk::AnnotationProperty::IsEqual(const BaseProperty &property) const
 {
   return ((this->m_Label == static_cast<const Self &>(property).m_Label) &&
           (this->m_Position == static_cast<const Self &>(property).m_Position));
 }
 
 bool mitk::AnnotationProperty::Assign(const BaseProperty &property)
 {
   this->m_Label = static_cast<const Self &>(property).m_Label;
   this->m_Position = static_cast<const Self &>(property).m_Position;
   return true;
 }
 
 std::string mitk::AnnotationProperty::GetValueAsString() const
 {
   std::stringstream myStr;
 
   myStr << this->GetLabel() << this->GetPosition();
   return myStr.str();
 }
 
 itk::LightObject::Pointer mitk::AnnotationProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
+
+bool mitk::AnnotationProperty::ToJSON(nlohmann::json& j) const
+{
+  j = nlohmann::json{
+    {"Label", this->GetLabel()},
+    {"Position", this->GetPosition()}};
+
+  return true;
+}
+
+bool mitk::AnnotationProperty::FromJSON(const nlohmann::json& j)
+{
+  this->SetLabel(j["Label"].get<std::string>());
+  this->SetPosition(j["Position"].get<Point3D>());
+  return true;
+}
diff --git a/Modules/Core/src/DataManagement/mitkClippingProperty.cpp b/Modules/Core/src/DataManagement/mitkClippingProperty.cpp
index 5dc7014d1e..b3e5a677e4 100644
--- a/Modules/Core/src/DataManagement/mitkClippingProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkClippingProperty.cpp
@@ -1,91 +1,110 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkClippingProperty.h"
 
 namespace mitk
 {
   ClippingProperty::ClippingProperty() : m_ClippingEnabled(false), m_Origin(0.0), m_Normal(0.0) {}
   ClippingProperty::ClippingProperty(const ClippingProperty &other)
     : BaseProperty(other),
       m_ClippingEnabled(other.m_ClippingEnabled),
       m_Origin(other.m_Origin),
       m_Normal(other.m_Normal)
   {
   }
 
   ClippingProperty::ClippingProperty(const Point3D &origin, const Vector3D &normal)
     : m_ClippingEnabled(true), m_Origin(origin), m_Normal(normal)
   {
   }
 
   bool ClippingProperty::GetClippingEnabled() const { return m_ClippingEnabled; }
   void ClippingProperty::SetClippingEnabled(bool enabled)
   {
     if (m_ClippingEnabled != enabled)
     {
       m_ClippingEnabled = enabled;
       this->Modified();
     }
   }
 
   const Point3D &ClippingProperty::GetOrigin() const { return m_Origin; }
   void ClippingProperty::SetOrigin(const Point3D &origin)
   {
     if (m_Origin != origin)
     {
       m_Origin = origin;
       this->Modified();
     }
   }
 
   const Vector3D &ClippingProperty::GetNormal() const { return m_Normal; }
   void ClippingProperty::SetNormal(const Vector3D &normal)
   {
     if (m_Normal != normal)
     {
       m_Normal = normal;
       this->Modified();
     }
   }
 
   bool ClippingProperty::IsEqual(const BaseProperty &property) const
   {
     return ((this->m_ClippingEnabled == static_cast<const Self &>(property).m_ClippingEnabled) &&
             (this->m_Origin == static_cast<const Self &>(property).m_Origin) &&
             (this->m_Normal == static_cast<const Self &>(property).m_Normal));
   }
 
   bool ClippingProperty::Assign(const BaseProperty &property)
   {
     this->m_ClippingEnabled = static_cast<const Self &>(property).m_ClippingEnabled;
     this->m_Origin = static_cast<const Self &>(property).m_Origin;
     this->m_Normal = static_cast<const Self &>(property).m_Normal;
     return true;
   }
 
   std::string ClippingProperty::GetValueAsString() const
   {
     std::stringstream myStr;
 
     myStr << this->GetClippingEnabled() << this->GetOrigin() << this->GetNormal();
     return myStr.str();
   }
 
+  bool ClippingProperty::ToJSON(nlohmann::json& j) const
+  {
+    j = nlohmann::json{
+      {"Enabled", this->GetClippingEnabled()},
+      {"Origin", this->GetOrigin()},
+      {"Normal", this->GetNormal()}};
+
+    return true;
+  }
+
+  bool ClippingProperty::FromJSON(const nlohmann::json& j)
+  {
+    this->SetClippingEnabled(j["Enabled"].get<bool>());
+    this->SetOrigin(j["Origin"].get<Point3D>());
+    this->SetNormal(j["Normal"].get<Vector3D>());
+
+    return true;
+  }
+
   itk::LightObject::Pointer ClippingProperty::InternalClone() const
   {
     itk::LightObject::Pointer result(new Self(*this));
     result->UnRegister();
     return result;
   }
 
 } // namespace
diff --git a/Modules/Core/src/DataManagement/mitkColorProperty.cpp b/Modules/Core/src/DataManagement/mitkColorProperty.cpp
index 2340d23b94..25d48f86a3 100644
--- a/Modules/Core/src/DataManagement/mitkColorProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkColorProperty.cpp
@@ -1,100 +1,103 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkColorProperty.h"
 #include <sstream>
+#include <nlohmann/json.hpp>
 
 mitk::ColorProperty::ColorProperty() : m_Color(0.0f)
 {
 }
 
 mitk::ColorProperty::ColorProperty(const mitk::ColorProperty &other) : BaseProperty(other), m_Color(other.m_Color)
 {
 }
 
 mitk::ColorProperty::ColorProperty(const float color[3]) : m_Color(color)
 {
 }
 
 mitk::ColorProperty::ColorProperty(const float red, const float green, const float blue)
 {
   m_Color.Set(red, green, blue);
 }
 
 mitk::ColorProperty::ColorProperty(const mitk::Color &color) : m_Color(color)
 {
 }
 
 bool mitk::ColorProperty::IsEqual(const BaseProperty &property) const
 {
   return this->m_Color == static_cast<const Self &>(property).m_Color;
 }
 
 bool mitk::ColorProperty::Assign(const BaseProperty &property)
 {
   this->m_Color = static_cast<const Self &>(property).m_Color;
   return true;
 }
 
 const mitk::Color &mitk::ColorProperty::GetColor() const
 {
   return m_Color;
 }
 
 void mitk::ColorProperty::SetColor(const mitk::Color &color)
 {
   if (m_Color != color)
   {
     m_Color = color;
     Modified();
   }
 }
 
 void mitk::ColorProperty::SetValue(const mitk::Color &color)
 {
   SetColor(color);
 }
 
 void mitk::ColorProperty::SetColor(float red, float green, float blue)
 {
   float tmp[3] = {red, green, blue};
   SetColor(mitk::Color(tmp));
 }
 
 std::string mitk::ColorProperty::GetValueAsString() const
 {
   std::stringstream myStr;
   myStr.imbue(std::locale::classic());
   myStr << GetValue();
   return myStr.str();
 }
 const mitk::Color &mitk::ColorProperty::GetValue() const
 {
   return GetColor();
 }
 
-void mitk::ColorProperty::ToJSON(nlohmann::json& j) const
+bool mitk::ColorProperty::ToJSON(nlohmann::json& j) const
 {
   j = this->GetColor();
+  return true;
 }
 
-void mitk::ColorProperty::FromJSON(const nlohmann::json& j)
+bool mitk::ColorProperty::FromJSON(const nlohmann::json& j)
 {
   this->SetColor(j.get<Color>());
+  return true;
 }
 
 itk::LightObject::Pointer mitk::ColorProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
diff --git a/Modules/Core/src/DataManagement/mitkEnumerationProperty.cpp b/Modules/Core/src/DataManagement/mitkEnumerationProperty.cpp
index a898451421..2019bf5375 100644
--- a/Modules/Core/src/DataManagement/mitkEnumerationProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkEnumerationProperty.cpp
@@ -1,181 +1,183 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include <mitkEnumerationProperty.h>
 #include <algorithm>
+#include <nlohmann/json.hpp>
 
 mitk::EnumerationProperty::EnumerationProperty()
   : m_CurrentValue(0)
 {
 }
 
 mitk::EnumerationProperty::EnumerationProperty(const EnumerationProperty &other)
   : BaseProperty(other),
     m_CurrentValue(other.m_CurrentValue),
     m_IdMap(other.m_IdMap),
     m_NameMap(other.m_NameMap)
 {
 }
 
 bool mitk::EnumerationProperty::AddEnum(const std::string &name, const IdType &id)
 {
   if (false == this->IsValidEnumerationValue(id) &&
       false == this->IsValidEnumerationValue(name))
   {
     this->GetEnumIds().insert(std::make_pair(id, name));
     this->GetEnumStrings().insert(std::make_pair(name, id));
 
     return true;
   }
 
   return false;
 }
 
 bool mitk::EnumerationProperty::SetValue(const std::string &name)
 {
   if (this->IsValidEnumerationValue(name))
   {
     m_CurrentValue = this->GetEnumId(name);
     this->Modified();
 
     return true;
   }
 
   return false;
 }
 
 bool mitk::EnumerationProperty::SetValue(const IdType &id)
 {
   if (this->IsValidEnumerationValue(id))
   {
     m_CurrentValue = id;
     this->Modified();
 
     return true;
   }
 
   return false;
 }
 
 mitk::EnumerationProperty::IdType mitk::EnumerationProperty::GetValueAsId() const
 {
   return m_CurrentValue;
 }
 
 std::string mitk::EnumerationProperty::GetValueAsString() const
 {
   return this->GetEnumString(m_CurrentValue);
 }
 
 void mitk::EnumerationProperty::Clear()
 {
   this->GetEnumIds().clear();
   this->GetEnumStrings().clear();
 
   m_CurrentValue = 0;
 }
 
 mitk::EnumerationProperty::EnumIdsContainerType::size_type mitk::EnumerationProperty::Size() const
 {
   return this->GetEnumIds().size();
 }
 
 mitk::EnumerationProperty::EnumConstIterator mitk::EnumerationProperty::Begin() const
 {
   return this->GetEnumIds().cbegin();
 }
 
 mitk::EnumerationProperty::EnumConstIterator mitk::EnumerationProperty::End() const
 {
   return this->GetEnumIds().cend();
 }
 
 std::string mitk::EnumerationProperty::GetEnumString(const IdType &id) const
 {
   return this->IsValidEnumerationValue(id)
     ? this->GetEnumIds().find(id)->second
     : std::string("invalid enum id or enums empty");
 }
 
 mitk::EnumerationProperty::IdType mitk::EnumerationProperty::GetEnumId(const std::string &name) const
 {
   return this->IsValidEnumerationValue(name)
     ? this->GetEnumStrings().find(name)->second
     : 0;
 }
 
 bool mitk::EnumerationProperty::IsEqual(const BaseProperty &property) const
 {
   const auto &other = static_cast<const Self &>(property);
 
   return
     this->Size() == other.Size() &&
     this->GetValueAsId() == other.GetValueAsId() &&
     std::equal(this->Begin(), this->End(), other.Begin());
 }
 
 bool mitk::EnumerationProperty::Assign(const BaseProperty &property)
 {
   const auto &other = static_cast<const Self &>(property);
 
   this->GetEnumIds() = other.GetEnumIds();
   this->GetEnumStrings() = other.GetEnumStrings();
 
   m_CurrentValue = other.m_CurrentValue;
 
   return true;
 }
 
 bool mitk::EnumerationProperty::IsValidEnumerationValue(const IdType &id) const
 {
   return this->GetEnumIds().end() != this->GetEnumIds().find(id);
 }
 
 bool mitk::EnumerationProperty::IsValidEnumerationValue(const std::string &name) const
 {
   return this->GetEnumStrings().end() != this->GetEnumStrings().find(name);
 }
 
 mitk::EnumerationProperty::EnumIdsContainerType & mitk::EnumerationProperty::GetEnumIds()
 {
   return m_IdMap;
 }
 
 const mitk::EnumerationProperty::EnumIdsContainerType & mitk::EnumerationProperty::GetEnumIds() const
 {
   return m_IdMap;
 }
 
 mitk::EnumerationProperty::EnumStringsContainerType & mitk::EnumerationProperty::GetEnumStrings()
 {
   return m_NameMap;
 }
 
 const mitk::EnumerationProperty::EnumStringsContainerType & mitk::EnumerationProperty::GetEnumStrings() const
 {
   return m_NameMap;
 }
 
-void mitk::EnumerationProperty::ToJSON(nlohmann::json& j) const
+bool mitk::EnumerationProperty::ToJSON(nlohmann::json& j) const
 {
   j = this->GetValueAsString();
+  return true;
 }
 
-void mitk::EnumerationProperty::FromJSON(const nlohmann::json& j)
+bool mitk::EnumerationProperty::FromJSON(const nlohmann::json& j)
 {
   auto name = j.get<std::string>();
 
-  if (!this->IsValidEnumerationValue(name))
+  if (!this->SetValue(name))
     mitkThrow() << '"' << name << "\" is not a valid enumeration value for " << this->GetNameOfClass() << '!';
 
-  this->SetValue(name);
+  return true;
 }
diff --git a/Modules/Core/src/DataManagement/mitkGroupTagProperty.cpp b/Modules/Core/src/DataManagement/mitkGroupTagProperty.cpp
index 2fc2aa5e05..272bbec8ff 100644
--- a/Modules/Core/src/DataManagement/mitkGroupTagProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkGroupTagProperty.cpp
@@ -1,39 +1,51 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkGroupTagProperty.h"
+#include <nlohmann/json.hpp>
 
 mitk::GroupTagProperty::GroupTagProperty() : mitk::BaseProperty()
 {
 }
 
 mitk::GroupTagProperty::GroupTagProperty(const GroupTagProperty &other) : mitk::BaseProperty(other)
 {
 }
 
 bool mitk::GroupTagProperty::IsEqual(const BaseProperty & /*property*/) const
 {
   // if other property is also a GroupTagProperty, then it is equal to us, because tags have no value themselves
   return true;
 }
 
 bool mitk::GroupTagProperty::Assign(const BaseProperty & /*property*/)
 {
   return true;
 }
 
+bool mitk::GroupTagProperty::ToJSON(nlohmann::json& j) const
+{
+  j = nlohmann::json::object();
+  return true;
+}
+
+bool mitk::GroupTagProperty::FromJSON(const nlohmann::json&)
+{
+  return true;
+}
+
 itk::LightObject::Pointer mitk::GroupTagProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
diff --git a/Modules/Core/src/DataManagement/mitkLevelWindow.cpp b/Modules/Core/src/DataManagement/mitkLevelWindow.cpp
index c3d8841919..be8a030d6a 100644
--- a/Modules/Core/src/DataManagement/mitkLevelWindow.cpp
+++ b/Modules/Core/src/DataManagement/mitkLevelWindow.cpp
@@ -1,510 +1,548 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkLevelWindow.h"
 #include "mitkImage.h"
 #include "mitkImageSliceSelector.h"
 #include "mitkImageStatisticsHolder.h"
 
 #include <algorithm>
+#include <nlohmann/json.hpp>
 
 void mitk::LevelWindow::EnsureConsistency()
 {
   // Check if total range is ok
   {
     if (m_RangeMin > m_RangeMax)
       std::swap(m_RangeMin, m_RangeMax);
     if (m_RangeMin == m_RangeMax)
       m_RangeMin = m_RangeMax - 1;
   }
 
   // Check if current window is ok
   {
     if (m_LowerWindowBound > m_UpperWindowBound)
       std::swap(m_LowerWindowBound, m_UpperWindowBound);
 
     if (m_LowerWindowBound <= m_RangeMin)
       m_LowerWindowBound = m_RangeMin;
     if (m_UpperWindowBound <= m_RangeMin)
       m_UpperWindowBound = m_RangeMin + 1;
     if (m_LowerWindowBound >= m_RangeMax)
       m_LowerWindowBound = m_RangeMax - 1;
     if (m_UpperWindowBound >= m_RangeMax)
       m_UpperWindowBound = m_RangeMax;
 
     if (m_LowerWindowBound == m_UpperWindowBound)
     {
       m_UpperWindowBound += 0.5;
       m_LowerWindowBound -= 0.5;
 
       m_UpperWindowBound = std::min(m_UpperWindowBound, m_RangeMax);
       m_LowerWindowBound = std::max(m_LowerWindowBound, m_RangeMin);
     }
   }
 }
 
 mitk::LevelWindow::LevelWindow(mitk::ScalarType level, mitk::ScalarType window)
   : m_LowerWindowBound(level - window / 2.0),
     m_UpperWindowBound(level + window / 2.0),
     m_RangeMin(-2048.0),
     m_RangeMax(4096.0),
     m_DefaultLowerBound(-2048.0),
     m_DefaultUpperBound(4096.0),
     m_IsFloatingImage(false),
     m_Fixed(false)
 {
   SetDefaultLevelWindow(level, window);
   SetLevelWindow(level, window, true);
 }
 
 mitk::LevelWindow::LevelWindow(const mitk::LevelWindow &levWin)
   : m_LowerWindowBound(levWin.GetLowerWindowBound()),
     m_UpperWindowBound(levWin.GetUpperWindowBound()),
     m_RangeMin(levWin.GetRangeMin()),
     m_RangeMax(levWin.GetRangeMax()),
     m_DefaultLowerBound(levWin.GetDefaultLowerBound()),
     m_DefaultUpperBound(levWin.GetDefaultUpperBound()),
     m_IsFloatingImage(levWin.IsFloatingValues()),
     m_Fixed(levWin.GetFixed())
 {
 }
 
 mitk::LevelWindow::~LevelWindow()
 {
 }
 
 mitk::ScalarType mitk::LevelWindow::GetLevel() const
 {
   return (m_UpperWindowBound - m_LowerWindowBound) / 2.0 + m_LowerWindowBound;
 }
 
 mitk::ScalarType mitk::LevelWindow::GetWindow() const
 {
   return (m_UpperWindowBound - m_LowerWindowBound);
 }
 
 mitk::ScalarType mitk::LevelWindow::GetDefaultLevel() const
 {
   return ((m_DefaultUpperBound + m_DefaultLowerBound) / 2.0);
 }
 
 mitk::ScalarType mitk::LevelWindow::GetDefaultWindow() const
 {
   return ((m_DefaultUpperBound - m_DefaultLowerBound));
 }
 
 void mitk::LevelWindow::ResetDefaultLevelWindow()
 {
   SetLevelWindow(GetDefaultLevel(), GetDefaultWindow());
 }
 
 mitk::ScalarType mitk::LevelWindow::GetLowerWindowBound() const
 {
   return m_LowerWindowBound;
 }
 
 mitk::ScalarType mitk::LevelWindow::GetUpperWindowBound() const
 {
   return m_UpperWindowBound;
 }
 
 void mitk::LevelWindow::SetDefaultLevelWindow(mitk::ScalarType level, mitk::ScalarType window)
 {
   SetDefaultBoundaries((level - (window / 2.0)), (level + (window / 2.0)));
 }
 
 void mitk::LevelWindow::SetLevelWindow(mitk::ScalarType level, mitk::ScalarType window, bool expandRangesIfNecessary)
 {
   SetWindowBounds((level - (window / 2.0)), (level + (window / 2.0)), expandRangesIfNecessary);
 }
 
 void mitk::LevelWindow::SetWindowBounds(mitk::ScalarType lowerBound,
                                         mitk::ScalarType upperBound,
                                         bool expandRangesIfNecessary)
 {
   if (IsFixed())
     return;
 
   upperBound = std::clamp(upperBound, -1e300, 1e300);
   lowerBound = std::clamp(lowerBound, -1e300, 1e300);
 
   m_LowerWindowBound = lowerBound;
   m_UpperWindowBound = upperBound;
 
   if (expandRangesIfNecessary)
   {
     /* if caller is sure he wants exactly that level/window, we make sure the limits match */
     if (m_LowerWindowBound > m_UpperWindowBound)
       std::swap(m_LowerWindowBound, m_UpperWindowBound);
     if (m_LowerWindowBound < m_RangeMin)
     {
       m_RangeMin = m_LowerWindowBound;
     }
 
     if (m_UpperWindowBound > m_RangeMax)
     {
       m_RangeMax = m_UpperWindowBound;
     }
   }
 
   EnsureConsistency();
 }
 
 void mitk::LevelWindow::SetRangeMinMax(mitk::ScalarType min, mitk::ScalarType max)
 {
   if (IsFixed())
     return;
   m_RangeMin = min;
   m_RangeMax = max;
   EnsureConsistency();
 }
 
 void mitk::LevelWindow::SetDefaultBoundaries(mitk::ScalarType low, mitk::ScalarType up)
 {
   if (IsFixed())
     return;
   m_DefaultLowerBound = low;
   m_DefaultUpperBound = up;
   // Check if default window is ok
   {
     if (m_DefaultLowerBound > m_DefaultUpperBound)
       std::swap(m_DefaultLowerBound, m_DefaultUpperBound);
 
     if (m_DefaultLowerBound == m_DefaultUpperBound)
       m_DefaultLowerBound--;
   }
   EnsureConsistency();
 }
 
 void mitk::LevelWindow::SetToMaxWindowSize()
 {
   SetWindowBounds(m_RangeMin, m_RangeMax);
 }
 
 mitk::ScalarType mitk::LevelWindow::GetRangeMin() const
 {
   return m_RangeMin;
 }
 
 mitk::ScalarType mitk::LevelWindow::GetRangeMax() const
 {
   return m_RangeMax;
 }
 
 mitk::ScalarType mitk::LevelWindow::GetRange() const
 {
   return m_RangeMax - m_RangeMin;
 }
 
 mitk::ScalarType mitk::LevelWindow::GetDefaultUpperBound() const
 {
   return m_DefaultUpperBound;
 }
 
 mitk::ScalarType mitk::LevelWindow::GetDefaultLowerBound() const
 {
   return m_DefaultLowerBound;
 }
 
 void mitk::LevelWindow::ResetDefaultRangeMinMax()
 {
   SetRangeMinMax(m_DefaultLowerBound, m_DefaultUpperBound);
 }
 
 /*!
 This method initializes a mitk::LevelWindow from an mitk::Image. The algorithm is as follows:
 
 Default to taking the central image slice for quick analysis.
 
 Compute the smallest (minValue), second smallest (min2ndValue), second largest (max2ndValue), and
 largest (maxValue) data value by traversing the pixel values only once. In the
 same scan it also computes the count of minValue values and maxValue values.
 After that a basic histogram with specific information about the
 extremes is complete.
 
 If minValue == maxValue, the center slice is uniform and the above scan is repeated for
 the complete image, not just one slice
 
 Next, special cases of images with only 1, 2 or 3 distinct data values
 have hand assigned level window ranges.
 
 Next the level window is set relative to the inner range IR = lengthOf([min2ndValue, max2ndValue])
 
 For count(minValue) > 20% the smallest values are frequent and should be
 distinct from the min2ndValue and larger values (minValue may be std:min, may signify
 something special) hence the lower end of the level window is set to min2ndValue - 0.5 * IR
 
 For count(minValue) <= 20% the smallest values are not so important and can
 blend with the next ones => min(level window) = min2ndValue
 
 And analog for max(level window):
 count(max2ndValue) > 20%:  max(level window) = max2ndValue + 0.5 * IR
 count(max2ndValue) < 20%:  max(level window) = max2ndValue
 
 In both 20%+ cases the level window bounds are clamped to the [minValue, maxValue] range
 
 In consequence the level window maximizes contrast with minimal amount of
 computation and does do useful things if the data contains std::min or
 std:max values or has only 1 or 2 or 3 data values.
 */
 void mitk::LevelWindow::SetAuto(const mitk::Image *image,
                                 bool /*tryPicTags*/,
                                 bool guessByCentralSlice,
                                 unsigned selectedComponent)
 {
   if (IsFixed())
     return;
 
   if (image == nullptr || !image->IsInitialized())
     return;
 
   if (itk::IOComponentEnum::FLOAT == image->GetPixelType().GetComponentType()
   ||  itk::IOComponentEnum::DOUBLE == image->GetPixelType().GetComponentType())
   {
     m_IsFloatingImage = true;
   }
   else
   {
     m_IsFloatingImage = false;
   }
 
   const mitk::Image *wholeImage = image;
   ScalarType minValue = 0.0;
   ScalarType maxValue = 0.0;
   ScalarType min2ndValue = 0.0;
   ScalarType max2ndValue = 0.0;
   mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New();
   if (guessByCentralSlice)
   {
     sliceSelector->SetInput(image);
     sliceSelector->SetSliceNr(image->GetDimension(2) / 2);
     sliceSelector->SetTimeNr(image->GetDimension(3) / 2);
     sliceSelector->SetChannelNr(image->GetDimension(4) / 2);
     sliceSelector->Update();
     image = sliceSelector->GetOutput();
     if (image == nullptr || !image->IsInitialized())
       return;
 
     minValue = image->GetStatistics()->GetScalarValueMin(0, selectedComponent);
     maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute();
     min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute();
     max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute();
     if (minValue == maxValue)
     {
       // guessByCentralSlice seems to have failed, lets look at all data
       image = wholeImage;
       minValue = image->GetStatistics()->GetScalarValueMin(0, selectedComponent);
       maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute();
       min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute();
       max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute();
     }
   }
   else
   {
     const_cast<Image *>(image)->Update();
     minValue = image->GetStatistics()->GetScalarValueMin(0, selectedComponent);
     maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute(0);
     min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute(0);
     max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute(0);
     for (unsigned int i = 1; i < image->GetDimension(3); ++i)
     {
       ScalarType minValueTemp = image->GetStatistics()->GetScalarValueMin(i, selectedComponent);
       if (minValue > minValueTemp)
         minValue = minValueTemp;
       ScalarType maxValueTemp = image->GetStatistics()->GetScalarValueMaxNoRecompute(i);
       if (maxValue < maxValueTemp)
         maxValue = maxValueTemp;
       ScalarType min2ndValueTemp = image->GetStatistics()->GetScalarValue2ndMinNoRecompute(i);
       if (min2ndValue > min2ndValueTemp)
         min2ndValue = min2ndValueTemp;
       ScalarType max2ndValueTemp = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute(i);
       if (max2ndValue > max2ndValueTemp)
         max2ndValue = max2ndValueTemp;
     }
   }
 
   // Fix for bug# 344 Level Window wird bei Eris Cut bildern nicht richtig gesetzt
   if (image->GetPixelType().GetPixelType() == itk::IOPixelEnum::SCALAR &&
       image->GetPixelType().GetComponentType() == itk::IOComponentEnum::INT && image->GetPixelType().GetBpe() >= 8)
   {
     // the windows compiler complains about ambiguous 'pow' call, therefore static casting to (double, int)
     if (minValue == -(pow((double)2.0, static_cast<int>(image->GetPixelType().GetBpe() / 2))))
     {
       minValue = min2ndValue;
     }
   }
   // End fix
 
   //// uniform image
   if (minValue == maxValue)
   {
     minValue = maxValue - 1;
   }
   else
   {
     // Due to bug #8690 level window now is no longer of fixed range by default but the range adapts according to
     // levelwindow interaction
     // This is done because the range should be a little bit larger from the beginning so that the scale doesn't start
     // to resize right from the beginning
     double additionalRange = 0.15 * (maxValue - minValue);
     minValue -= additionalRange;
     maxValue += additionalRange;
   }
 
   if (!std::isfinite(minValue))
   {
     minValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute(0);
   }
   if (!std::isfinite(maxValue))
   {
     maxValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute(0);
   }
 
   SetRangeMinMax(minValue, maxValue);
   SetDefaultBoundaries(minValue, maxValue);
 
   size_t numPixelsInDataset = image->GetDimensions()[0];
   for (decltype(image->GetDimension()) k = 1; k < image->GetDimension(); ++k)
     numPixelsInDataset *= image->GetDimensions()[k];
   const auto minCount = image->GetStatistics()->GetCountOfMinValuedVoxelsNoRecompute();
   const auto maxCount = image->GetStatistics()->GetCountOfMaxValuedVoxelsNoRecompute();
   const auto minCountFraction = minCount / static_cast<ScalarType>(numPixelsInDataset);
   const auto maxCountFraction = maxCount / static_cast<ScalarType>(numPixelsInDataset);
 
   //// binary image
   if (min2ndValue == maxValue)
   {
     // noop; full range is fine
   }
 
   //// triple value image, put middle value in center of gray level ramp
   else if (min2ndValue == max2ndValue)
   {
     ScalarType minDelta = std::min(min2ndValue - minValue, maxValue - min2ndValue);
     minValue = min2ndValue - minDelta;
     maxValue = min2ndValue + minDelta;
   }
 
   // now we can assume more than three distict scalar values
   else
   {
     ScalarType innerRange = max2ndValue - min2ndValue;
 
     if (minCountFraction > 0.2) //// lots of min values -> make different from rest, but not miles away
     {
       ScalarType halfInnerRangeGapMinValue = min2ndValue - innerRange / 2.0;
       minValue = std::max(minValue, halfInnerRangeGapMinValue);
     }
     else //// few min values -> focus on innerRange
     {
       minValue = min2ndValue;
     }
 
     if (maxCountFraction > 0.2) //// lots of max values -> make different from rest
     {
       ScalarType halfInnerRangeGapMaxValue = max2ndValue + innerRange / 2.0;
       maxValue = std::min(maxValue, halfInnerRangeGapMaxValue);
     }
     else //// few max values -> focus on innerRange
     {
       maxValue = max2ndValue;
     }
   }
   SetWindowBounds(minValue, maxValue);
   SetDefaultLevelWindow((maxValue - minValue) / 2 + minValue, maxValue - minValue);
 }
 
 void mitk::LevelWindow::SetToImageRange(const mitk::Image *image)
 {
   if (IsFixed())
     return;
 
   if (image == nullptr || !image->IsInitialized())
     return;
 
   ScalarType minValue = image->GetStatistics()->GetScalarValueMin(0);
   if (!std::isfinite(minValue))
   {
     minValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute(0);
   }
   ScalarType maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute(0);
   if (!std::isfinite(maxValue))
   {
     maxValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute(0);
   }
 
   SetRangeMinMax(minValue, maxValue);
   SetDefaultBoundaries(minValue, maxValue);
   SetWindowBounds(minValue, maxValue);
   SetDefaultLevelWindow((maxValue - minValue) / 2 + minValue, maxValue - minValue);
 }
 
 void mitk::LevelWindow::SetFixed(bool fixed)
 {
   m_Fixed = fixed;
 }
 
 bool mitk::LevelWindow::GetFixed() const
 {
   return m_Fixed;
 }
 
 bool mitk::LevelWindow::IsFixed() const
 {
   return m_Fixed;
 }
 
 bool mitk::LevelWindow::IsFloatingValues() const
 {
   return m_IsFloatingImage;
 }
 
 void mitk::LevelWindow::SetFloatingValues(bool value)
 {
   m_IsFloatingImage = value;
 }
 
 bool mitk::LevelWindow::operator==(const mitk::LevelWindow &levWin) const
 {
   return mitk::Equal(this->m_RangeMin, levWin.m_RangeMin, mitk::sqrteps) &&
          mitk::Equal(this->m_RangeMax, levWin.m_RangeMax, mitk::sqrteps) &&
          mitk::Equal(this->m_DefaultLowerBound, levWin.m_DefaultLowerBound, mitk::sqrteps) &&
          mitk::Equal(this->m_DefaultUpperBound, levWin.m_DefaultUpperBound, mitk::sqrteps) &&
          mitk::Equal(this->m_LowerWindowBound, levWin.m_LowerWindowBound, mitk::sqrteps) &&
          mitk::Equal(this->m_UpperWindowBound, levWin.m_UpperWindowBound, mitk::sqrteps) &&
          m_Fixed == levWin.IsFixed() && m_IsFloatingImage == levWin.IsFloatingValues();
 }
 
 bool mitk::LevelWindow::operator!=(const mitk::LevelWindow &levWin) const
 {
   return !((*this) == levWin);
 }
 
 mitk::LevelWindow &mitk::LevelWindow::operator=(const mitk::LevelWindow &levWin)
 {
   if (this == &levWin)
   {
     return *this;
   }
   else
   {
     m_RangeMin = levWin.GetRangeMin();
     m_RangeMax = levWin.GetRangeMax();
     m_LowerWindowBound = levWin.GetLowerWindowBound();
     m_UpperWindowBound = levWin.GetUpperWindowBound();
     m_DefaultLowerBound = levWin.GetDefaultLowerBound();
     m_DefaultUpperBound = levWin.GetDefaultUpperBound();
     m_Fixed = levWin.GetFixed();
     m_IsFloatingImage = levWin.IsFloatingValues();
     return *this;
   }
 }
+
+namespace mitk
+{
+  void to_json(nlohmann::json& j, const LevelWindow& lw)
+  {
+    j = nlohmann::json{
+      {"Fixed", lw.IsFixed()},
+      {"IsFloatingImage", lw.IsFloatingValues()},
+      {"CurrentSettings", {
+        {"Level", lw.GetLevel()},
+        {"Window", lw.GetWindow()}}},
+      {"DefaultSettings", {
+        {"Level", lw.GetDefaultLevel()},
+        {"Window", lw.GetDefaultWindow()}}},
+      {"CurrentRange", {
+        {"Min", lw.GetRangeMin()},
+        {"Max", lw.GetRangeMax()}}}};
+  }
+
+  void from_json(const nlohmann::json& j, LevelWindow& lw)
+  {
+    lw.SetRangeMinMax(
+      j["CurrentRange"]["Min"].get<ScalarType>(),
+      j["CurrentRange"]["Max"].get<ScalarType>());
+
+    lw.SetDefaultLevelWindow(
+      j["DefaultSettings"]["Level"].get<ScalarType>(),
+      j["DefaultSettings"]["Window"].get<ScalarType>());
+
+    lw.SetLevelWindow(
+      j["CurrentSettings"]["Level"].get<ScalarType>(),
+      j["CurrentSettings"]["Window"].get<ScalarType>());
+
+    lw.SetFixed(j["Fixed"].get<bool>());
+    lw.SetFloatingValues(j["IsFloatingImage"].get<bool>());
+  }
+}
diff --git a/Modules/Core/src/DataManagement/mitkLevelWindowProperty.cpp b/Modules/Core/src/DataManagement/mitkLevelWindowProperty.cpp
index 5376d63183..2f82af0ba7 100755
--- a/Modules/Core/src/DataManagement/mitkLevelWindowProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkLevelWindowProperty.cpp
@@ -1,80 +1,92 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkLevelWindowProperty.h"
 
 mitk::LevelWindowProperty::LevelWindowProperty()
 {
 }
 
 mitk::LevelWindowProperty::LevelWindowProperty(const mitk::LevelWindowProperty &other)
   : BaseProperty(other), m_LevWin(other.m_LevWin)
 {
 }
 
 mitk::LevelWindowProperty::LevelWindowProperty(const mitk::LevelWindow &levWin)
 {
   SetLevelWindow(levWin);
 }
 
 mitk::LevelWindowProperty::~LevelWindowProperty()
 {
 }
 
 bool mitk::LevelWindowProperty::IsEqual(const BaseProperty &property) const
 {
   return this->m_LevWin == static_cast<const Self &>(property).m_LevWin;
 }
 
 bool mitk::LevelWindowProperty::Assign(const BaseProperty &property)
 {
   this->m_LevWin = static_cast<const Self &>(property).m_LevWin;
   return true;
 }
 
 const mitk::LevelWindow &mitk::LevelWindowProperty::GetLevelWindow() const
 {
   return m_LevWin;
 }
 
 const mitk::LevelWindow &mitk::LevelWindowProperty::GetValue() const
 {
   return GetLevelWindow();
 }
 
 void mitk::LevelWindowProperty::SetLevelWindow(const mitk::LevelWindow &levWin)
 {
   if (m_LevWin != levWin)
   {
     m_LevWin = levWin;
     Modified();
   }
 }
 
 void mitk::LevelWindowProperty::SetValue(const ValueType &levWin)
 {
   SetLevelWindow(levWin);
 }
 
 std::string mitk::LevelWindowProperty::GetValueAsString() const
 {
   std::stringstream myStr;
   myStr << "L:" << m_LevWin.GetLevel() << " W:" << m_LevWin.GetWindow();
   return myStr.str();
 }
 
+bool mitk::LevelWindowProperty::ToJSON(nlohmann::json& j) const
+{
+  j = this->GetLevelWindow();
+  return true;
+}
+
+bool mitk::LevelWindowProperty::FromJSON(const nlohmann::json& j)
+{
+  this->SetLevelWindow(j.get<LevelWindow>());
+  return true;
+}
+
 itk::LightObject::Pointer mitk::LevelWindowProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
diff --git a/Modules/Core/src/DataManagement/mitkLookupTableProperty.cpp b/Modules/Core/src/DataManagement/mitkLookupTableProperty.cpp
index d9edff7c6b..63751f8bfa 100644
--- a/Modules/Core/src/DataManagement/mitkLookupTableProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkLookupTableProperty.cpp
@@ -1,149 +1,154 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkLookupTableProperty.h"
+#include <nlohmann/json.hpp>
 
 mitk::LookupTableProperty::LookupTableProperty()
 {
   mitk::LookupTable::Pointer lut = mitk::LookupTable::New();
   this->SetLookupTable(lut);
 }
 
 mitk::LookupTableProperty::LookupTableProperty(const LookupTableProperty &other)
   : mitk::BaseProperty(other), m_LookupTable(other.m_LookupTable)
 {
 }
 
 mitk::LookupTableProperty::LookupTableProperty(const mitk::LookupTable::Pointer lut)
 {
   this->SetLookupTable(lut);
 }
 
 bool mitk::LookupTableProperty::IsEqual(const BaseProperty &property) const
 {
   return *(this->m_LookupTable) == *(static_cast<const Self &>(property).m_LookupTable);
 }
 
 bool mitk::LookupTableProperty::Assign(const BaseProperty &property)
 {
   this->m_LookupTable = static_cast<const Self &>(property).m_LookupTable;
   return true;
 }
 
 std::string mitk::LookupTableProperty::GetValueAsString() const
 {
   std::stringstream ss;
   ss << m_LookupTable;
   return ss.str();
 }
 
 mitk::LookupTableProperty::ValueType mitk::LookupTableProperty::GetValue() const
 {
   return m_LookupTable;
 }
 
 void mitk::LookupTableProperty::SetLookupTable(const mitk::LookupTable::Pointer aLookupTable)
 {
   if ((m_LookupTable != aLookupTable) || (*m_LookupTable != *aLookupTable))
   {
     m_LookupTable = aLookupTable;
     Modified();
   }
 }
 
 void mitk::LookupTableProperty::SetValue(const ValueType &value)
 {
   SetLookupTable(value);
 }
 
-void mitk::LookupTableProperty::ToJSON(nlohmann::json& j) const
+bool mitk::LookupTableProperty::ToJSON(nlohmann::json& j) const
 {
   auto lut = this->GetValue()->GetVtkLookupTable();
 
   auto table = nlohmann::json::array();
   auto numTableValues = lut->GetNumberOfTableValues();
 
   for (decltype(numTableValues) i = 0; i < numTableValues; ++i)
   {
     auto value = nlohmann::json::array();
 
     for (size_t j = 0; j < 4; ++j)
       value.push_back(lut->GetTableValue(i)[j]);
 
     table.push_back(value);
   }
 
-  j = nlohmann::json::object({
+  j = nlohmann::json{{
     { "NumberOfColors", static_cast<int>(lut->GetNumberOfTableValues()) },
     { "Scale", lut->GetScale() },
     { "Ramp", lut->GetRamp() },
     { "HueRange", nlohmann::json::array({ lut->GetHueRange()[0], lut->GetHueRange()[1] }) },
     { "ValueRange", nlohmann::json::array({ lut->GetValueRange()[0], lut->GetValueRange()[1] }) },
     { "SaturationRange", nlohmann::json::array({ lut->GetSaturationRange()[0], lut->GetSaturationRange()[1] }) },
     { "AlphaRange", nlohmann::json::array({ lut->GetAlphaRange()[0], lut->GetAlphaRange()[1] }) },
     { "TableRange", nlohmann::json::array({ lut->GetTableRange()[0], lut->GetTableRange()[1] }) },
     { "Table", table }
-  });
+  }};
+
+  return true;
 }
 
-void mitk::LookupTableProperty::FromJSON(const nlohmann::json& j)
+bool mitk::LookupTableProperty::FromJSON(const nlohmann::json& j)
 {
   auto lut = vtkSmartPointer<vtkLookupTable>::New();
 
   lut->SetNumberOfTableValues(j["NumberOfColors"].get<int>());
   lut->SetScale(j["Scale"].get<int>());
   lut->SetScale(j["Ramp"].get<int>());
 
   std::array<double, 2> range;
 
   j["HueRange"][0].get_to(range[0]);
   j["HueRange"][1].get_to(range[1]);
   lut->SetHueRange(range.data());
 
   j["ValueRange"][0].get_to(range[0]);
   j["ValueRange"][1].get_to(range[1]);
   lut->SetValueRange(range.data());
 
   j["SaturationRange"][0].get_to(range[0]);
   j["SaturationRange"][1].get_to(range[1]);
   lut->SetSaturationRange(range.data());
 
   j["AlphaRange"][0].get_to(range[0]);
   j["AlphaRange"][1].get_to(range[1]);
   lut->SetAlphaRange(range.data());
 
   j["TableRange"][0].get_to(range[0]);
   j["TableRange"][1].get_to(range[1]);
   lut->SetTableRange(range.data());
 
   std::array<double, 4> rgba;
   vtkIdType i = 0;
 
   for (const auto& value : j["Table"])
   {
     for (size_t j = 0; j < 4; ++j)
       value[j].get_to(rgba[j]);
 
     lut->SetTableValue(i++, rgba.data());
   }
 
   auto mitkLut = LookupTable::New();
   mitkLut->SetVtkLookupTable(lut);
   this->SetLookupTable(mitkLut);
+
+  return true;
 }
 
 itk::LightObject::Pointer mitk::LookupTableProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
diff --git a/Modules/Core/src/DataManagement/mitkSmartPointerProperty.cpp b/Modules/Core/src/DataManagement/mitkSmartPointerProperty.cpp
index 0ca671f20d..dad9fa882d 100644
--- a/Modules/Core/src/DataManagement/mitkSmartPointerProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkSmartPointerProperty.cpp
@@ -1,136 +1,146 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkSmartPointerProperty.h"
 
 mitk::SmartPointerProperty::ReferenceCountMapType mitk::SmartPointerProperty::m_ReferenceCount;
 mitk::SmartPointerProperty::ReferencesUIDMapType mitk::SmartPointerProperty::m_ReferencesUID;
 mitk::SmartPointerProperty::ReadInSmartPointersMapType mitk::SmartPointerProperty::m_ReadInInstances;
 mitk::SmartPointerProperty::ReadInTargetsMapType mitk::SmartPointerProperty::m_ReadInTargets;
 mitk::UIDGenerator mitk::SmartPointerProperty::m_UIDGenerator("POINTER_");
 
 void mitk::SmartPointerProperty::PostProcessXMLReading()
 {
   for (auto iter = m_ReadInInstances.begin(); iter != m_ReadInInstances.end(); ++iter)
   {
     if (m_ReadInTargets.find(iter->second) != m_ReadInTargets.end())
     {
       iter->first->SetSmartPointer(m_ReadInTargets[iter->second]);
     }
   }
 
   m_ReadInInstances.clear();
 }
 
 /// \return The number of SmartPointerProperties that point to @param object
 unsigned int mitk::SmartPointerProperty::GetReferenceCountFor(itk::Object *object)
 {
   if (m_ReferenceCount.find(object) != m_ReferenceCount.end())
   {
     return m_ReferenceCount[object];
   }
   else
   {
     return 0;
   }
 }
 
 void mitk::SmartPointerProperty::RegisterPointerTarget(itk::Object *object, const std::string uid)
 {
   m_ReadInTargets[uid] = object;
 }
 
 std::string mitk::SmartPointerProperty::GetReferenceUIDFor(itk::Object *object)
 {
   if (m_ReferencesUID.find(object) != m_ReferencesUID.end())
   {
     return m_ReferencesUID[object];
   }
   else
   {
     return std::string("invalid");
   }
 }
 
 bool mitk::SmartPointerProperty::IsEqual(const BaseProperty &property) const
 {
   return this->m_SmartPointer == static_cast<const Self &>(property).m_SmartPointer;
 }
 
 bool mitk::SmartPointerProperty::Assign(const BaseProperty &property)
 {
   this->m_SmartPointer = static_cast<const Self &>(property).m_SmartPointer;
   return true;
 }
 
 mitk::SmartPointerProperty::SmartPointerProperty(itk::Object *pointer)
 {
   SetSmartPointer(pointer);
 }
 
 mitk::SmartPointerProperty::SmartPointerProperty(const SmartPointerProperty &other)
   : BaseProperty(other), m_SmartPointer(other.m_SmartPointer)
 {
 }
 
 itk::Object::Pointer mitk::SmartPointerProperty::GetSmartPointer() const
 {
   return m_SmartPointer;
 }
 
 itk::Object::Pointer mitk::SmartPointerProperty::GetValue() const
 {
   return this->GetSmartPointer();
 }
 
 void mitk::SmartPointerProperty::SetSmartPointer(itk::Object *pointer)
 {
   if (m_SmartPointer.GetPointer() != pointer)
   {
     // keep track of referenced objects
     if (m_SmartPointer.GetPointer() &&
         --m_ReferenceCount[m_SmartPointer.GetPointer()] == 0) // if there is no reference left, delete entry
     {
       m_ReferenceCount.erase(m_SmartPointer.GetPointer());
       m_ReferencesUID.erase(m_SmartPointer.GetPointer());
     }
 
     if (pointer && ++m_ReferenceCount[pointer] == 1) // first reference --> generate UID
     {
       m_ReferencesUID[pointer] = m_UIDGenerator.GetUID();
     }
 
     // change pointer
     m_SmartPointer = pointer;
     Modified();
   }
 }
 
 void mitk::SmartPointerProperty::SetValue(const ValueType &value)
 {
   this->SetSmartPointer(value.GetPointer());
 }
 
 std::string mitk::SmartPointerProperty::GetValueAsString() const
 {
   if (m_SmartPointer.IsNotNull())
     return m_ReferencesUID[m_SmartPointer.GetPointer()];
   else
     return std::string("nullptr");
 }
 
+bool mitk::SmartPointerProperty::ToJSON(nlohmann::json&) const
+{
+  return false;
+}
+
+bool mitk::SmartPointerProperty::FromJSON(const nlohmann::json&)
+{
+  return false;
+}
+
 itk::LightObject::Pointer mitk::SmartPointerProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
diff --git a/Modules/Core/src/DataManagement/mitkStringProperty.cpp b/Modules/Core/src/DataManagement/mitkStringProperty.cpp
index 88b088ef25..cc1ecf9e69 100644
--- a/Modules/Core/src/DataManagement/mitkStringProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkStringProperty.cpp
@@ -1,61 +1,64 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkStringProperty.h"
+#include <nlohmann/json.hpp>
 
 const char *mitk::StringProperty::PATH = "path";
 mitk::StringProperty::StringProperty(const char *string) : m_Value()
 {
   if (string)
     m_Value = string;
 }
 
 mitk::StringProperty::StringProperty(const std::string &s) : m_Value(s)
 {
 }
 
 mitk::StringProperty::StringProperty(const StringProperty &other) : BaseProperty(other), m_Value(other.m_Value)
 {
 }
 
 bool mitk::StringProperty::IsEqual(const BaseProperty &property) const
 {
   return this->m_Value == static_cast<const Self &>(property).m_Value;
 }
 
 bool mitk::StringProperty::Assign(const BaseProperty &property)
 {
   this->m_Value = static_cast<const Self &>(property).m_Value;
   return true;
 }
 
 std::string mitk::StringProperty::GetValueAsString() const
 {
   return m_Value;
 }
 
-void mitk::StringProperty::ToJSON(nlohmann::json& j) const
+bool mitk::StringProperty::ToJSON(nlohmann::json& j) const
 {
   j = this->GetValueAsString();
+  return true;
 }
 
-void mitk::StringProperty::FromJSON(const nlohmann::json& j)
+bool mitk::StringProperty::FromJSON(const nlohmann::json& j)
 {
   this->SetValue(j.get<std::string>());
+  return true;
 }
 
 itk::LightObject::Pointer mitk::StringProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
diff --git a/Modules/Core/src/DataManagement/mitkTemporoSpatialStringProperty.cpp b/Modules/Core/src/DataManagement/mitkTemporoSpatialStringProperty.cpp
index a3e0b1f549..6a2eeb4a09 100644
--- a/Modules/Core/src/DataManagement/mitkTemporoSpatialStringProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkTemporoSpatialStringProperty.cpp
@@ -1,493 +1,426 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include <iterator>
 #include <set>
 #include <type_traits>
 
 #include "mitkTemporoSpatialStringProperty.h"
 
 #include <nlohmann/json.hpp>
 
-using namespace nlohmann;
+using CondensedTimeKeyType = std::pair<mitk::TimeStepType, mitk::TimeStepType>;
+using CondensedTimePointsType = std::map<CondensedTimeKeyType, std::string>;
+
+using CondensedSliceKeyType = std::pair<mitk::TemporoSpatialStringProperty::IndexValueType, mitk::TemporoSpatialStringProperty::IndexValueType>;
+using CondensedSlicesType = std::map<CondensedSliceKeyType, CondensedTimePointsType>;
+
+namespace
+{
+  /** Helper function that checks if between an ID and a successive ID is no gap.*/
+  template<typename TValue>
+  bool isGap(const TValue& value, const TValue& successor)
+  {
+    return value<successor || value > successor + 1;
+  }
+
+
+  template<typename TNewKey, typename TNewValue, typename TMasterKey, typename TMasterValue, typename TCondensedContainer>
+  void CheckAndCondenseElement(const TNewKey& newKeyMinID, const TNewValue& newValue, TMasterKey& masterKey, TMasterValue& masterValue, TCondensedContainer& condensedContainer)
+  {
+    if (newValue != masterValue
+      || isGap(newKeyMinID, masterKey.second))
+    {
+      condensedContainer[masterKey] = masterValue;
+      masterValue = newValue;
+      masterKey.first = newKeyMinID;
+    }
+    masterKey.second = newKeyMinID;
+  }
+
+  /** Helper function that tries to condense the values of time points for a slice as much as possible and returns all slices with condensed timepoint values.*/
+  CondensedSlicesType CondenseTimePointValuesOfProperty(const mitk::TemporoSpatialStringProperty* tsProp)
+  {
+    CondensedSlicesType uncondensedSlices;
+
+    auto zs = tsProp->GetAvailableSlices();
+    for (const auto z : zs)
+    {
+      CondensedTimePointsType condensedTimePoints;
+      auto timePointIDs = tsProp->GetAvailableTimeSteps(z);
+      CondensedTimeKeyType condensedKey = { timePointIDs.front(),timePointIDs.front() };
+      auto refValue = tsProp->GetValue(timePointIDs.front(), z);
+
+      for (const auto timePointID : timePointIDs)
+      {
+        const auto& newVal = tsProp->GetValue(timePointID, z);
+        CheckAndCondenseElement(timePointID, newVal, condensedKey, refValue, condensedTimePoints);
+      }
+      condensedTimePoints[condensedKey] = refValue;
+      uncondensedSlices[{ z, z }] = condensedTimePoints;
+    }
+    return uncondensedSlices;
+  }
+}
 
 mitk::TemporoSpatialStringProperty::TemporoSpatialStringProperty(const char *s)
 {
   if (s)
   {
     SliceMapType slices{{0, s}};
 
     m_Values.insert(std::make_pair(0, slices));
   }
 }
 
 mitk::TemporoSpatialStringProperty::TemporoSpatialStringProperty(const std::string &s)
 {
   SliceMapType slices{{0, s}};
 
   m_Values.insert(std::make_pair(0, slices));
 }
 
 mitk::TemporoSpatialStringProperty::TemporoSpatialStringProperty(const TemporoSpatialStringProperty &other)
   : BaseProperty(other), m_Values(other.m_Values)
 {
 }
 
 bool mitk::TemporoSpatialStringProperty::IsEqual(const BaseProperty &property) const
 {
   return this->m_Values == static_cast<const Self &>(property).m_Values;
 }
 
 bool mitk::TemporoSpatialStringProperty::Assign(const BaseProperty &property)
 {
   this->m_Values = static_cast<const Self &>(property).m_Values;
   return true;
 }
 
 std::string mitk::TemporoSpatialStringProperty::GetValueAsString() const
 {
   return GetValue();
 }
 
 bool mitk::TemporoSpatialStringProperty::IsUniform() const
 {
   auto refValue = this->GetValue();
 
   for (const auto& timeStep : m_Values)
   {
     auto finding = std::find_if_not(timeStep.second.begin(), timeStep.second.end(), [&refValue](const mitk::TemporoSpatialStringProperty::SliceMapType::value_type& val) { return val.second == refValue; });
     if (finding != timeStep.second.end())
     {
       return false;
     }
   }
 
   return true;
 }
 
 itk::LightObject::Pointer mitk::TemporoSpatialStringProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
 
 mitk::TemporoSpatialStringProperty::ValueType mitk::TemporoSpatialStringProperty::GetValue() const
 {
   std::string result = "";
 
   if (!m_Values.empty())
   {
     if (!m_Values.begin()->second.empty())
     {
       result = m_Values.begin()->second.begin()->second;
     }
   }
   return result;
 };
 
 std::pair<bool, mitk::TemporoSpatialStringProperty::ValueType> mitk::TemporoSpatialStringProperty::CheckValue(
   const TimeStepType &timeStep, const IndexValueType &zSlice, bool allowCloseTime, bool allowCloseSlice) const
 {
   std::string value = "";
   bool found = false;
 
   auto timeIter = m_Values.find(timeStep);
   auto timeEnd = m_Values.end();
   if (timeIter == timeEnd && allowCloseTime)
   { // search for closest time step (earlier preverd)
     timeIter = m_Values.upper_bound(timeStep);
     if (timeIter != m_Values.begin())
     { // there is a key lower than time step
       timeIter = std::prev(timeIter);
     }
   }
 
   if (timeIter != timeEnd)
   {
     const SliceMapType &slices = timeIter->second;
 
     auto sliceIter = slices.find(zSlice);
     auto sliceEnd = slices.end();
     if (sliceIter == sliceEnd && allowCloseSlice)
     { // search for closest slice (earlier preverd)
       sliceIter = slices.upper_bound(zSlice);
       if (sliceIter != slices.begin())
       { // there is a key lower than slice
         sliceIter = std::prev(sliceIter);
       }
     }
 
     if (sliceIter != sliceEnd)
     {
       value = sliceIter->second;
       found = true;
     }
   }
 
   return std::make_pair(found, value);
 };
 
 mitk::TemporoSpatialStringProperty::ValueType mitk::TemporoSpatialStringProperty::GetValue(const TimeStepType &timeStep,
                                                                                            const IndexValueType &zSlice,
                                                                                            bool allowCloseTime,
                                                                                            bool allowCloseSlice) const
 {
   return CheckValue(timeStep, zSlice, allowCloseTime, allowCloseSlice).second;
 };
 
 mitk::TemporoSpatialStringProperty::ValueType mitk::TemporoSpatialStringProperty::GetValueBySlice(
   const IndexValueType &zSlice, bool allowClose) const
 {
   return GetValue(0, zSlice, true, allowClose);
 };
 
 mitk::TemporoSpatialStringProperty::ValueType mitk::TemporoSpatialStringProperty::GetValueByTimeStep(
   const TimeStepType &timeStep, bool allowClose) const
 {
   return GetValue(timeStep, 0, allowClose, true);
 };
 
 bool mitk::TemporoSpatialStringProperty::HasValue() const
 {
   return !m_Values.empty();
 };
 
 bool mitk::TemporoSpatialStringProperty::HasValue(const TimeStepType &timeStep,
                                                   const IndexValueType &zSlice,
                                                   bool allowCloseTime,
                                                   bool allowCloseSlice) const
 {
   return CheckValue(timeStep, zSlice, allowCloseTime, allowCloseSlice).first;
 };
 
 bool mitk::TemporoSpatialStringProperty::HasValueBySlice(const IndexValueType &zSlice, bool allowClose) const
 {
   return HasValue(0, zSlice, true, allowClose);
 };
 
 bool mitk::TemporoSpatialStringProperty::HasValueByTimeStep(const TimeStepType &timeStep, bool allowClose) const
 {
   return HasValue(timeStep, 0, allowClose, true);
 };
 
 std::vector<mitk::TemporoSpatialStringProperty::IndexValueType> mitk::TemporoSpatialStringProperty::GetAvailableSlices() const
 {
   std::set<IndexValueType> uniqueSlices;
 
   for (const auto& timeStep : m_Values)
   {
     for (const auto& slice : timeStep.second)
     {
       uniqueSlices.insert(slice.first);
     }
   }
 
   return std::vector<IndexValueType>(std::begin(uniqueSlices), std::end(uniqueSlices));
 }
 
 std::vector<mitk::TemporoSpatialStringProperty::IndexValueType> mitk::TemporoSpatialStringProperty::GetAvailableSlices(
   const TimeStepType &timeStep) const
 {
   std::vector<IndexValueType> result;
 
   auto timeIter = m_Values.find(timeStep);
   auto timeEnd = m_Values.end();
 
   if (timeIter != timeEnd)
   {
     for (auto const &element : timeIter->second)
     {
       result.push_back(element.first);
     }
   }
 
   return result;
 };
 
 std::vector<mitk::TimeStepType> mitk::TemporoSpatialStringProperty::GetAvailableTimeSteps() const
 {
   std::vector<mitk::TimeStepType> result;
 
   for (auto const &element : m_Values)
   {
     result.push_back(element.first);
   }
 
   return result;
 };
 
 std::vector<mitk::TimeStepType> mitk::TemporoSpatialStringProperty::GetAvailableTimeSteps(const IndexValueType& slice) const
 {
   std::vector<mitk::TimeStepType> result;
 
   for (const auto& timeStep : m_Values)
   {
     if (timeStep.second.find(slice) != std::end(timeStep.second))
     {
       result.push_back(timeStep.first);
     }
   }
   return result;
 }
 
 
 void mitk::TemporoSpatialStringProperty::SetValue(const TimeStepType &timeStep,
                                                   const IndexValueType &zSlice,
                                                   const ValueType &value)
 {
   auto timeIter = m_Values.find(timeStep);
   auto timeEnd = m_Values.end();
 
   if (timeIter == timeEnd)
   {
     SliceMapType slices{{zSlice, value}};
     m_Values.insert(std::make_pair(timeStep, slices));
   }
   else
   {
     timeIter->second[zSlice] = value;
   }
   this->Modified();
 };
 
 void mitk::TemporoSpatialStringProperty::SetValue(const ValueType &value)
 {
   this->Modified();
   m_Values.clear();
   this->SetValue(0, 0, value);
 };
 
-// Create necessary escape sequences from illegal characters
-// REMARK: This code is based upon code from boost::ptree::json_writer.
-// The corresponding boost function was not used directly, because it is not part of
-// the public interface of ptree::json_writer. :(
-// A own serialization strategy was implemented instead of using boost::ptree::json_write because
-// currently (<= boost 1.60) everything (even numbers) are converted into string representations
-// by the writer, so e.g. it becomes "t":"2" instead of "t":2
-template <class Ch>
-std::basic_string<Ch> CreateJSONEscapes(const std::basic_string<Ch> &s)
+bool mitk::TemporoSpatialStringProperty::ToJSON(nlohmann::json& j) const
 {
-  std::basic_string<Ch> result;
-  typename std::basic_string<Ch>::const_iterator b = s.begin();
-  typename std::basic_string<Ch>::const_iterator e = s.end();
-  while (b != e)
-  {
-    using UCh = std::make_unsigned_t<Ch>;
-    UCh c(*b);
-    // This assumes an ASCII superset.
-    // We escape everything outside ASCII, because this code can't
-    // handle high unicode characters.
-    if (c == 0x20 || c == 0x21 || (c >= 0x23 && c <= 0x2E) || (c >= 0x30 && c <= 0x5B) || (c >= 0x5D && c <= 0x7F))
-      result += *b;
-    else if (*b == Ch('\b'))
-      result += Ch('\\'), result += Ch('b');
-    else if (*b == Ch('\f'))
-      result += Ch('\\'), result += Ch('f');
-    else if (*b == Ch('\n'))
-      result += Ch('\\'), result += Ch('n');
-    else if (*b == Ch('\r'))
-      result += Ch('\\'), result += Ch('r');
-    else if (*b == Ch('\t'))
-      result += Ch('\\'), result += Ch('t');
-    else if (*b == Ch('/'))
-      result += Ch('\\'), result += Ch('/');
-    else if (*b == Ch('"'))
-      result += Ch('\\'), result += Ch('"');
-    else if (*b == Ch('\\'))
-      result += Ch('\\'), result += Ch('\\');
-    else
-    {
-      const char *hexdigits = "0123456789ABCDEF";
-      unsigned long u = (std::min)(static_cast<unsigned long>(static_cast<UCh>(*b)), 0xFFFFul);
-      int d1 = u / 4096;
-      u -= d1 * 4096;
-      int d2 = u / 256;
-      u -= d2 * 256;
-      int d3 = u / 16;
-      u -= d3 * 16;
-      int d4 = u;
-      result += Ch('\\');
-      result += Ch('u');
-      result += Ch(hexdigits[d1]);
-      result += Ch(hexdigits[d2]);
-      result += Ch(hexdigits[d3]);
-      result += Ch(hexdigits[d4]);
-    }
-    ++b;
-  }
-  return result;
-}
-
-using CondensedTimeKeyType = std::pair<mitk::TimeStepType, mitk::TimeStepType>;
-using CondensedTimePointsType = std::map<CondensedTimeKeyType, std::string>;
-
-using CondensedSliceKeyType = std::pair<mitk::TemporoSpatialStringProperty::IndexValueType, mitk::TemporoSpatialStringProperty::IndexValueType>;
-using CondensedSlicesType = std::map<CondensedSliceKeyType, CondensedTimePointsType>;
-
-/** Helper function that checks if between an ID and a successive ID is no gap.*/
-template<typename TValue>
-bool isGap(const TValue& value, const TValue& successor)
-{
-  return value<successor || value > successor + 1;
-}
-
-
-template<typename TNewKey, typename TNewValue, typename TMasterKey, typename TMasterValue, typename TCondensedContainer>
-void CheckAndCondenseElement(const TNewKey& newKeyMinID, const TNewValue& newValue, TMasterKey& masterKey, TMasterValue& masterValue, TCondensedContainer& condensedContainer)
-{
-  if (newValue != masterValue
-    || isGap(newKeyMinID, masterKey.second))
-  {
-    condensedContainer[masterKey] = masterValue;
-    masterValue = newValue;
-    masterKey.first = newKeyMinID;
-  }
-  masterKey.second = newKeyMinID;
-}
-
-/** Helper function that tries to condense the values of time points for a slice as much as possible and returns all slices with condensed timepoint values.*/
-CondensedSlicesType CondenseTimePointValuesOfProperty(const mitk::TemporoSpatialStringProperty* tsProp)
-{
-  CondensedSlicesType uncondensedSlices;
-
-  auto zs = tsProp->GetAvailableSlices();
-  for (const auto z : zs)
-  {
-    CondensedTimePointsType condensedTimePoints;
-    auto timePointIDs = tsProp->GetAvailableTimeSteps(z);
-    CondensedTimeKeyType condensedKey = { timePointIDs.front(),timePointIDs.front() };
-    auto refValue = tsProp->GetValue(timePointIDs.front(), z);
-
-    for (const auto timePointID : timePointIDs)
-    {
-      const auto& newVal = tsProp->GetValue(timePointID, z);
-      CheckAndCondenseElement(timePointID, newVal, condensedKey, refValue, condensedTimePoints);
-    }
-    condensedTimePoints[condensedKey] = refValue;
-    uncondensedSlices[{ z, z }] = condensedTimePoints;
-  }
-  return uncondensedSlices;
-}
-
-::std::string mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON(
-  const mitk::BaseProperty *prop)
-{
-  // REMARK: Implemented own serialization instead of using boost::ptree::json_write because
-  // currently (<= boost 1.60) everything (even numbers) are converted into string representations
-  // by the writer, so e.g. it becomes "t":"2" instead of "t":2
-  // If this problem is fixed with boost, we should switch back to json_writer (and remove the custom
-  // implementation of CreateJSONEscapes (see above)).
-  const auto *tsProp = dynamic_cast<const mitk::TemporoSpatialStringProperty *>(prop);
-
-  if (!tsProp)
-  {
-    mitkThrow() << "Cannot serialize properties of types other than TemporoSpatialStringProperty.";
-  }
-
-  std::ostringstream stream;
-  stream.imbue(std::locale("C"));
-  stream << "{\"values\":[";
-
-  //we condense the content of the property to have a compact serialization.
-  //we start with condensing time points and then slices (in difference to the
-  //internal layout). Reason: There is more entropy in slices (looking at DICOM)
-  //than across time points for one slice, so we can "compress" to a higher rate.
-  //We don't wanted to change the internal structure of the property as it would
-  //introduce API inconvenience and subtle changes in behavior.
-  CondensedSlicesType uncondensedSlices = CondenseTimePointValuesOfProperty(tsProp);
-
-  //now condense the slices
+  // We condense the content of the property to have a compact serialization.
+  // We start with condensing time points and then slices (in difference to the
+  // internal layout). Reason: There is more entropy in slices (looking at DICOM)
+  // than across time points for one slice, so we can "compress" at a higher rate.
+  // We didn't want to change the internal structure of the property as it would
+  // introduce API inconvenience and subtle changes in behavior.
+  auto uncondensedSlices = CondenseTimePointValuesOfProperty(this);
   CondensedSlicesType condensedSlices;
+
   if(!uncondensedSlices.empty())
   {
-    CondensedTimePointsType& masterSlice = uncondensedSlices.begin()->second;
-    CondensedSliceKeyType masterSliceKey = uncondensedSlices.begin()->first;
+    auto& masterSlice = uncondensedSlices.begin()->second;
+    auto masterSliceKey = uncondensedSlices.begin()->first;
 
     for (const auto& uncondensedSlice : uncondensedSlices)
     {
       const auto& uncondensedSliceID = uncondensedSlice.first.first;
       CheckAndCondenseElement(uncondensedSliceID, uncondensedSlice.second, masterSliceKey, masterSlice, condensedSlices);
     }
+
     condensedSlices[masterSliceKey] = masterSlice;
   }
 
+  auto values = nlohmann::json::array();
 
-  bool first = true;
   for (const auto& z : condensedSlices)
   {
     for (const auto& t : z.second)
     {
-      if (first)
-      {
-        first = false;
-      }
-      else
-      {
-        stream << ", ";
-      }
-
       const auto& minSliceID = z.first.first;
       const auto& maxSliceID = z.first.second;
       const auto& minTimePointID = t.first.first;
       const auto& maxTimePointID = t.first.second;
 
-      stream << "{\"z\":" << minSliceID << ", ";
+      auto value = nlohmann::json::object();
+      value.push_back({"z", minSliceID});
+
       if (minSliceID != maxSliceID)
-      {
-        stream << "\"zmax\":" << maxSliceID << ", ";
-      }
-      stream << "\"t\":" << minTimePointID << ", ";
+        value.push_back({"zmax", maxSliceID});
+
+      value.push_back({"t", minTimePointID});
+
       if (minTimePointID != maxTimePointID)
-      {
-        stream << "\"tmax\":" << maxTimePointID << ", ";
-      }
+        value.push_back({"tmax", maxTimePointID});
+
+      value.push_back({"value", t.second});
 
-      const auto& value = t.second;
-      stream << "\"value\":\"" << CreateJSONEscapes(value) << "\"}";
+      values.push_back(value);
     }
   }
 
-  stream << "]}";
+  j = nlohmann::json{{"values", values}};
 
-  return stream.str();
+  return true;
 }
 
-mitk::BaseProperty::Pointer mitk::PropertyPersistenceDeserialization::deserializeJSONToTemporoSpatialStringProperty(
-  const std::string &value)
+bool mitk::TemporoSpatialStringProperty::FromJSON(const nlohmann::json& j)
 {
-  if (value.empty())
-    return nullptr;
-
-  mitk::TemporoSpatialStringProperty::Pointer prop = mitk::TemporoSpatialStringProperty::New();
-
-  auto root = json::parse(value);
-
-  for (const auto& element : root["values"])
+  for (const auto& element : j["values"])
   {
     auto value = element.value("value", "");
     auto z = element.value<TemporoSpatialStringProperty::IndexValueType>("z", 0);
     auto zmax = element.value<TemporoSpatialStringProperty::IndexValueType>("zmax", z);
     auto t = element.value<TimeStepType>("t", 0);
     auto tmax = element.value<TimeStepType>("tmax", t);
 
     for (auto currentT = t; currentT <= tmax; ++currentT)
     {
       for (auto currentZ = z; currentZ <= zmax; ++currentZ)
       {
-        prop->SetValue(currentT, currentZ, value);
+        this->SetValue(currentT, currentZ, value);
       }
     }
   }
 
+  return true;
+}
+
+std::string mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON(const mitk::BaseProperty *prop)
+{
+  const auto *tsProp = dynamic_cast<const mitk::TemporoSpatialStringProperty *>(prop);
+
+  if (!tsProp)
+    mitkThrow() << "Cannot serialize properties of types other than TemporoSpatialStringProperty.";
+
+  nlohmann::json j;
+  tsProp->ToJSON(j);
+
+  return j.dump();
+}
+
+mitk::BaseProperty::Pointer mitk::PropertyPersistenceDeserialization::deserializeJSONToTemporoSpatialStringProperty(const std::string &value)
+{
+  if (value.empty())
+    return nullptr;
+
+  auto prop = mitk::TemporoSpatialStringProperty::New();
+
+  auto root = nlohmann::json::parse(value);
+  prop->FromJSON(root);
+
   return prop.GetPointer();
 }
diff --git a/Modules/Core/src/DataManagement/mitkTransferFunctionProperty.cpp b/Modules/Core/src/DataManagement/mitkTransferFunctionProperty.cpp
index 3e5bce2ca6..20a59af2a7 100644
--- a/Modules/Core/src/DataManagement/mitkTransferFunctionProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkTransferFunctionProperty.cpp
@@ -1,53 +1,125 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkTransferFunctionProperty.h"
+#include <nlohmann/json.hpp>
 
 namespace mitk
 {
   bool TransferFunctionProperty::IsEqual(const BaseProperty &property) const
   {
     return *(this->m_Value) == *(static_cast<const Self &>(property).m_Value);
   }
 
   bool TransferFunctionProperty::Assign(const BaseProperty &property)
   {
     this->m_Value = static_cast<const Self &>(property).m_Value;
     return true;
   }
 
   std::string TransferFunctionProperty::GetValueAsString() const
   {
     std::stringstream myStr;
     myStr << GetValue();
     return myStr.str();
   }
 
   TransferFunctionProperty::TransferFunctionProperty() : BaseProperty(), m_Value(mitk::TransferFunction::New()) {}
   TransferFunctionProperty::TransferFunctionProperty(const TransferFunctionProperty &other)
     : BaseProperty(other), m_Value(other.m_Value->Clone())
   {
   }
 
   TransferFunctionProperty::TransferFunctionProperty(mitk::TransferFunction::Pointer value)
     : BaseProperty(), m_Value(value)
   {
   }
 
+  bool TransferFunctionProperty::ToJSON(nlohmann::json& j) const
+  {
+    auto tf = this->GetValue();
+
+    auto scalarOpacity = nlohmann::json::array();
+
+    for (const auto& point : tf->GetScalarOpacityPoints())
+      scalarOpacity.push_back(point);
+
+    auto gradientOpacity = nlohmann::json::array();
+
+    for (const auto& point : tf->GetGradientOpacityPoints())
+      gradientOpacity.push_back(point);
+
+    auto* ctf = tf->GetColorTransferFunction();
+    auto size = ctf->GetSize();
+
+    std::array<double, 6> value;
+    auto color = nlohmann::json::array();
+
+    for (int i = 0; i < size; ++i)
+    {
+      ctf->GetNodeValue(i, value.data());
+      color.push_back(value);
+    }
+
+    j = nlohmann::json{
+      {"ScalarOpacity", scalarOpacity},
+      {"GradientOpacity", gradientOpacity},
+      {"Color", color}};
+
+    return true;
+  }
+
+  bool TransferFunctionProperty::FromJSON(const nlohmann::json& j)
+  {
+    auto tf = TransferFunction::New();
+    TransferFunction::ControlPoints::value_type point; 
+
+    tf->ClearScalarOpacityPoints();
+
+    for (const auto& opacity : j["ScalarOpacity"])
+    {
+      opacity.get_to(point);
+      tf->AddScalarOpacityPoint(point.first, point.second);
+    }
+
+    tf->ClearGradientOpacityPoints();
+
+    for (const auto& opacity : j["GradientOpacity"])
+    {
+      opacity.get_to(point);
+      tf->AddGradientOpacityPoint(point.first, point.second);
+    }
+
+    auto* ctf = tf->GetColorTransferFunction();
+    ctf->RemoveAllPoints();
+
+    std::array<double, 6> value;
+
+    for (const auto& color : j["Color"])
+    {
+      color.get_to(value);
+      ctf->AddRGBPoint(value[0], value[1], value[2], value[3], value[4], value[5]);
+    }
+
+    this->SetValue(tf);
+
+    return true;
+  }
+
   itk::LightObject::Pointer TransferFunctionProperty::InternalClone() const
   {
     itk::LightObject::Pointer result(new Self(*this));
     result->UnRegister();
     return result;
   }
 
 } // namespace mitk
diff --git a/Modules/Core/src/DataManagement/mitkVectorProperty.cpp b/Modules/Core/src/DataManagement/mitkVectorProperty.cpp
index d2fa075f52..f6e986629f 100644
--- a/Modules/Core/src/DataManagement/mitkVectorProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkVectorProperty.cpp
@@ -1,90 +1,105 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkVectorProperty.h"
+#include <nlohmann/json.hpp>
 
 namespace mitk
 {
   template <typename DATATYPE>
   bool VectorProperty<DATATYPE>::IsEqual(const BaseProperty &property) const
   {
     return this->m_PropertyContent == static_cast<const Self &>(property).m_PropertyContent;
   }
 
   template <typename DATATYPE>
   bool VectorProperty<DATATYPE>::Assign(const BaseProperty &property)
   {
     this->m_PropertyContent = static_cast<const Self &>(property).m_PropertyContent;
     return true;
   }
 
   template <typename DATATYPE>
   itk::LightObject::Pointer VectorProperty<DATATYPE>::InternalClone() const
   {
     itk::LightObject::Pointer result(new Self(*this));
     return result;
   }
 
   template <typename DATATYPE>
   std::string VectorProperty<DATATYPE>::GetValueAsString() const
   {
     const size_t displayBlockLength = 3;
     size_t beginningElementsCount = displayBlockLength;
     size_t endElementsCount = displayBlockLength;
 
     if (m_PropertyContent.size() <= 2 * displayBlockLength)
     {
       beginningElementsCount = m_PropertyContent.size();
       endElementsCount = 0;
     }
 
     // return either a block of all items
     // if the total number of maximum 2*displayBlockLength
     //
     // or return the first and last "displayBlockLength"
     // number of items separated by "[...]";
     std::stringstream string_collector;
     for (size_t i = 0; i < beginningElementsCount; i++)
       string_collector << m_PropertyContent[i] << "\n";
     if (endElementsCount)
       string_collector << "[... " << m_PropertyContent.size() - 2 * displayBlockLength << " more]\n";
     for (size_t i = m_PropertyContent.size() - endElementsCount; i < m_PropertyContent.size(); ++i)
       string_collector << m_PropertyContent[i] << "\n";
 
     std::string return_value = string_collector.str();
 
     // remove last '\n'
     if (!return_value.empty())
       return_value.erase(return_value.size() - 1);
 
     return return_value;
   }
 
   template <typename DATATYPE>
   void VectorProperty<DATATYPE>::SetValue(const VectorType &newValue)
   {
     m_PropertyContent = newValue;
   }
 
   template <typename DATATYPE>
   const typename VectorProperty<DATATYPE>::VectorType &VectorProperty<DATATYPE>::GetValue() const
   {
     return m_PropertyContent;
   }
 
+  template <typename DATATYPE>
+  bool VectorProperty<DATATYPE>::ToJSON(nlohmann::json& j) const
+  {
+    j = this->GetValue();
+    return true;
+  }
+
+  template <typename DATATYPE>
+  bool VectorProperty<DATATYPE>::FromJSON(const nlohmann::json& j)
+  {
+    this->SetValue(j.get<VectorType>());
+    return true;
+  }
+
   // Explicit instantiation for defined types.
   MITK_DEFINE_VECTOR_PROPERTY(double)
   MITK_DEFINE_VECTOR_PROPERTY(int)
   MITK_DEFINE_VECTOR_PROPERTY(unsigned int)
   MITK_DEFINE_VECTOR_PROPERTY(std::string)
 
 } // namespace mitk
diff --git a/Modules/Core/src/DataManagement/mitkWeakPointerProperty.cpp b/Modules/Core/src/DataManagement/mitkWeakPointerProperty.cpp
index 33249b73cf..e3b8f46fde 100644
--- a/Modules/Core/src/DataManagement/mitkWeakPointerProperty.cpp
+++ b/Modules/Core/src/DataManagement/mitkWeakPointerProperty.cpp
@@ -1,75 +1,85 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkWeakPointerProperty.h"
 
 bool mitk::WeakPointerProperty::IsEqual(const BaseProperty &property) const
 {
   return this->m_WeakPointer == static_cast<const Self &>(property).m_WeakPointer;
 }
 
 bool mitk::WeakPointerProperty::Assign(const BaseProperty &property)
 {
   this->m_WeakPointer = static_cast<const Self &>(property).m_WeakPointer;
   return true;
 }
 
 mitk::WeakPointerProperty::WeakPointerProperty(itk::Object *pointer) : m_WeakPointer(pointer)
 {
 }
 
 mitk::WeakPointerProperty::WeakPointerProperty(const WeakPointerProperty &other)
   : mitk::BaseProperty(other), m_WeakPointer(other.m_WeakPointer)
 {
 }
 
 mitk::WeakPointerProperty::~WeakPointerProperty()
 {
 }
 
 std::string mitk::WeakPointerProperty::GetValueAsString() const
 {
   std::stringstream ss;
   ss << m_WeakPointer.GetPointer();
   return ss.str();
 }
 
 mitk::WeakPointerProperty::ValueType mitk::WeakPointerProperty::GetWeakPointer() const
 {
   return m_WeakPointer.GetPointer();
 }
 
 mitk::WeakPointerProperty::ValueType mitk::WeakPointerProperty::GetValue() const
 {
   return GetWeakPointer();
 }
 
 void mitk::WeakPointerProperty::SetWeakPointer(itk::Object *pointer)
 {
   if (m_WeakPointer.GetPointer() != pointer)
   {
     m_WeakPointer = pointer;
     Modified();
   }
 }
 
 void mitk::WeakPointerProperty::SetValue(const ValueType &value)
 {
   SetWeakPointer(value.GetPointer());
 }
 
+bool mitk::WeakPointerProperty::ToJSON(nlohmann::json&) const
+{
+  return false;
+}
+
+bool mitk::WeakPointerProperty::FromJSON(const nlohmann::json&)
+{
+  return false;
+}
+
 itk::LightObject::Pointer mitk::WeakPointerProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   result->UnRegister();
   return result;
 }
diff --git a/Modules/Core/test/mitkTemporoSpatialStringPropertyTest.cpp b/Modules/Core/test/mitkTemporoSpatialStringPropertyTest.cpp
index ae79c6260b..48db4613df 100644
--- a/Modules/Core/test/mitkTemporoSpatialStringPropertyTest.cpp
+++ b/Modules/Core/test/mitkTemporoSpatialStringPropertyTest.cpp
@@ -1,242 +1,245 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkTemporoSpatialStringProperty.h"
 #include "mitkTestFixture.h"
 #include "mitkTestingMacros.h"
 
 #include <limits>
 
 class mitkTemporoSpatialStringPropertyTestSuite : public mitk::TestFixture
 {
   CPPUNIT_TEST_SUITE(mitkTemporoSpatialStringPropertyTestSuite);
 
   MITK_TEST(GetValue);
   MITK_TEST(HasValue);
   MITK_TEST(SetValue);
   MITK_TEST(IsUniform);
 
   MITK_TEST(serializeTemporoSpatialStringPropertyToJSON);
   MITK_TEST(deserializeJSONToTemporoSpatialStringProperty);
 
   CPPUNIT_TEST_SUITE_END();
 
 private:
   std::string refJSON;
   std::string refJSON_legacy;
   std::string refPartlyCondensibleJSON;
   std::string refCondensibleJSON;
   mitk::TemporoSpatialStringProperty::Pointer refProp;
   mitk::TemporoSpatialStringProperty::Pointer refPartlyCondensibleProp;
   mitk::TemporoSpatialStringProperty::Pointer refCondensibleProp;
 
 public:
   void setUp() override
   {
     refJSON_legacy = "{\"values\":[{\"t\":0, \"z\":0, \"value\":\"v_0_0\"}, {\"t\":3, \"z\":0, \"value\":\"v_3_0\"}, "
                      "{\"t\":3, \"z\":2, \"value\":\"v_3_2\"}, {\"t\":6, \"z\":1, \"value\":\"v_6_1\"}]}";
     refJSON = "{\"values\":[{\"z\":0, \"t\":0, \"value\":\"v_0_0\"}, {\"z\":0, \"t\":3, \"value\":\"v_3_0\"}, {\"z\":1, \"t\":6, \"value\":\"v_6_1\"}, {\"z\":2, \"t\":3, \"value\":\"v_3_2\"}]}";
     refPartlyCondensibleJSON = "{\"values\":[{\"z\":0, \"t\":0, \"value\":\"0\"}, {\"z\":1, \"t\":0, \"tmax\":1, \"value\":\"0\"}, {\"z\":1, \"t\":3, \"tmax\":5, \"value\":\"0\"}, {\"z\":1, \"t\":6, \"value\":\"otherValue\"}, {\"z\":2, \"t\":6, \"value\":\"0\"}]}";
     refCondensibleJSON = "{\"values\":[{\"z\":0, \"zmax\":2, \"t\":0, \"tmax\":1, \"value\":\"1\"}]}";
     refProp = mitk::TemporoSpatialStringProperty::New();
     refProp->SetValue(0, 0, "v_0_0");
     refProp->SetValue(3, 0, "v_3_0");
     refProp->SetValue(3, 2, "v_3_2");
     refProp->SetValue(6, 1, "v_6_1");
 
     refPartlyCondensibleProp = mitk::TemporoSpatialStringProperty::New();
     refPartlyCondensibleProp->SetValue(0, 0, "0");
     refPartlyCondensibleProp->SetValue(0, 1, "0");
     refPartlyCondensibleProp->SetValue(1, 1, "0");
     refPartlyCondensibleProp->SetValue(3, 1, "0");
     refPartlyCondensibleProp->SetValue(4, 1, "0");
     refPartlyCondensibleProp->SetValue(5, 1, "0");
     refPartlyCondensibleProp->SetValue(6, 1, "otherValue");
     refPartlyCondensibleProp->SetValue(6, 2, "0");
 
     refCondensibleProp = mitk::TemporoSpatialStringProperty::New();
     refCondensibleProp->SetValue(0, 0, "1");
     refCondensibleProp->SetValue(1, 0, "1");
     refCondensibleProp->SetValue(0, 1, "1");
     refCondensibleProp->SetValue(1, 1, "1");
     refCondensibleProp->SetValue(0, 2, "1");
     refCondensibleProp->SetValue(1, 2, "1");
   }
 
   void tearDown() override {}
 
   void GetValue()
   {
     CPPUNIT_ASSERT(refProp->GetValue() == "v_0_0");
 
     CPPUNIT_ASSERT(refProp->GetValue(3, 0) == "v_3_0");
     CPPUNIT_ASSERT(refProp->GetValue(3, 2) == "v_3_2");
     CPPUNIT_ASSERT(refProp->GetValue(3, 1, false, true) == "v_3_0");
     CPPUNIT_ASSERT(refProp->GetValue(3, 5, false, true) == "v_3_2");
 
     CPPUNIT_ASSERT(refProp->GetValueBySlice(0) == "v_0_0");
     CPPUNIT_ASSERT(refProp->GetValueBySlice(4, true) == "v_0_0");
 
     CPPUNIT_ASSERT(refProp->GetValueByTimeStep(3) == "v_3_0");
     CPPUNIT_ASSERT(refProp->GetValueByTimeStep(6) == "v_6_1");
     CPPUNIT_ASSERT(refProp->GetValueByTimeStep(5, true) == "v_3_0");
 
     CPPUNIT_ASSERT(refProp->GetValueAsString() == "v_0_0");
 
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps().size() == 3);
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps()[0] == 0);
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps()[1] == 3);
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps()[2] == 6);
 
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps(0).size() == 2);
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps(0)[0] == 0);
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps(0)[1] == 3);
 
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps(1).size() == 1);
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps(1)[0] == 6);
 
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps(5).size() == 0);
 
     CPPUNIT_ASSERT(refProp->GetAvailableSlices().size() == 3);
     CPPUNIT_ASSERT(refProp->GetAvailableSlices()[0] == 0);
     CPPUNIT_ASSERT(refProp->GetAvailableSlices()[1] == 1);
     CPPUNIT_ASSERT(refProp->GetAvailableSlices()[2] == 2);
 
     CPPUNIT_ASSERT(refProp->GetAvailableSlices(0).size() == 1);
     CPPUNIT_ASSERT(refProp->GetAvailableSlices(0)[0] == 0);
     CPPUNIT_ASSERT(refProp->GetAvailableSlices(3).size() == 2);
     CPPUNIT_ASSERT(refProp->GetAvailableSlices(3)[0] == 0);
     CPPUNIT_ASSERT(refProp->GetAvailableSlices(3)[1] == 2);
 
     CPPUNIT_ASSERT(refProp->GetAvailableSlices(2).size() == 0);
   }
 
   void HasValue()
   {
     CPPUNIT_ASSERT(refProp->HasValue());
 
     CPPUNIT_ASSERT(refProp->HasValue(3, 0));
     CPPUNIT_ASSERT(refProp->HasValue(3, 2));
     CPPUNIT_ASSERT(refProp->HasValue(3, 1, false, true));
     CPPUNIT_ASSERT(refProp->HasValue(3, 5, false, true));
     CPPUNIT_ASSERT(!refProp->HasValue(3, 1));
     CPPUNIT_ASSERT(!refProp->HasValue(3, 5));
     CPPUNIT_ASSERT(refProp->HasValue(4, 2, true, true));
     CPPUNIT_ASSERT(refProp->HasValue(4, 2, true, false));
     CPPUNIT_ASSERT(!refProp->HasValue(4, 2, false, true));
 
     CPPUNIT_ASSERT(refProp->HasValueBySlice(0));
     CPPUNIT_ASSERT(refProp->HasValueBySlice(4, true));
     CPPUNIT_ASSERT(!refProp->HasValueBySlice(4));
 
     CPPUNIT_ASSERT(refProp->HasValueByTimeStep(3));
     CPPUNIT_ASSERT(refProp->HasValueByTimeStep(6));
     CPPUNIT_ASSERT(refProp->HasValueByTimeStep(5, true));
     CPPUNIT_ASSERT(!refProp->HasValueByTimeStep(5));
   }
 
   void SetValue()
   {
     CPPUNIT_ASSERT_NO_THROW(refProp->SetValue(8, 9, "v_8_9"));
     CPPUNIT_ASSERT(refProp->GetValue(8, 9) == "v_8_9");
 
     CPPUNIT_ASSERT_NO_THROW(refProp->SetValue("newValue"));
     CPPUNIT_ASSERT(refProp->GetValue(0, 0) == "newValue");
     CPPUNIT_ASSERT(refProp->GetAvailableTimeSteps().size() == 1);
     CPPUNIT_ASSERT(refProp->GetAvailableSlices(0).size() == 1);
   }
 
   void IsUniform()
   {
     CPPUNIT_ASSERT(!refProp->IsUniform());
     CPPUNIT_ASSERT(!refPartlyCondensibleProp->IsUniform());
     CPPUNIT_ASSERT(refCondensibleProp->IsUniform());
   }
 
   void serializeTemporoSpatialStringPropertyToJSON()
   {
-    std::string data = mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON(refProp);
-    CPPUNIT_ASSERT(refJSON ==
-      data); //"Testing serializeTemporoSpatialStringPropertyToJSON() producing correct string.");
+    auto data = nlohmann::json::parse(mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON(refProp));
+    auto ref = nlohmann::json::parse(refJSON);
 
-    data = mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON(refPartlyCondensibleProp);
-    CPPUNIT_ASSERT(refPartlyCondensibleJSON ==
-      data);
+    CPPUNIT_ASSERT(ref == data); //"Testing serializeTemporoSpatialStringPropertyToJSON() producing correct string.");
 
-    data = mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON(refCondensibleProp);
-    CPPUNIT_ASSERT(refCondensibleJSON ==
-      data);
+    data = nlohmann::json::parse(mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON(refPartlyCondensibleProp));
+    ref = nlohmann::json::parse(refPartlyCondensibleJSON);
+
+    CPPUNIT_ASSERT(ref == data);
+
+    data = nlohmann::json::parse(mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON(refCondensibleProp));
+    ref = nlohmann::json::parse(refCondensibleJSON);
+
+    CPPUNIT_ASSERT(ref == data);
   }
 
   void deserializeJSONToTemporoSpatialStringProperty()
   {
     mitk::BaseProperty::Pointer prop =
       mitk::PropertyPersistenceDeserialization::deserializeJSONToTemporoSpatialStringProperty(refJSON);
 
     auto *tsProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(prop.GetPointer());
 
     CPPUNIT_ASSERT(
       tsProp->GetValue(0, 0) ==
       "v_0_0"); //"Testing deserializeJSONToTemporoSpatialStringProperty() producing property with correct value 1");
     CPPUNIT_ASSERT(
       tsProp->GetValue(3, 0) ==
       "v_3_0"); //"Testing deserializeJSONToTemporoSpatialStringProperty() producing property with correct value 2");
     CPPUNIT_ASSERT(
       tsProp->GetValue(3, 2) ==
       "v_3_2"); //"Testing deserializeJSONToTemporoSpatialStringProperty() producing property with correct value 3");
     CPPUNIT_ASSERT(
       tsProp->GetValue(6, 1) ==
       "v_6_1"); //"Testing deserializeJSONToTemporoSpatialStringProperty() producing property with correct value 4");
     CPPUNIT_ASSERT(*tsProp == *refProp); //"Testing deserializeJSONToTemporoSpatialStringProperty()");
 
     prop = mitk::PropertyPersistenceDeserialization::deserializeJSONToTemporoSpatialStringProperty(refJSON_legacy);
     tsProp = dynamic_cast<mitk::TemporoSpatialStringProperty*>(prop.GetPointer());
     CPPUNIT_ASSERT(
       tsProp->GetValue(0, 0) ==
       "v_0_0"); //"Testing deserializeJSONToTemporoSpatialStringProperty() producing property with correct value 1");
     CPPUNIT_ASSERT(
       tsProp->GetValue(3, 0) ==
       "v_3_0"); //"Testing deserializeJSONToTemporoSpatialStringProperty() producing property with correct value 2");
     CPPUNIT_ASSERT(
       tsProp->GetValue(3, 2) ==
       "v_3_2"); //"Testing deserializeJSONToTemporoSpatialStringProperty() producing property with correct value 3");
     CPPUNIT_ASSERT(
       tsProp->GetValue(6, 1) ==
       "v_6_1"); //"Testing deserializeJSONToTemporoSpatialStringProperty() producing property with correct value 4");
     CPPUNIT_ASSERT(*tsProp == *refProp); //"Testing deserializeJSONToTemporoSpatialStringProperty()");
 
 
     prop = mitk::PropertyPersistenceDeserialization::deserializeJSONToTemporoSpatialStringProperty(refPartlyCondensibleJSON);
     tsProp = dynamic_cast<mitk::TemporoSpatialStringProperty*>(prop.GetPointer());
     CPPUNIT_ASSERT(tsProp->GetValue(0, 0) =="0");
     CPPUNIT_ASSERT(tsProp->GetValue(0, 1) == "0");
     CPPUNIT_ASSERT(tsProp->GetValue(1, 1) == "0");
     CPPUNIT_ASSERT(tsProp->GetValue(3, 1) == "0");
     CPPUNIT_ASSERT(tsProp->GetValue(4, 1) == "0");
     CPPUNIT_ASSERT(tsProp->GetValue(5, 1) == "0");
     CPPUNIT_ASSERT(tsProp->GetValue(6, 1) == "otherValue");
     CPPUNIT_ASSERT(tsProp->GetValue(6, 2) == "0");
     CPPUNIT_ASSERT(*tsProp == *refPartlyCondensibleProp);
     
     prop = mitk::PropertyPersistenceDeserialization::deserializeJSONToTemporoSpatialStringProperty(refCondensibleJSON);
     tsProp = dynamic_cast<mitk::TemporoSpatialStringProperty*>(prop.GetPointer());
     CPPUNIT_ASSERT(tsProp->GetValue(0, 0) == "1");
     CPPUNIT_ASSERT(tsProp->GetValue(1, 0) == "1");
     CPPUNIT_ASSERT(tsProp->GetValue(0, 1) == "1");
     CPPUNIT_ASSERT(tsProp->GetValue(1, 1) == "1");
     CPPUNIT_ASSERT(tsProp->GetValue(0, 2) == "1");
     CPPUNIT_ASSERT(tsProp->GetValue(1, 2) == "1");
     CPPUNIT_ASSERT(*tsProp == *refCondensibleProp);
   }
 };
 
 MITK_TEST_SUITE_REGISTRATION(mitkTemporoSpatialStringProperty)
diff --git a/Modules/ModelFit/include/mitkScalarListLookupTable.h b/Modules/ModelFit/include/mitkScalarListLookupTable.h
index 92c1541736..b7bed70910 100644
--- a/Modules/ModelFit/include/mitkScalarListLookupTable.h
+++ b/Modules/ModelFit/include/mitkScalarListLookupTable.h
@@ -1,91 +1,95 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkScalarListLookupTable_h
 #define mitkScalarListLookupTable_h
 
 #include <string>
 #include <vector>
 #include <map>
+#include <nlohmann/json_fwd.hpp>
 
 #include "MitkModelFitExports.h"
 
 namespace mitk
 {
     /**
      *  @brief  Data class for modelfit properties that store a map of lists (e.g. static
      *          parameters).
      */
     class MITKMODELFIT_EXPORT ScalarListLookupTable
     {
     public:
         typedef std::string KeyType;
         typedef std::vector<double> ValueType;
         typedef std::map<KeyType, ValueType> LookupTableType;
         typedef std::pair<KeyType, ValueType> EntryType;
 
         ScalarListLookupTable() {}
         virtual ~ScalarListLookupTable() {}
 
         virtual const char* GetNameOfClass() const;
 
         /**
          *  @brief          Sets the list at the given map key to the given value.
          *  @param key      The name of the list (i.e. map key).
          *  @param value    The list to be added (i.e. map value).
          */
         void SetTableValue(const KeyType& key, const ValueType& value);
 
         /**
          *  @brief      Returns true if the list with the given name exists.
          *  @param key  The name of the desired list (i.e. map key)
          *  @return     true if the list exists or false otherwise.
          */
         bool ValueExists(const KeyType& key) const;
 
         /**
          *  @brief      Returns the list with the given name.
          *  @param key  The name (i.e. map key) of the desired list.
          *  @return     The list with the given name.
          *  @throw std::range_error If the list doesn't exist.
          */
         const ValueType& GetTableValue(const KeyType& key) const;
 
         /**
          *  @brief  Returns the map of lists.
          *  @return The map of lists.
          */
         const LookupTableType& GetLookupTable() const;
 
         void SetLookupTable(const LookupTableType& table);
 
         bool operator==(const ScalarListLookupTable& lookupTable) const;
         bool operator!=(const ScalarListLookupTable& lookupTable) const;
 
         virtual ScalarListLookupTable& operator=(const ScalarListLookupTable& other);
 
     protected:
         LookupTableType m_LookupTable;
     };
 
     /**
      *  @brief          Adds the string representation of the given ScalarListLookupTable to the
      *                  given stream.
      *  @param stream   The stream to which the map's string representation should be added.
      *  @param l        The map whose string representation should be added to the stream.
      *  @return         The given stream with the added string representation of the map.
      */
     MITKMODELFIT_EXPORT std::ostream& operator<<(std::ostream& stream,
             const ScalarListLookupTable& l);
+
+    MITKMODELFIT_EXPORT void to_json(nlohmann::json& j, const ScalarListLookupTable& lut);
+    MITKMODELFIT_EXPORT void from_json(const nlohmann::json& j, ScalarListLookupTable& lut);
 }
 
 #endif
diff --git a/Modules/ModelFit/src/Common/mitkScalarListLookupTable.cpp b/Modules/ModelFit/src/Common/mitkScalarListLookupTable.cpp
index 35d1c336ac..fa8c3b5a3b 100644
--- a/Modules/ModelFit/src/Common/mitkScalarListLookupTable.cpp
+++ b/Modules/ModelFit/src/Common/mitkScalarListLookupTable.cpp
@@ -1,116 +1,131 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkScalarListLookupTable.h"
 #include <stdexcept>
 #include <iostream>
+#include <nlohmann/json.hpp>
+
+namespace mitk
+{
+	void to_json(nlohmann::json& j, const ScalarListLookupTable& lut)
+	{
+		j = lut.GetLookupTable();
+	}
+
+	void from_json(const nlohmann::json& j, ScalarListLookupTable& lut)
+	{
+		lut.SetLookupTable(j.get<ScalarListLookupTable::LookupTableType>());
+	}
+}
+
 const char* mitk::ScalarListLookupTable::GetNameOfClass() const
 {
 	return "ScalarListLookupTable";
 }
 
 void mitk::ScalarListLookupTable::SetTableValue(const KeyType& key, const ValueType& value)
 {
 	m_LookupTable[key] = value;
 }
 
 bool mitk::ScalarListLookupTable::ValueExists(const KeyType& key) const
 {
 	LookupTableType::const_iterator it = m_LookupTable.find(key);
 	return (it != m_LookupTable.end());
 }
 
 const mitk::ScalarListLookupTable::ValueType&
 mitk::ScalarListLookupTable::GetTableValue(const KeyType& key) const
 {
 	LookupTableType::const_iterator it = m_LookupTable.find(key);
 
 	if (it != m_LookupTable.end())
 	{
 		return it->second;
 	}
 	else
 	{
 		throw std::range_error("id does not exist in the lookup table");
 	}
 }
 
 const mitk::ScalarListLookupTable::LookupTableType&
 mitk::ScalarListLookupTable::GetLookupTable() const
 {
 	return m_LookupTable;
 }
 
 void mitk::ScalarListLookupTable::SetLookupTable(const LookupTableType& table)
 {
 	m_LookupTable = table;
 };
 
 
 bool mitk::ScalarListLookupTable::operator==(const mitk::ScalarListLookupTable& lookupTable) const
 {
 	return (m_LookupTable == lookupTable.m_LookupTable);
 }
 bool mitk::ScalarListLookupTable::operator!=(const mitk::ScalarListLookupTable& lookupTable) const
 {
 	return !(m_LookupTable == lookupTable.m_LookupTable);
 }
 
 mitk::ScalarListLookupTable&
 mitk::ScalarListLookupTable::operator=(const ScalarListLookupTable& other)
 {
 	if (this == &other)
 	{
 		return *this;
 	}
 	else
 	{
 		m_LookupTable = other.m_LookupTable;
 		return *this;
 	}
 }
 
 std::ostream& mitk::operator<<(std::ostream& stream, const ScalarListLookupTable& l)
 {
 	typedef ScalarListLookupTable::LookupTableType::const_iterator MapIterType;
 	typedef ScalarListLookupTable::ValueType::const_iterator VectorIterType;
 	MapIterType mapStart = l.GetLookupTable().begin();
 	MapIterType mapEnd = l.GetLookupTable().end();
 	stream << "[";
 
 	for (MapIterType i = mapStart; i != mapEnd; ++i)
 	{
 		if (i != mapStart)
 		{
 			stream << ", ";
 		}
 
 		stream << i->first << " -> [";
 
 		VectorIterType vectorStart = i->second.begin();
 		VectorIterType vectorEnd = i->second.end();
 
 		for (VectorIterType j = vectorStart; j != vectorEnd; ++j)
 		{
 			if (j != vectorStart)
 			{
 				stream << ", ";
 			}
 
 			stream << *j;
 		}
 
 		stream << "]";
 	}
 
 	return stream << "]";
 };
diff --git a/Modules/RT/include/mitkIsoDoseLevelSetProperty.h b/Modules/RT/include/mitkIsoDoseLevelSetProperty.h
index 32aa056beb..84bce165a9 100644
--- a/Modules/RT/include/mitkIsoDoseLevelSetProperty.h
+++ b/Modules/RT/include/mitkIsoDoseLevelSetProperty.h
@@ -1,73 +1,76 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 
 #ifndef mitkIsoDoseLevelSetProperty_h
 #define mitkIsoDoseLevelSetProperty_h
 
 #include "mitkBaseProperty.h"
 #include "mitkIsoDoseLevelCollections.h"
 #include "MitkRTExports.h"
 
 namespace mitk {
 
 /**
 \brief Property class for dose iso level sets.
 */
 class MITKRT_EXPORT IsoDoseLevelSetProperty : public BaseProperty
 {
 
 protected:
     IsoDoseLevelSet::Pointer m_IsoLevelSet;
 
     IsoDoseLevelSetProperty();
 
     explicit IsoDoseLevelSetProperty(const IsoDoseLevelSetProperty& other);
 
     explicit IsoDoseLevelSetProperty(IsoDoseLevelSet* levelSet);
 
 public:
     mitkClassMacro(IsoDoseLevelSetProperty, BaseProperty);
 
     itkNewMacro(IsoDoseLevelSetProperty);
     mitkNewMacro1Param(IsoDoseLevelSetProperty, IsoDoseLevelSet*);
 
     typedef IsoDoseLevelSet ValueType;
 
     ~IsoDoseLevelSetProperty() override;
 
     const IsoDoseLevelSet * GetIsoDoseLevelSet() const;
     const IsoDoseLevelSet * GetValue() const;
     IsoDoseLevelSet * GetIsoDoseLevelSet();
     IsoDoseLevelSet * GetValue();
 
 
     void SetIsoDoseLevelSet(IsoDoseLevelSet* levelSet);
     void SetValue(IsoDoseLevelSet* levelSet);
 
     std::string GetValueAsString() const override;
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     using BaseProperty::operator=;
 
 private:
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty& property) const override;
     bool Assign(const BaseProperty& property) override;
 
 };
 
 } // namespace mitk
 
 
 #endif
diff --git a/Modules/RT/include/mitkIsoDoseLevelVectorProperty.h b/Modules/RT/include/mitkIsoDoseLevelVectorProperty.h
index eadc300ac4..5887234c37 100644
--- a/Modules/RT/include/mitkIsoDoseLevelVectorProperty.h
+++ b/Modules/RT/include/mitkIsoDoseLevelVectorProperty.h
@@ -1,74 +1,77 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 
 #ifndef mitkIsoDoseLevelVectorProperty_h
 #define mitkIsoDoseLevelVectorProperty_h
 
 #include "mitkBaseProperty.h"
 #include "mitkIsoDoseLevelCollections.h"
 #include "MitkRTExports.h"
 
 namespace mitk {
 
 /**
 \brief Property class for dose iso level vector.
 */
 class MITKRT_EXPORT IsoDoseLevelVectorProperty : public BaseProperty
 {
 
 protected:
     IsoDoseLevelVector::Pointer m_IsoLevelVector;
 
     IsoDoseLevelVectorProperty();
 
     explicit IsoDoseLevelVectorProperty(const IsoDoseLevelVectorProperty& other);
 
     explicit IsoDoseLevelVectorProperty(IsoDoseLevelVector* levelVector);
 
 public:
     mitkClassMacro(IsoDoseLevelVectorProperty, BaseProperty);
 
     itkNewMacro(IsoDoseLevelVectorProperty);
     mitkNewMacro1Param(IsoDoseLevelVectorProperty, IsoDoseLevelVector*);
 
     typedef IsoDoseLevelVector ValueType;
 
     ~IsoDoseLevelVectorProperty() override;
 
     const IsoDoseLevelVector * GetIsoDoseLevelVector() const;
     const IsoDoseLevelVector * GetValue() const;
     IsoDoseLevelVector * GetIsoDoseLevelVector();
     IsoDoseLevelVector * GetValue();
 
 
     void SetIsoDoseLevelVector(IsoDoseLevelVector* levelVector);
     void SetValue(IsoDoseLevelVector* levelVector);
 
     std::string GetValueAsString() const override;
 
+    bool ToJSON(nlohmann::json& j) const override;
+    bool FromJSON(const nlohmann::json& j) override;
+
     using BaseProperty::operator=;
 
 private:
 
     itk::LightObject::Pointer InternalClone() const override;
 
     bool IsEqual(const BaseProperty& property) const override;
     bool Assign(const BaseProperty& property) override;
 
 };
 
 } // namespace mitk
 
 
 
 #endif
diff --git a/Modules/RT/src/mitkIsoDoseLevelSetProperty.cpp b/Modules/RT/src/mitkIsoDoseLevelSetProperty.cpp
index aa15834838..35b321b3ab 100644
--- a/Modules/RT/src/mitkIsoDoseLevelSetProperty.cpp
+++ b/Modules/RT/src/mitkIsoDoseLevelSetProperty.cpp
@@ -1,103 +1,113 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 
 #include "mitkIsoDoseLevelSetProperty.h"
 
 
 mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty()
 {
 }
 
 mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty(const mitk::IsoDoseLevelSetProperty& other)
   : BaseProperty(other)
   , m_IsoLevelSet(other.m_IsoLevelSet)
 {
 }
 
 mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty(IsoDoseLevelSet* levelSet) : m_IsoLevelSet(levelSet)
 {
 }
 
 mitk::IsoDoseLevelSetProperty::~IsoDoseLevelSetProperty()
 {
 }
 
 bool mitk::IsoDoseLevelSetProperty::IsEqual(const BaseProperty& property) const
 {
   return this->m_IsoLevelSet == static_cast<const Self&>(property).m_IsoLevelSet;
 }
 
 bool mitk::IsoDoseLevelSetProperty::Assign(const BaseProperty& property)
 {
   this->m_IsoLevelSet = static_cast<const Self&>(property).m_IsoLevelSet;
   return true;
 }
 
 const mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetIsoDoseLevelSet() const
 {
   return m_IsoLevelSet;
 }
 
 const mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetValue() const
 {
   return GetIsoDoseLevelSet();
 }
 
 mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetIsoDoseLevelSet()
 {
   return m_IsoLevelSet;
 }
 
 mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetValue()
 {
   return GetIsoDoseLevelSet();
 }
 
 
 void mitk::IsoDoseLevelSetProperty::SetIsoDoseLevelSet(IsoDoseLevelSet* levelSet)
 {
   if(m_IsoLevelSet != levelSet)
   {
     m_IsoLevelSet = levelSet;
     Modified();
   }
 }
 
 void mitk::IsoDoseLevelSetProperty::SetValue(IsoDoseLevelSet* levelSet)
 {
   SetIsoDoseLevelSet(levelSet);
 }
 
 std::string mitk::IsoDoseLevelSetProperty::GetValueAsString() const
 {
   std::stringstream myStr;
 
   myStr << "IsoDoseLevels: ";
 
   if (m_IsoLevelSet.IsNotNull())
   {
     myStr << m_IsoLevelSet->Size() << std::endl;
 
     for (IsoDoseLevelSet::ConstIterator pos = m_IsoLevelSet->Begin(); pos != m_IsoLevelSet->End(); ++pos)
     {
       myStr << "  " << 100*(pos->GetDoseValue()) << "% : ("<<pos->GetColor()<< "); iso line: " << pos->GetVisibleIsoLine() << "; color wash: "<<pos->GetVisibleColorWash() << std::endl;
     }
   }
   return myStr.str();
 }
 
+bool mitk::IsoDoseLevelSetProperty::ToJSON(nlohmann::json&) const
+{
+  return false; // Not implemented
+}
+
+bool mitk::IsoDoseLevelSetProperty::FromJSON(const nlohmann::json&)
+{
+  return false; // Not implemented
+}
+
 itk::LightObject::Pointer mitk::IsoDoseLevelSetProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   return result;
 }
diff --git a/Modules/RT/src/mitkIsoDoseLevelVectorProperty.cpp b/Modules/RT/src/mitkIsoDoseLevelVectorProperty.cpp
index 0182f7c135..808acfa397 100644
--- a/Modules/RT/src/mitkIsoDoseLevelVectorProperty.cpp
+++ b/Modules/RT/src/mitkIsoDoseLevelVectorProperty.cpp
@@ -1,103 +1,113 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 
 #include "mitkIsoDoseLevelVectorProperty.h"
 
 
 mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty()
 {
 }
 
 mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty(const mitk::IsoDoseLevelVectorProperty& other)
   : BaseProperty(other)
   , m_IsoLevelVector(other.m_IsoLevelVector)
 {
 }
 
 mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty(IsoDoseLevelVector* levelVector) : m_IsoLevelVector(levelVector)
 {
 }
 
 mitk::IsoDoseLevelVectorProperty::~IsoDoseLevelVectorProperty()
 {
 }
 
 bool mitk::IsoDoseLevelVectorProperty::IsEqual(const BaseProperty& property) const
 {
   return this->m_IsoLevelVector == static_cast<const Self&>(property).m_IsoLevelVector;
 }
 
 bool mitk::IsoDoseLevelVectorProperty::Assign(const BaseProperty& property)
 {
   this->m_IsoLevelVector = static_cast<const Self&>(property).m_IsoLevelVector;
   return true;
 }
 
 const mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetIsoDoseLevelVector() const
 {
   return m_IsoLevelVector;
 }
 
 const mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetValue() const
 {
   return GetIsoDoseLevelVector();
 }
 
 mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetIsoDoseLevelVector()
 {
   return m_IsoLevelVector;
 }
 
 mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetValue()
 {
   return GetIsoDoseLevelVector();
 }
 
 
 void mitk::IsoDoseLevelVectorProperty::SetIsoDoseLevelVector(IsoDoseLevelVector* levelVector)
 {
   if(m_IsoLevelVector != levelVector)
   {
     m_IsoLevelVector = levelVector;
     Modified();
   }
 }
 
 void mitk::IsoDoseLevelVectorProperty::SetValue(IsoDoseLevelVector* levelVector)
 {
   SetIsoDoseLevelVector(levelVector);
 }
 
 std::string mitk::IsoDoseLevelVectorProperty::GetValueAsString() const
 {
   std::stringstream myStr;
 
   myStr << "IsoDoseLevels: ";
 
   if (m_IsoLevelVector.IsNotNull())
   {
     myStr << m_IsoLevelVector->Size() << std::endl;
 
     for (IsoDoseLevelVector::ConstIterator pos = m_IsoLevelVector->Begin(); pos != m_IsoLevelVector->End(); ++pos)
     {
       myStr << "  " << 100*(pos->Value()->GetDoseValue()) << "% : ("<<pos->Value()->GetColor()<< "); iso line: " << pos->Value()->GetVisibleIsoLine() << std::endl;
     }
   }
   return myStr.str();
 }
 
+bool mitk::IsoDoseLevelVectorProperty::ToJSON(nlohmann::json&) const
+{
+  return false; // Not implemented
+}
+
+bool mitk::IsoDoseLevelVectorProperty::FromJSON(const nlohmann::json&)
+{
+  return false; // Not implemented
+}
+
 itk::LightObject::Pointer mitk::IsoDoseLevelVectorProperty::InternalClone() const
 {
   itk::LightObject::Pointer result(new Self(*this));
   return result;
 }