diff --git a/Modules/Core/include/mitkDataNode.h b/Modules/Core/include/mitkDataNode.h
index 1b25ca2f6c..ec70738850 100644
--- a/Modules/Core/include/mitkDataNode.h
+++ b/Modules/Core/include/mitkDataNode.h
@@ -1,597 +1,601 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center,
 Division of Medical and Biological Informatics.
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #ifndef DATATREENODE_H_HEADER_INCLUDED_C1E14338
 #define DATATREENODE_H_HEADER_INCLUDED_C1E14338
 
 #include "mitkBaseData.h"
 //#include "mitkMapper.h"
 #include "mitkDataInteractor.h"
+#include "mitkIIdentifiable.h"
 
 #ifdef MBI_NO_STD_NAMESPACE
 #define MBI_STD
 #include <fstream.h>
 #include <iostream.h>
 #else
 #define MBI_STD std
 #include <fstream>
 #include <iostream>
 #endif
 
 #include "mitkColorProperty.h"
 #include "mitkPropertyList.h"
 #include "mitkStringProperty.h"
 //#include "mitkMapper.h"
 
 #include "mitkGeometry3D.h"
 #include "mitkLevelWindow.h"
 #include <map>
 #include <set>
 
 class vtkLinearTransform;
 
 namespace mitk
 {
   class BaseRenderer;
   class Mapper;
 
   /**
    * \brief Class for nodes of the DataTree
    *
    * Contains the data (instance of BaseData), a list of mappers, which can
    * draw the data, a transform (vtkTransform) and a list of properties
    * (PropertyList).
    * \ingroup DataManagement
    *
    * \todo clean up all the GetProperty methods. There are too many different flavours... Can most probably be reduced
    * to
    * <tt>bool GetProperty<type>(type&)</tt>
    *
    * \warning Change in semantics of SetProperty() since Aug 25th 2006. Check your usage of this method if you do
    *          more with properties than just call <tt>SetProperty( "key", new SomeProperty("value") )</tt>.
    */
-  class MITKCORE_EXPORT DataNode : public itk::DataObject
+  class MITKCORE_EXPORT DataNode : public itk::DataObject, public IIdentifiable
   {
   public:
     typedef mitk::Geometry3D::Pointer Geometry3DPointer;
     typedef std::vector<itk::SmartPointer<Mapper>> MapperVector;
     typedef std::map<std::string, mitk::PropertyList::Pointer> MapOfPropertyLists;
     typedef std::vector<MapOfPropertyLists::key_type> PropertyListKeyNames;
     typedef std::set<std::string> GroupTagList;
 
     /**
      * \brief Definition of an itk::Event that is invoked when
      * a DataInteractor is set on this DataNode.
      */
     itkEventMacro(InteractorChangedEvent, itk::AnyEvent);
 
     mitkClassMacroItkParent(DataNode, itk::DataObject);
 
     itkFactorylessNewMacro(Self) itkCloneMacro(Self)
 
       mitk::Mapper *GetMapper(MapperSlotId id) const;
 
     /**
      * \brief Get the data object (instance of BaseData, e.g., an Image)
      * managed by this DataNode
      */
     BaseData *GetData() const;
 
     /**
      * \brief Get the transformation applied prior to displaying the data as
      * a vtkTransform
      * \deprecated use GetData()->GetGeometry()->GetVtkTransform() instead
      */
     vtkLinearTransform *GetVtkTransform(int t = 0) const;
 
     /**
      * \brief Set the data object (instance of BaseData, e.g., an Image)
      * managed by this DataNode
      *
      * Prior set properties are kept if previous data of the node already exists and has the same
      * type as the new data to be set. Otherwise, the default properties are used.
      * In case that previous data already exists, the property list of the data node is cleared
      * before setting new default properties.
      *
      * \warning the actor-mode of the vtkInteractor does not work any more, if the transform of the
      * data-tree-node is connected to the transform of the basedata via vtkTransform->SetInput.
      */
     virtual void SetData(mitk::BaseData *baseData);
 
     /**
      * \brief Set the Interactor.
      */
     virtual void SetDataInteractor(const DataInteractor::Pointer interactor);
     virtual DataInteractor::Pointer GetDataInteractor() const;
 
     mitk::DataNode &operator=(const DataNode &right);
 
     mitk::DataNode &operator=(BaseData *right);
     virtual void SetMapper(MapperSlotId id, mitk::Mapper *mapper);
     virtual void UpdateOutputInformation() override;
 
     virtual void SetRequestedRegionToLargestPossibleRegion() override;
 
     virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() override;
 
     virtual bool VerifyRequestedRegion() override;
 
     virtual void SetRequestedRegion(const itk::DataObject *data) override;
 
     virtual void CopyInformation(const itk::DataObject *data) override;
 
     /**
      * \brief The "names" used for (renderer-specific) PropertyLists in GetPropertyList(string).
      *
      * All possible values for the "renderer" parameters of
      * the diverse GetProperty/List() methods.
      */
     PropertyListKeyNames GetPropertyListNames() const;
 
     /**
      * \brief Set the property (instance of BaseProperty) with key \a propertyKey in the PropertyList
      * of the \a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-value.
      *
      * \warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do
      *          more with properties than just call <tt>SetProperty( "key", new SomeProperty("value") )</tt>.
      *
      * \sa GetProperty
      * \sa m_PropertyList
      * \sa m_MapOfPropertyLists
      */
     void SetProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief Replace the property (instance of BaseProperty) with key \a propertyKey in the PropertyList
      * of the \a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-reference.
      *
      * If \a renderer is \a nullptr the property is set in the BaseRenderer-independent
      * PropertyList of this DataNode.
      * \sa GetProperty
      * \sa m_PropertyList
      * \sa m_MapOfPropertyLists
      */
     void ReplaceProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief Add the property (instance of BaseProperty) if it does
      * not exist (or always if\a overwrite is\a true)
      * with key \a propertyKey in the PropertyList
      * of the \a renderer (if nullptr, use BaseRenderer-independent
      * PropertyList). This is set-by-value.
      *
      * For\a overwrite ==\a false the property is\em not changed
      * if it already exists. For\a overwrite ==\a true the method
      * is identical to SetProperty.
      *
      * \sa SetProperty
      * \sa GetProperty
      * \sa m_PropertyList
      * \sa m_MapOfPropertyLists
      */
     void AddProperty(const char *propertyKey,
                      BaseProperty *property,
                      const mitk::BaseRenderer *renderer = nullptr,
                      bool overwrite = false);
 
     /**
      * \brief Get the PropertyList of the \a renderer. If \a renderer is \a
      * nullptr, the BaseRenderer-independent PropertyList of this DataNode
      * is returned.
      * \sa GetProperty
      * \sa m_PropertyList
      * \sa m_MapOfPropertyLists
      */
     mitk::PropertyList *GetPropertyList(const mitk::BaseRenderer *renderer = nullptr) const;
     mitk::PropertyList *GetPropertyList(const std::string &rendererName) const;
 
     /**
      * \brief Add values from another PropertyList.
      *
      * Overwrites values in m_PropertyList only when possible (i.e. when types are compatible).
      * If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty,
      * set the \param replace.
      *
      * \param replace true: if \param pList contains a property "visible" of type ColorProperty and our m_PropertyList
      * also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects
      * behind the pointer.
      *
      * \sa SetProperty
      * \sa ReplaceProperty
      * \sa m_PropertyList
      */
     void ConcatenatePropertyList(PropertyList *pList, bool replace = false);
 
     /**
      * \brief Get the property (instance of BaseProperty) with key \a propertyKey from the PropertyList
      * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
      *
      * If \a renderer is \a nullptr or the \a propertyKey cannot be found
      * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent
      * PropertyList of this DataNode is queried.
      * \sa GetPropertyList
      * \sa m_PropertyList
      * \sa m_MapOfPropertyLists
      */
     mitk::BaseProperty *GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr) const;
 
     /**
      * \brief Get the property of type T with key \a propertyKey from the PropertyList
      * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
      *
      * If \a renderer is \a nullptr or the \a propertyKey cannot be found
      * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent
      * PropertyList of this DataNode is queried.
      * \sa GetPropertyList
      * \sa m_PropertyList
      * \sa m_MapOfPropertyLists
      */
     template <typename T>
     bool GetProperty(itk::SmartPointer<T> &property,
                      const char *propertyKey,
                      const mitk::BaseRenderer *renderer = nullptr) const
     {
       property = dynamic_cast<T *>(GetProperty(propertyKey, renderer));
       return property.IsNotNull();
     }
 
     /**
      * \brief Get the property of type T with key \a propertyKey from the PropertyList
      * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
      *
      * If \a renderer is \a nullptr or the \a propertyKey cannot be found
      * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent
      * PropertyList of this DataNode is queried.
      * \sa GetPropertyList
      * \sa m_PropertyList
      * \sa m_MapOfPropertyLists
      */
     template <typename T>
     bool GetProperty(T *&property, const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr) const
     {
       property = dynamic_cast<T *>(GetProperty(propertyKey, renderer));
       return property != nullptr;
     }
 
     /**
      * \brief Convenience access method for GenericProperty<T> properties
      * (T being the type of the second parameter)
      * \return \a true property was found
      */
     template <typename T>
     bool GetPropertyValue(const char *propertyKey, T &value, const mitk::BaseRenderer *renderer = nullptr) const
     {
       GenericProperty<T> *gp = dynamic_cast<GenericProperty<T> *>(GetProperty(propertyKey, renderer));
       if (gp != nullptr)
       {
         value = gp->GetValue();
         return true;
       }
       return false;
     }
 
     /// \brief Get a set of all group tags from this node's property list
     GroupTagList GetGroupTags() const;
 
     /**
      * \brief Convenience access method for bool properties (instances of
      * BoolProperty)
      * \return \a true property was found
      */
     bool GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer = nullptr) const;
 
     /**
      * \brief Convenience access method for int properties (instances of
      * IntProperty)
      * \return \a true property was found
      */
     bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer = nullptr) const;
 
     /**
      * \brief Convenience access method for float properties (instances of
      * FloatProperty)
      * \return \a true property was found
      */
     bool GetFloatProperty(const char *propertyKey,
                           float &floatValue,
                           const mitk::BaseRenderer *renderer = nullptr) const;
 
     /**
      * \brief Convenience access method for double properties (instances of
      * DoubleProperty)
      *
      * If there is no DoubleProperty for the given\c propertyKey argument, the method
      * looks for a corresponding FloatProperty instance.
      *
      * \return \a true property was found
      */
     bool GetDoubleProperty(const char *propertyKey,
                            double &doubleValue,
                            const mitk::BaseRenderer *renderer = nullptr) const;
 
     /**
      * \brief Convenience access method for string properties (instances of
      * StringProperty)
      * \return \a true property was found
      */
     bool GetStringProperty(const char *propertyKey,
                            std::string &string,
                            const mitk::BaseRenderer *renderer = nullptr) const;
 
     /**
      * \brief Convenience access method for color properties (instances of
      * ColorProperty)
      * \return \a true property was found
      */
     bool GetColor(float rgb[3], const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color") const;
 
     /**
      * \brief Convenience access method for level-window properties (instances of
      * LevelWindowProperty)
      * \return \a true property was found
      */
     bool GetLevelWindow(mitk::LevelWindow &levelWindow,
                         const mitk::BaseRenderer *renderer = nullptr,
                         const char *propertyKey = "levelwindow") const;
 
     /**
      * \brief set the node as selected
      */
     void SetSelected(bool selected, const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief set the node as selected
      * \return \a true node is selected
      */
     bool IsSelected(const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief Convenience access method for accessing the name of an object (instance of
      * StringProperty with property-key "name")
      * \return \a true property was found
      */
     bool GetName(std::string &nodeName,
                  const mitk::BaseRenderer *renderer = nullptr,
                  const char *propertyKey = "name") const
     {
       return GetStringProperty(propertyKey, nodeName, renderer);
     }
 
     /**
      * \brief Extra convenience access method for accessing the name of an object (instance of
      * StringProperty with property-key "name").
      *
      * This method does not take the renderer specific
      * propertylists into account, because the name of an object should never be renderer specific.
      * \returns a std::string with the name of the object (content of "name" Property).
      * If there is no "name" Property, an empty string will be returned.
      */
     virtual std::string GetName() const
     {
       mitk::StringProperty *sp = dynamic_cast<mitk::StringProperty *>(this->GetProperty("name"));
       if (sp == nullptr)
         return "";
       return sp->GetValue();
     }
 
     /**
      * \brief Extra convenience access method to set the name of an object.
      *
      * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name".
      */
     virtual void SetName(const char *name)
     {
       if (name == nullptr)
         return;
       this->SetProperty("name", StringProperty::New(name));
     }
     /**
      * \brief Extra convenience access method to set the name of an object.
      *
      * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name".
      */
     virtual void SetName(const std::string name) { this->SetName(name.c_str()); }
     /**
      * \brief Convenience access method for visibility properties (instances
      * of BoolProperty with property-key "visible")
      * \return \a true property was found
      * \sa IsVisible
      */
     bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey = "visible") const
     {
       return GetBoolProperty(propertyKey, visible, renderer);
     }
 
     /**
      * \brief Convenience access method for opacity properties (instances of
      * FloatProperty)
      * \return \a true property was found
      */
     bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey = "opacity") const;
 
     /**
      * \brief Convenience access method for boolean properties (instances
      * of BoolProperty). Return value is the value of the property. If the property is
      * not found, the value of \a defaultIsOn is returned.
      *
      * Thus, the return value has a different meaning than in the
      * GetBoolProperty method!
      * \sa GetBoolProperty
      */
     bool IsOn(const char *propertyKey, const mitk::BaseRenderer *renderer, bool defaultIsOn = true) const
     {
       if (propertyKey == nullptr)
         return defaultIsOn;
       GetBoolProperty(propertyKey, defaultIsOn, renderer);
       return defaultIsOn;
     }
 
     /**
      * \brief Convenience access method for visibility properties (instances
      * of BoolProperty). Return value is the visibility. Default is
      * visible==true, i.e., true is returned even if the property (\a
      * propertyKey) is not found.
      *
      * Thus, the return value has a different meaning than in the
      * GetVisibility method!
      * \sa GetVisibility
      * \sa IsOn
      */
     bool IsVisible(const mitk::BaseRenderer *renderer,
                    const char *propertyKey = "visible",
                    bool defaultIsOn = true) const
     {
       return IsOn(propertyKey, renderer, defaultIsOn);
     }
 
     /**
      * \brief Convenience method for setting color properties (instances of
      * ColorProperty)
      */
     void SetColor(const mitk::Color &color,
                   const mitk::BaseRenderer *renderer = nullptr,
                   const char *propertyKey = "color");
 
     /**
      * \brief Convenience method for setting color properties (instances of
      * ColorProperty)
      */
     void SetColor(float red,
                   float green,
                   float blue,
                   const mitk::BaseRenderer *renderer = nullptr,
                   const char *propertyKey = "color");
 
     /**
      * \brief Convenience method for setting color properties (instances of
      * ColorProperty)
      */
     void SetColor(const float rgb[3], const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color");
 
     /**
      * \brief Convenience method for setting visibility properties (instances
      * of BoolProperty)
      * \param visible If set to true, the data will be rendered. If false, the render will skip this data.
      * \param renderer Specify a renderer if the visibility shall be specific to a renderer
      * \param propertykey Can be used to specify a user defined name of the visibility propery.
      */
     void SetVisibility(bool visible, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "visible");
 
     /**
      * \brief Convenience method for setting opacity properties (instances of
      * FloatProperty)
      */
     void SetOpacity(float opacity, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "opacity");
 
     /**
      * \brief Convenience method for setting level-window properties
      * (instances of LevelWindowProperty)
      */
     void SetLevelWindow(mitk::LevelWindow levelWindow,
                         const mitk::BaseRenderer *renderer = nullptr,
                         const char *propertyKey = "levelwindow");
 
     /**
      * \brief Convenience method for setting int properties (instances of
      * IntProperty)
      */
     void SetIntProperty(const char *propertyKey, int intValue, const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief Convenience method for setting boolean properties (instances of
      * BoolProperty)
      */
     void SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief Convenience method for setting float properties (instances of
      * FloatProperty)
      */
     void SetFloatProperty(const char *propertyKey, float floatValue, const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief Convenience method for setting double properties (instances of
      * DoubleProperty)
      */
     void SetDoubleProperty(const char *propertyKey, double doubleValue, const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief Convenience method for setting string properties (instances of
      * StringProperty)
      */
     void SetStringProperty(const char *propertyKey, const char *string, const mitk::BaseRenderer *renderer = nullptr);
 
     /**
      * \brief Get the timestamp of the last change of the contents of this node or
      * the referenced BaseData.
      */
     virtual unsigned long GetMTime() const override;
 
     /**
      * \brief Get the timestamp of the last change of the reference to the
      * BaseData.
      */
     unsigned long GetDataReferenceChangedTime() const { return m_DataReferenceChangedTime.GetMTime(); }
+
+    virtual UIDType GetUID() const override;
+
   protected:
     DataNode();
 
     virtual ~DataNode();
 
     /// Invoked when the property list was modified. Calls Modified() of the DataNode
     virtual void PropertyListModified(const itk::Object *caller, const itk::EventObject &event);
 
     /// \brief Mapper-slots
     mutable MapperVector m_Mappers;
 
     /**
      * \brief The data object (instance of BaseData, e.g., an Image) managed
      * by this DataNode
      */
     BaseData::Pointer m_Data;
 
     /**
      * \brief BaseRenderer-independent PropertyList
      *
      * Properties herein can be overwritten specifically for each BaseRenderer
      * by the BaseRenderer-specific properties defined in m_MapOfPropertyLists.
      */
     PropertyList::Pointer m_PropertyList;
 
     /// \brief Map associating each BaseRenderer with its own PropertyList
     mutable MapOfPropertyLists m_MapOfPropertyLists;
 
     DataInteractor::Pointer m_DataInteractor;
 
     /// \brief Timestamp of the last change of m_Data
     itk::TimeStamp m_DataReferenceChangedTime;
 
     unsigned long m_PropertyListModifiedObserverTag;
   };
 
 #if (_MSC_VER > 1200) || !defined(_MSC_VER)
   MITKCORE_EXPORT MBI_STD::istream &operator>>(MBI_STD::istream &i, DataNode::Pointer &dtn);
 
   MITKCORE_EXPORT MBI_STD::ostream &operator<<(MBI_STD::ostream &o, DataNode::Pointer &dtn);
 #endif
 } // namespace mitk
 
 #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
 MITKCORE_EXPORT MBI_STD::istream &operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn);
 
 MITKCORE_EXPORT MBI_STD::ostream &operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn);
 #endif
 
 #endif /* DATATREENODE_H_HEADER_INCLUDED_C1E14338 */
diff --git a/Modules/Core/src/DataManagement/mitkDataNode.cpp b/Modules/Core/src/DataManagement/mitkDataNode.cpp
index 0105ad141a..cc53e606f6 100644
--- a/Modules/Core/src/DataManagement/mitkDataNode.cpp
+++ b/Modules/Core/src/DataManagement/mitkDataNode.cpp
@@ -1,599 +1,612 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center,
 Division of Medical and Biological Informatics.
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include "mitkDataNode.h"
 #include "mitkCoreObjectFactory.h"
 #include <vtkTransform.h>
 
 #include "mitkGroupTagProperty.h"
 #include "mitkProperties.h"
 #include "mitkSmartPointerProperty.h"
 #include "mitkStringProperty.h"
 //#include "mitkMaterialProperty.h"
 #include "mitkColorProperty.h"
 #include "mitkCoreObjectFactory.h"
 #include "mitkGenericProperty.h"
 #include "mitkGeometry3D.h"
 #include "mitkImageSource.h"
 #include "mitkLevelWindowProperty.h"
 #include "mitkRenderingManager.h"
+#include <mitkUIDGenerator.h>
 
 mitk::Mapper *mitk::DataNode::GetMapper(MapperSlotId id) const
 {
   if ((id >= m_Mappers.size()) || (m_Mappers[id].IsNull()))
   {
     if (id >= m_Mappers.capacity())
     {
       //      int i, size=id-m_Mappers.capacity()+10;
       m_Mappers.resize(id + 10);
     }
     m_Mappers[id] = CoreObjectFactory::GetInstance()->CreateMapper(const_cast<DataNode *>(this), id);
   }
   return m_Mappers[id];
 }
 
 mitk::BaseData *mitk::DataNode::GetData() const
 {
   return m_Data;
 }
 
 void mitk::DataNode::SetData(mitk::BaseData *baseData)
 {
   if (m_Data != baseData)
   {
     m_Mappers.clear();
     m_Mappers.resize(10);
 
     if (m_Data.IsNotNull() && baseData != nullptr)
     {
       // Do previous and new data have same type? Keep existing properties.
       if (0 == strcmp(m_Data->GetNameOfClass(), baseData->GetNameOfClass()))
       {
         m_Data = baseData;
       }
       else
       {
         m_Data = baseData;
         this->GetPropertyList()->Clear();
         mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this);
       }
     }
     else
     {
       m_Data = baseData;
       mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this);
     }
 
     m_DataReferenceChangedTime.Modified();
     Modified();
   }
 }
 
-mitk::DataNode::DataNode() : m_PropertyListModifiedObserverTag(0)
+mitk::DataNode::DataNode()
+  : m_PropertyListModifiedObserverTag(0),
+    m_PropertyList(PropertyList::New())
 {
   m_Mappers.resize(10);
 
-  m_PropertyList = PropertyList::New();
+  UIDGenerator generator;
+  this->SetProperty("uid", StringProperty::New(generator.GetUID()));
 
   // subscribe for modified event
   itk::MemberCommand<mitk::DataNode>::Pointer _PropertyListModifiedCommand = itk::MemberCommand<mitk::DataNode>::New();
   _PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::DataNode::PropertyListModified);
   m_PropertyListModifiedObserverTag = m_PropertyList->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand);
 }
 
 mitk::DataNode::~DataNode()
 {
   if (m_PropertyList.IsNotNull())
     m_PropertyList->RemoveObserver(m_PropertyListModifiedObserverTag);
 
   m_Mappers.clear();
   m_Data = nullptr;
 }
 
 mitk::DataNode &mitk::DataNode::operator=(const DataNode &right)
 {
   mitk::DataNode *node = mitk::DataNode::New();
   node->SetData(right.GetData());
   return *node;
 }
 
 mitk::DataNode &mitk::DataNode::operator=(mitk::BaseData *right)
 {
   mitk::DataNode *node = mitk::DataNode::New();
   node->SetData(right);
   return *node;
 }
 
 #if (_MSC_VER > 1200) || !defined(_MSC_VER)
 MBI_STD::istream &mitk::operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn)
 #endif
 #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
   MBI_STD::istream &
   operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn)
 #endif
 {
   dtn = mitk::DataNode::New();
   // i >> av.get();
   return i;
 }
 
 #if (_MSC_VER > 1200) || !defined(_MSC_VER)
 MBI_STD::ostream &mitk::operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn)
 #endif
 #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
   MBI_STD::ostream &
   operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn)
 #endif
 {
   if (dtn->GetData() != nullptr)
     o << dtn->GetData()->GetNameOfClass();
   else
     o << "empty data";
   return o;
 }
 
 void mitk::DataNode::SetMapper(MapperSlotId id, mitk::Mapper *mapper)
 {
   m_Mappers[id] = mapper;
 
   if (mapper != nullptr)
     mapper->SetDataNode(this);
 }
 
 void mitk::DataNode::UpdateOutputInformation()
 {
   if (this->GetSource())
   {
     this->GetSource()->UpdateOutputInformation();
   }
 }
 
 void mitk::DataNode::SetRequestedRegionToLargestPossibleRegion()
 {
 }
 
 bool mitk::DataNode::RequestedRegionIsOutsideOfTheBufferedRegion()
 {
   return false;
 }
 
 bool mitk::DataNode::VerifyRequestedRegion()
 {
   return true;
 }
 
 void mitk::DataNode::SetRequestedRegion(const itk::DataObject * /*data*/)
 {
 }
 
 mitk::DataNode::PropertyListKeyNames mitk::DataNode::GetPropertyListNames() const
 {
   PropertyListKeyNames result;
 
   for (auto entries : m_MapOfPropertyLists)
     result.push_back(entries.first);
 
   return result;
 }
 
 void mitk::DataNode::CopyInformation(const itk::DataObject * /*data*/)
 {
 }
 mitk::PropertyList *mitk::DataNode::GetPropertyList(const mitk::BaseRenderer *renderer) const
 {
   if (renderer == nullptr)
     return m_PropertyList;
 
   return this->GetPropertyList(renderer->GetName());
 }
 
 mitk::PropertyList *mitk::DataNode::GetPropertyList(const std::string &rendererName) const
 {
   if (rendererName.empty())
     return m_PropertyList;
 
   mitk::PropertyList::Pointer &propertyList = m_MapOfPropertyLists[rendererName];
 
   if (propertyList.IsNull())
     propertyList = mitk::PropertyList::New();
 
   assert(m_MapOfPropertyLists[rendererName].IsNotNull());
 
   return propertyList;
 }
 
 void mitk::DataNode::ConcatenatePropertyList(PropertyList *pList, bool replace)
 {
   m_PropertyList->ConcatenatePropertyList(pList, replace);
 }
 
 mitk::BaseProperty *mitk::DataNode::GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer) const
 {
   if (propertyKey == nullptr)
     return nullptr;
 
   // renderer specified?
   if (renderer)
   {
     std::string rendererName = renderer->GetName();
 
     MapOfPropertyLists::const_iterator it;
     // check for the renderer specific property
     it = m_MapOfPropertyLists.find(rendererName);
     if (it != m_MapOfPropertyLists.end()) // found
     {
       mitk::BaseProperty::Pointer property;
       property = it->second->GetProperty(propertyKey);
       if (property.IsNotNull()) // found an enabled property in the render specific list
         return property;
       else                                               // found a renderer specific list, but not the desired property
         return m_PropertyList->GetProperty(propertyKey); // return renderer unspecific property
     }
     else // didn't find the property list of the given renderer
     {
       // return the renderer unspecific property if there is one
       return m_PropertyList->GetProperty(propertyKey);
     }
   }
   else // no specific renderer given; use the renderer independent one
   {
     mitk::BaseProperty::Pointer property;
     property = m_PropertyList->GetProperty(propertyKey);
     if (property.IsNotNull())
       return property;
   }
 
   // only to satisfy compiler!
   return nullptr;
 }
 
 mitk::DataNode::GroupTagList mitk::DataNode::GetGroupTags() const
 {
   GroupTagList groups;
   const PropertyList::PropertyMap *propertyMap = m_PropertyList->GetMap();
 
   for (auto groupIter =
          propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here
        groupIter != propertyMap->end();
        ++groupIter)
   {
     const BaseProperty *bp = groupIter->second;
     if (dynamic_cast<const GroupTagProperty *>(bp))
     {
       groups.insert(groupIter->first);
     }
   }
 
   return groups;
 }
 
 bool mitk::DataNode::GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer) const
 {
   mitk::BoolProperty::Pointer boolprop = dynamic_cast<mitk::BoolProperty *>(GetProperty(propertyKey, renderer));
   if (boolprop.IsNull())
     return false;
 
   boolValue = boolprop->GetValue();
   return true;
 }
 
 bool mitk::DataNode::GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer) const
 {
   mitk::IntProperty::Pointer intprop = dynamic_cast<mitk::IntProperty *>(GetProperty(propertyKey, renderer));
   if (intprop.IsNull())
     return false;
 
   intValue = intprop->GetValue();
   return true;
 }
 
 bool mitk::DataNode::GetFloatProperty(const char *propertyKey,
                                       float &floatValue,
                                       const mitk::BaseRenderer *renderer) const
 {
   mitk::FloatProperty::Pointer floatprop = dynamic_cast<mitk::FloatProperty *>(GetProperty(propertyKey, renderer));
   if (floatprop.IsNull())
     return false;
 
   floatValue = floatprop->GetValue();
   return true;
 }
 
 bool mitk::DataNode::GetDoubleProperty(const char *propertyKey,
                                        double &doubleValue,
                                        const mitk::BaseRenderer *renderer) const
 {
   mitk::DoubleProperty::Pointer doubleprop = dynamic_cast<mitk::DoubleProperty *>(GetProperty(propertyKey, renderer));
   if (doubleprop.IsNull())
   {
     // try float instead
     float floatValue = 0;
     if (this->GetFloatProperty(propertyKey, floatValue, renderer))
     {
       doubleValue = floatValue;
       return true;
     }
     return false;
   }
 
   doubleValue = doubleprop->GetValue();
   return true;
 }
 
 bool mitk::DataNode::GetStringProperty(const char *propertyKey,
                                        std::string &string,
                                        const mitk::BaseRenderer *renderer) const
 {
   mitk::StringProperty::Pointer stringProp = dynamic_cast<mitk::StringProperty *>(GetProperty(propertyKey, renderer));
   if (stringProp.IsNull())
   {
     return false;
   }
   else
   {
     // memcpy((void*)string, stringProp->GetValue(), strlen(stringProp->GetValue()) + 1 ); // looks dangerous
     string = stringProp->GetValue();
     return true;
   }
 }
 
 bool mitk::DataNode::GetColor(float rgb[3], const mitk::BaseRenderer *renderer, const char *propertyKey) const
 {
   mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty *>(GetProperty(propertyKey, renderer));
   if (colorprop.IsNull())
     return false;
 
   memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3 * sizeof(float));
   return true;
 }
 
 bool mitk::DataNode::GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey) const
 {
   mitk::FloatProperty::Pointer opacityprop = dynamic_cast<mitk::FloatProperty *>(GetProperty(propertyKey, renderer));
   if (opacityprop.IsNull())
     return false;
 
   opacity = opacityprop->GetValue();
   return true;
 }
 
 bool mitk::DataNode::GetLevelWindow(mitk::LevelWindow &levelWindow,
                                     const mitk::BaseRenderer *renderer,
                                     const char *propertyKey) const
 {
   mitk::LevelWindowProperty::Pointer levWinProp =
     dynamic_cast<mitk::LevelWindowProperty *>(GetProperty(propertyKey, renderer));
   if (levWinProp.IsNull())
     return false;
 
   levelWindow = levWinProp->GetLevelWindow();
   return true;
 }
 
 void mitk::DataNode::SetColor(const mitk::Color &color, const mitk::BaseRenderer *renderer, const char *propertyKey)
 {
   mitk::ColorProperty::Pointer prop;
   prop = mitk::ColorProperty::New(color);
   GetPropertyList(renderer)->SetProperty(propertyKey, prop);
 }
 
 void mitk::DataNode::SetColor(
   float red, float green, float blue, const mitk::BaseRenderer *renderer, const char *propertyKey)
 {
   float color[3];
   color[0] = red;
   color[1] = green;
   color[2] = blue;
   SetColor(color, renderer, propertyKey);
 }
 
 void mitk::DataNode::SetColor(const float rgb[3], const mitk::BaseRenderer *renderer, const char *propertyKey)
 {
   mitk::ColorProperty::Pointer prop;
   prop = mitk::ColorProperty::New(rgb);
   GetPropertyList(renderer)->SetProperty(propertyKey, prop);
 }
 
 void mitk::DataNode::SetVisibility(bool visible, const mitk::BaseRenderer *renderer, const char *propertyKey)
 {
   mitk::BoolProperty::Pointer prop;
   prop = mitk::BoolProperty::New(visible);
   GetPropertyList(renderer)->SetProperty(propertyKey, prop);
 }
 
 void mitk::DataNode::SetOpacity(float opacity, const mitk::BaseRenderer *renderer, const char *propertyKey)
 {
   mitk::FloatProperty::Pointer prop;
   prop = mitk::FloatProperty::New(opacity);
   GetPropertyList(renderer)->SetProperty(propertyKey, prop);
 }
 
 void mitk::DataNode::SetLevelWindow(mitk::LevelWindow levelWindow,
                                     const mitk::BaseRenderer *renderer,
                                     const char *propertyKey)
 {
   mitk::LevelWindowProperty::Pointer prop;
   prop = mitk::LevelWindowProperty::New(levelWindow);
   GetPropertyList(renderer)->SetProperty(propertyKey, prop);
 }
 
 void mitk::DataNode::SetIntProperty(const char *propertyKey, int intValue, const mitk::BaseRenderer *renderer)
 {
   GetPropertyList(renderer)->SetProperty(propertyKey, mitk::IntProperty::New(intValue));
 }
 void mitk::DataNode::SetBoolProperty(const char *propertyKey,
                                      bool boolValue,
                                      const mitk::BaseRenderer *renderer /*=nullptr*/)
 {
   GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue));
 }
 
 void mitk::DataNode::SetFloatProperty(const char *propertyKey,
                                       float floatValue,
                                       const mitk::BaseRenderer *renderer /*=nullptr*/)
 {
   if (dynamic_cast<DoubleProperty *>(this->GetProperty(propertyKey, renderer)) != nullptr)
   {
     MITK_WARN << "Setting float property " << propertyKey
               << " although a double property with the same name already exists";
   }
   GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue));
 }
 
 void mitk::DataNode::SetDoubleProperty(const char *propertyKey, double doubleValue, const mitk::BaseRenderer *renderer)
 {
   if (dynamic_cast<FloatProperty *>(this->GetProperty(propertyKey, renderer)) != nullptr)
   {
     MITK_WARN << "Setting double property " << propertyKey
               << " although a float property with the same name already exists";
   }
   GetPropertyList(renderer)->SetProperty(propertyKey, mitk::DoubleProperty::New(doubleValue));
 }
 
 void mitk::DataNode::SetStringProperty(const char *propertyKey,
                                        const char *stringValue,
                                        const mitk::BaseRenderer *renderer /*=nullptr*/)
 {
   GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue));
 }
 
 void mitk::DataNode::SetProperty(const char *propertyKey,
                                  BaseProperty *propertyValue,
                                  const mitk::BaseRenderer *renderer)
 {
   GetPropertyList(renderer)->SetProperty(propertyKey, propertyValue);
 }
 
 void mitk::DataNode::ReplaceProperty(const char *propertyKey,
                                      BaseProperty *propertyValue,
                                      const mitk::BaseRenderer *renderer)
 {
   GetPropertyList(renderer)->ReplaceProperty(propertyKey, propertyValue);
 }
 
 void mitk::DataNode::AddProperty(const char *propertyKey,
                                  BaseProperty *propertyValue,
                                  const mitk::BaseRenderer *renderer,
                                  bool overwrite)
 {
   if ((overwrite) || (GetProperty(propertyKey, renderer) == nullptr))
   {
     SetProperty(propertyKey, propertyValue, renderer);
   }
 }
 
 vtkLinearTransform *mitk::DataNode::GetVtkTransform(int t) const
 {
   assert(m_Data.IsNotNull());
 
   mitk::BaseGeometry *geometry = m_Data->GetGeometry(t);
 
   if (geometry == nullptr)
     return nullptr;
 
   return geometry->GetVtkTransform();
 }
 
 unsigned long mitk::DataNode::GetMTime() const
 {
   unsigned long time = Superclass::GetMTime();
   if (m_Data.IsNotNull())
   {
     if ((time < m_Data->GetMTime()) || ((m_Data->GetSource().IsNotNull()) && (time < m_Data->GetSource()->GetMTime())))
     {
       Modified();
       return Superclass::GetMTime();
     }
   }
   return time;
 }
 
 void mitk::DataNode::SetSelected(bool selected, const mitk::BaseRenderer *renderer)
 {
   mitk::BoolProperty::Pointer selectedProperty = dynamic_cast<mitk::BoolProperty *>(GetProperty("selected"));
 
   if (selectedProperty.IsNull())
   {
     selectedProperty = mitk::BoolProperty::New();
     selectedProperty->SetValue(false);
     SetProperty("selected", selectedProperty, renderer);
   }
 
   if (selectedProperty->GetValue() != selected)
   {
     selectedProperty->SetValue(selected);
     itk::ModifiedEvent event;
     InvokeEvent(event);
   }
 }
 
 /*
 class SelectedEvent : public itk::ModifiedEvent
 {
 public:
   typedef SelectedEvent Self;
   typedef itk::ModifiedEvent Superclass;
 
   SelectedEvent(DataNode* dataNode)
     { m_DataNode = dataNode; };
   DataNode* GetDataNode()
     { return m_DataNode; };
   virtual const char * GetEventName() const
     { return "SelectedEvent"; }
   virtual bool CheckEvent(const ::itk::EventObject* e) const
     { return dynamic_cast<const Self*>(e); }
   virtual ::itk::EventObject* MakeObject() const
     { return new Self(m_DataNode); }
 private:
   DataNode* m_DataNode;
   SelectedEvent(const Self& event)
     { m_DataNode = event.m_DataNode; };
   void operator=(const Self& event)
   { m_DataNode = event.m_DataNode; }
 };
 */
 
 bool mitk::DataNode::IsSelected(const mitk::BaseRenderer *renderer)
 {
   bool selected;
 
   if (!GetBoolProperty("selected", selected, renderer))
     return false;
 
   return selected;
 }
 
 void mitk::DataNode::SetDataInteractor(const DataInteractor::Pointer interactor)
 {
   if (m_DataInteractor == interactor)
     return;
 
   m_DataInteractor = interactor;
   this->Modified();
 
   mitk::DataNode::InteractorChangedEvent changedEvent;
   this->InvokeEvent(changedEvent);
 }
 
 mitk::DataInteractor::Pointer mitk::DataNode::GetDataInteractor() const
 {
   return m_DataInteractor;
 }
 
 void mitk::DataNode::PropertyListModified(const itk::Object * /*caller*/, const itk::EventObject &)
 {
   Modified();
 }
+
+mitk::IIdentifiable::UIDType mitk::DataNode::GetUID() const
+{
+  auto uidProperty = dynamic_cast<StringProperty *>(this->GetProperty("uid"));
+
+  return nullptr != uidProperty
+    ? uidProperty->GetValue()
+    : "";
+}