diff --git a/Modules/ContourModel/IO/mitkContourModelWriter.h b/Modules/ContourModel/IO/mitkContourModelWriter.h
index 3a1b587533..0add146a3b 100644
--- a/Modules/ContourModel/IO/mitkContourModelWriter.h
+++ b/Modules/ContourModel/IO/mitkContourModelWriter.h
@@ -1,171 +1,158 @@
 /*============================================================================
 
 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 _MITK_CONTOURMODEL_WRITER__H_
 #define _MITK_CONTOURMODEL_WRITER__H_
 
 #include <mitkAbstractFileWriter.h>
 #include <mitkContourModel.h>
 
 // DEPRECATED
 #include <mitkTimeGeometry.h>
 
 namespace mitk
 {
   /**
    * @brief XML-based writer for mitk::ContourModels
    *
    * XML-based writer for mitk::ContourModels. Multiple ContourModels can be written in
    * a single XML file by simply setting multiple inputs to the filter.
    *
    * The xml file will look like:
    *
    *   <?xml version="1.0" encoding="utf-8"?>
    *   <contourModel>
    *      <head>
    *        <geometryInfo>
    *        </geometryInfo>
    *      </head>
    *      <data>
    *        <timestep n="0">
    *          <controlPoints>
    *            <point>
    *              <x></x>
    *              <y></y>
    *              <z></z>
    *            </point>
    *          </controlPoint>
    *        </timestep>
    *      </data>
    *    </contourModel>
    *
    * @ingroup MitkContourModelModule
    */
 
-  class TimeSlicedGeometry;
-
   class ContourModelWriter : public mitk::AbstractFileWriter
   {
   public:
     explicit ContourModelWriter(bool writeXMLHeader = true);
     ~ContourModelWriter() override;
 
     using AbstractFileWriter::Write;
     void Write() override;
 
   protected:
     ContourModelWriter(const ContourModelWriter &other);
 
     mitk::ContourModelWriter *Clone() const override;
 
     /**
      * Converts an arbitrary type to a string. The type has to
      * support the << operator. This works fine at least for integral
      * data types as float, int, long etc.
      * @param value the value to convert
      * @returns the string representation of value
      */
     template <typename T>
     std::string ConvertToString(T value);
 
     /**
      * Writes an XML representation of the given point set to
      * an outstream. The XML-Header an root node is not included!
      * @param contourModel the point set to be converted to xml
      * @param out the stream to write to.
      */
     void WriteXML(const mitk::ContourModel *contourModel, std::ostream &out);
 
     /**
     * Writes the geometry information of the TimeGeometry to an outstream.
     * The root tag is not included.
     * @param geometry the TimeGeometry of the contour.
     * @param out the stream to write to.
     */
     void WriteGeometryInformation(const mitk::TimeGeometry *geometry, std::ostream &out);
 
-    /**
-    * Writes the geometry information of the TimeGeometry to an outstream.
-    * The root tag is not included.
-    * @param geometry the TimeGeometry of the contour.
-    * @param out the stream to write to.
-    *
-    * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see
-    * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-    */
-    DEPRECATED(void WriteGeometryInformation(const mitk::TimeSlicedGeometry *geometry, std::ostream &out));
-
     /**
      * Writes an standard xml header to the given stream.
      * @param file the stream in which the header is written.
      */
     void WriteXMLHeader(std::ostream &file);
 
     /** Write a start element tag */
     void WriteStartElement(const char *const tag, std::ostream &file);
 
     void WriteStartElementWithAttribut(const char *const tag,
                                        std::vector<std::string> attributes,
                                        std::vector<std::string> values,
                                        std::ostream &file);
 
     /**
      * Write an end element tag
      * End-Elements following character data should pass indent = false.
      */
     void WriteEndElement(const char *const tag, std::ostream &file, const bool &indent = true);
 
     /** Write character data inside a tag. */
     void WriteCharacterData(const char *const data, std::ostream &file);
 
     /** Write a start element tag */
     void WriteStartElement(std::string &tag, std::ostream &file);
 
     /** Write an end element tag */
     void WriteEndElement(std::string &tag, std::ostream &file, const bool &indent = true);
 
     /** Write character data inside a tag. */
     void WriteCharacterData(std::string &data, std::ostream &file);
 
     /** Writes empty spaces to the stream according to m_IndentDepth and m_Indent */
     void WriteIndent(std::ostream &file);
 
     bool m_WriteXMLHeader;
 
     unsigned int m_IndentDepth;
 
     unsigned int m_Indent;
 
   public:
     static const char *XML_CONTOURMODEL;
 
     static const char *XML_HEAD;
 
     static const char *XML_GEOMETRY_INFO;
 
     static const char *XML_DATA;
 
     static const char *XML_TIME_STEP;
 
     static const char *XML_CONTROL_POINTS;
 
     static const char *XML_POINT;
 
     static const char *XML_X;
 
     static const char *XML_Y;
 
     static const char *XML_Z;
   };
 }
 
 #endif
diff --git a/Modules/Core/include/mitkBaseData.h b/Modules/Core/include/mitkBaseData.h
index 539a9e35fd..c43122796f 100644
--- a/Modules/Core/include/mitkBaseData.h
+++ b/Modules/Core/include/mitkBaseData.h
@@ -1,422 +1,388 @@
 /*============================================================================
 
 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 BASEDATA_H_HEADER_INCLUDED_C1EBB6FA
 #define BASEDATA_H_HEADER_INCLUDED_C1EBB6FA
 
 #include <itkDataObject.h>
 
 #include "mitkBaseProcess.h"
 #include "mitkIdentifiable.h"
 #include "mitkIPropertyOwner.h"
 #include "mitkOperationActor.h"
 #include "mitkPropertyList.h"
 #include "mitkTimeGeometry.h"
 #include <MitkCoreExports.h>
 
 namespace mitk
 {
   // class BaseProcess;
 
   //##Documentation
   //## @brief Base of all data objects
   //##
   //## Base of all data objects, e.g., images, contours, surfaces etc. Inherits
   //## from itk::DataObject and thus can be included in a pipeline.
   //## Inherits also from OperationActor and can be used as a destination for Undo
   //## @remark Some derived classes may support the persistence of the Identifiable UID.
   //** but it is no guaranteed feature and also depends on the format the data is stored in
   //** as not all formats support storing of meta information. Please check the documentation
   //** of the IFileReader and IFileWriter classes to see if the ID-persistance is supported.
   //** MITK SceneIO supports the UID persistance for all BaseData derived classes.
   //## @ingroup Data
   class MITKCORE_EXPORT BaseData
     : public itk::DataObject, public OperationActor, public Identifiable, public IPropertyOwner
   {
   public:
     mitkClassMacroItkParent(BaseData, itk::DataObject);
 
     // IPropertyProvider
     BaseProperty::ConstPointer GetConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) const override;
     std::vector<std::string> GetPropertyKeys(const std::string &contextName = "", bool includeDefaultContext = false) const override;
     std::vector<std::string> GetPropertyContextNames() const override;
 
     // IPropertyOwner
     BaseProperty * GetNonConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) override;
     void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override;
     void RemoveProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override;
 
     /**
     * \brief Return the TimeGeometry of the data as const pointer.
     *
     * \warning No update will be called. Use GetUpdatedGeometry() if you cannot
     * be sure that the geometry is up-to-date.
     *
     * Normally used in GenerateOutputInformation of subclasses of BaseProcess.
     */
     const mitk::TimeGeometry *GetTimeGeometry() const
     {
       return m_TimeGeometry.GetPointer();
     }
 
-    /**
-    * \brief Return the TimeGeometry of the data as const pointer.
-    *
-    * \warning No update will be called. Use GetUpdatedGeometry() if you cannot
-    * be sure that the geometry is up-to-date.
-    *
-    * Normally used in GenerateOutputInformation of subclasses of BaseProcess.
-     * \deprecatedSince{2013_09} Please use GetTimeGeometry instead: For additional information see
-    * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-    */
-    DEPRECATED(const mitk::TimeGeometry *GetTimeSlicedGeometry() const) { return GetTimeGeometry(); }
     /**
     * @brief Return the TimeGeometry of the data as pointer.
     *
     * \warning No update will be called. Use GetUpdatedGeometry() if you cannot
     * be sure that the geometry is up-to-date.
     *
     * Normally used in GenerateOutputInformation of subclasses of BaseProcess.
     */
     mitk::TimeGeometry *GetTimeGeometry() { return m_TimeGeometry.GetPointer(); }
     /**
     * @brief Return the TimeGeometry of the data.
     *
     * The method does not simply return the value of the m_TimeGeometry
     * member. Before doing this, it makes sure that the TimeGeometry
     * is up-to-date (by setting the update extent to largest possible and
     * calling UpdateOutputInformation).
     */
     const mitk::TimeGeometry *GetUpdatedTimeGeometry();
 
-    /**
-    * @brief Return the TimeGeometry of the data.
-    *
-    * The method does not simply return the value of the m_TimeGeometry
-    * member. Before doing this, it makes sure that the TimeGeometry
-    * is up-to-date (by setting the update extent to largest possible and
-    * calling UpdateOutputInformation).
-    * \deprecatedSince{2013_09} Please use GetUpdatedTimeGeometry instead: For additional information see
-    * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-    */
-    DEPRECATED(const mitk::TimeGeometry *GetUpdatedTimeSliceGeometry()) { return GetUpdatedTimeGeometry(); }
     /**
     * \brief Expands the TimeGeometry to a number of TimeSteps.
     *
     * The method expands the TimeGeometry to the given number of TimeSteps,
     * filling newly created elements with empty geometries. Sub-classes should override
     * this method to handle the elongation of their data vectors, too.
     * Note that a shrinking is neither possible nor intended.
     */
     virtual void Expand(unsigned int timeSteps);
 
     /**
     * \brief Return the BaseGeometry of the data at time \a t.
     *
     * The method does not simply return
     * m_TimeGeometry->GetGeometry(t).
     * Before doing this, it makes sure that the BaseGeometry is up-to-date
     * (by setting the update extent appropriately and calling
     * UpdateOutputInformation).
     *
     * @todo Appropriate setting of the update extent is missing.
     */
     const mitk::BaseGeometry *GetUpdatedGeometry(int t = 0);
 
     //##Documentation
     //## @brief Return the geometry, which is a TimeGeometry, of the data
     //## as non-const pointer.
     //##
     //## \warning No update will be called. Use GetUpdatedGeometry() if you cannot
     //## be sure that the geometry is up-to-date.
     //##
     //## Normally used in GenerateOutputInformation of subclasses of BaseProcess.
     mitk::BaseGeometry *GetGeometry(int t = 0) const
     {
       if (m_TimeGeometry.IsNull())
         return nullptr;
       return m_TimeGeometry->GetGeometryForTimeStep(t);
     }
 
     //##Documentation
     //## @brief Update the information for this BaseData (the geometry in particular)
     //## so that it can be used as an output of a BaseProcess.
     //##
     //## This method is used in the pipeline mechanism to propagate information and
     //## initialize the meta data associated with a BaseData. Any implementation
     //## of this method in a derived class is assumed to call its source's
     //## BaseProcess::UpdateOutputInformation() which determines modified
     //## times, LargestPossibleRegions, and any extra meta data like spacing,
     //## origin, etc. Default implementation simply call's it's source's
     //## UpdateOutputInformation().
     //## \note Implementations of this methods in derived classes must take care
     //## that the geometry is updated by calling
     //## GetTimeGeometry()->UpdateInformation()
     //## \em after calling its source's BaseProcess::UpdateOutputInformation().
     void UpdateOutputInformation() override;
 
     //##Documentation
     //## @brief Set the RequestedRegion to the LargestPossibleRegion.
     //##
     //## This forces a filter to produce all of the output in one execution
     //## (i.e. not streaming) on the next call to Update().
     void SetRequestedRegionToLargestPossibleRegion() override = 0;
 
     //##Documentation
     //## @brief Determine whether the RequestedRegion is outside of the BufferedRegion.
     //##
     //## This method returns true if the RequestedRegion
     //## is outside the BufferedRegion (true if at least one pixel is
     //## outside). This is used by the pipeline mechanism to determine
     //## whether a filter needs to re-execute in order to satisfy the
     //## current request.  If the current RequestedRegion is already
     //## inside the BufferedRegion from the previous execution (and the
     //## current filter is up to date), then a given filter does not need
     //## to re-execute
     bool RequestedRegionIsOutsideOfTheBufferedRegion() override = 0;
 
     //##Documentation
     //## @brief Verify that the RequestedRegion is within the LargestPossibleRegion.
     //##
     //## If the RequestedRegion is not within the LargestPossibleRegion,
     //## then the filter cannot possibly satisfy the request. This method
     //## returns true if the request can be satisfied (even if it will be
     //## necessary to process the entire LargestPossibleRegion) and
     //## returns false otherwise.  This method is used by
     //## PropagateRequestedRegion().  PropagateRequestedRegion() throws a
     //## InvalidRequestedRegionError exception if the requested region is
     //## not within the LargestPossibleRegion.
     bool VerifyRequestedRegion() override = 0;
 
     //##Documentation
     //## @brief Copy information from the specified data set.
     //##
     //## This method is part of the pipeline execution model. By default, a
     //## BaseProcess will copy meta-data from the first input to all of its
     //## outputs. See ProcessObject::GenerateOutputInformation().  Each
     //## subclass of DataObject is responsible for being able to copy
     //## whatever meta-data it needs from another DataObject.
     //## The default implementation of this method copies the time sliced geometry
     //## and the property list of an object. If a subclass overrides this
     //## method, it should always call its superclass' version.
     void CopyInformation(const itk::DataObject *data) override;
 
     //##Documentation
     //## @brief Check whether the data has been initialized, i.e.,
     //## at least the Geometry and other header data has been set
     //##
     //## \warning Set to \a true by default for compatibility reasons.
     //## Set m_Initialized=false in constructors of sub-classes that
     //## support distinction between initialized and uninitialized state.
     virtual bool IsInitialized() const;
 
     //##Documentation
     //## @brief Calls ClearData() and InitializeEmpty();
     //## \warning Only use in subclasses that reimplemented these methods.
     //## Just calling Clear from BaseData will reset an object to a not initialized,
     //## invalid state.
     virtual void Clear();
 
     //##Documentation
     //## @brief Check whether object contains data (at
     //## a specified time), e.g., a set of points may be empty
     //##
     //## \warning Returns IsInitialized()==false by default for
     //## compatibility reasons. Override in sub-classes that
     //## support distinction between empty/non-empty state.
     virtual bool IsEmptyTimeStep(unsigned int t) const;
 
     //##Documentation
     //## @brief Check whether object contains data (at
     //## least at one point in time), e.g., a set of points
     //## may be empty
     //##
     //## \warning Returns IsInitialized()==false by default for
     //## compatibility reasons. Override in sub-classes that
     //## support distinction between empty/non-empty state.
     virtual bool IsEmpty() const;
 
     //##Documentation
     //## @brief Set the requested region from this data object to match the requested
     //## region of the data object passed in as a parameter.
     //##
     //## This method is implemented in the concrete subclasses of BaseData.
     void SetRequestedRegion(const itk::DataObject *data) override = 0;
 
     //##Documentation
     //##@brief overwrite if the Data can be called by an Interactor (StateMachine).
     //##
     //## Empty by default. Overwrite and implement all the necessary operations here
     //## and get the necessary information from the parameter operation.
     void ExecuteOperation(Operation *operation) override;
 
     /**
     * \brief Set the BaseGeometry of the data, which will be referenced (not copied!).
     * Assumes the data object has only 1 time step ( is a 3D object ) and creates a
     * new TimeGeometry which saves the given BaseGeometry. If an TimeGeometry has already
     * been set for the object, it will be replaced after calling this function.
     *
     * @warning This method will normally be called internally by the sub-class of BaseData
     * during initialization.
     * \sa SetClonedGeometry
     */
     virtual void SetGeometry(BaseGeometry *aGeometry3D);
 
     /**
     * \brief Set the TimeGeometry of the data, which will be referenced (not copied!).
     *
     * @warning This method will normally be called internally by the sub-class of BaseData
     * during initialization.
     * \sa SetClonedTimeGeometry
     */
     virtual void SetTimeGeometry(TimeGeometry *geometry);
 
     /**
     * \brief Set a clone of the provided Geometry as Geometry of the data.
     * Assumes the data object has only 1 time step ( is a 3D object ) and
     * creates a new TimeGeometry. If an TimeGeometry has already
     * been set for the object, it will be replaced after calling this function.
     *
     * \sa SetGeometry
     */
     virtual void SetClonedGeometry(const BaseGeometry *aGeometry3D);
 
     /**
   * \brief Set a clone of the provided TimeGeometry as TimeGeometry of the data.
   *
   * \sa SetGeometry
   */
     virtual void SetClonedTimeGeometry(const TimeGeometry *geometry);
 
     //##Documentation
     //## @brief Set a clone of the provided geometry as BaseGeometry of a given time step.
     //##
     //## \sa SetGeometry
     virtual void SetClonedGeometry(const BaseGeometry *aGeometry3D, unsigned int time);
 
     //##Documentation
     //## @brief Get the data's property list
     //## @sa GetProperty
     //## @sa m_PropertyList
     mitk::PropertyList::Pointer GetPropertyList() const;
 
     //##Documentation
     //## @brief Set the data's property list
     //## @sa SetProperty
     //## @sa m_PropertyList
     void SetPropertyList(PropertyList *propertyList);
 
     //##Documentation
     //## @brief Get the property (instance of BaseProperty) with key @a propertyKey from the PropertyList,
     //## and set it to this, respectively;
     //## @sa GetPropertyList
     //## @sa m_PropertyList
     //## @sa m_MapOfPropertyLists
     mitk::BaseProperty::Pointer GetProperty(const char *propertyKey) const;
 
     void SetProperty(const char *propertyKey, BaseProperty *property);
 
     //##Documentation
     //## @brief Convenience method for setting the origin of
     //## the BaseGeometry instances of all time steps
     //##
     //## \warning Geometries contained in the BaseGeometry will
     //## \em not be changed, e.g. in case the BaseGeometry is a
     //## SlicedGeometry3D the origin will \em not be propagated
     //## to the contained slices. The sub-class SlicedData
     //## does this for the case that the SlicedGeometry3D is
     //## evenly spaced.
     virtual void SetOrigin(const Point3D &origin);
 
     /** \brief Get the process object that generated this data object.
      *
      * If there is no process object, then the data object has
      * been disconnected from the pipeline, or the data object
      * was created manually. (Note: we cannot use the GetObjectMacro()
      * defined in itkMacro because the mutual dependency of
      * DataObject and ProcessObject causes compile problems. Also,
      * a forward reference smart pointer is returned, not a smart pointer,
      * because of the circular dependency between the process and data object.)
      *
      * GetSource() returns a SmartPointer and not a WeakPointer
      * because it is assumed the code calling GetSource() wants to hold a
      * long term reference to the source. */
     itk::SmartPointer<mitk::BaseDataSource> GetSource() const;
 
     //##Documentation
     //## @brief Get the number of time steps from the TimeGeometry
     //## As the base data has not a data vector given by itself, the number
     //## of time steps is defined over the time sliced geometry. In sub classes,
     //## a better implementation could be over the length of the data vector.
     unsigned int GetTimeSteps() const { return m_TimeGeometry->CountTimeSteps(); }
     //##Documentation
     //## @brief Get the modified time of the last change of the contents
     //## this data object or its geometry.
     unsigned long GetMTime() const override;
 
     /**
      * \sa itk::ProcessObject::Graft
      */
     void Graft(const DataObject *) override;
 
   protected:
     BaseData();
     BaseData(const BaseData &other);
     ~BaseData() override;
 
     //##Documentation
     //## \brief Initialize the TimeGeometry for a number of time steps.
     //## The TimeGeometry is initialized empty and evenly timed.
     //## In many cases it will be necessary to overwrite this in sub-classes.
     virtual void InitializeTimeGeometry(unsigned int timeSteps = 1);
 
-    /**
-    * \brief Initialize the TimeGeometry for a number of time steps.
-    * The TimeGeometry is initialized empty and evenly timed.
-    * In many cases it will be necessary to overwrite this in sub-classes.
-    * \deprecatedSince{2013_09} Please use GetUpdatedTimeGeometry instead: For additional information see
-    * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-    */
-    DEPRECATED(virtual void InitializeTimeSlicedGeometry(unsigned int timeSteps = 1))
-    {
-      InitializeTimeGeometry(timeSteps);
-    }
-
     //##Documentation
     //## @brief reset to non-initialized state, release memory
     virtual void ClearData();
 
     //##Documentation
     //## @brief Pure virtual; Must be used in subclasses to get a data object to a
     //## valid state. Should at least create one empty object and call
     //## Superclass::InitializeTimeGeometry() to ensure an existing valid geometry
     virtual void InitializeEmpty() {}
     void PrintSelf(std::ostream &os, itk::Indent indent) const override;
 
     bool m_LastRequestedRegionWasOutsideOfTheBufferedRegion;
 
     mutable unsigned int m_SourceOutputIndexDuplicate;
 
     bool m_Initialized;
 
   private:
     //##Documentation
     //## @brief PropertyList, f.e. to hold pic-tags, tracking-data,..
     //##
     PropertyList::Pointer m_PropertyList;
 
     TimeGeometry::Pointer m_TimeGeometry;
   };
 
 } // namespace mitk
 
 #endif /* BASEDATA_H_HEADER_INCLUDED_C1EBB6FA */
diff --git a/Modules/Core/include/mitkBaseRenderer.h b/Modules/Core/include/mitkBaseRenderer.h
index b4015ffd7a..909de3a27c 100644
--- a/Modules/Core/include/mitkBaseRenderer.h
+++ b/Modules/Core/include/mitkBaseRenderer.h
@@ -1,532 +1,523 @@
 /*============================================================================
 
 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 BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4
 #define BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4
 
 #include "mitkCameraRotationController.h"
 #include "mitkDataStorage.h"
 #include "mitkPlaneGeometry.h"
 #include "mitkPlaneGeometryData.h"
 #include "mitkSliceNavigationController.h"
 #include "mitkTimeGeometry.h"
 
 #include "mitkBindDispatcherInteractor.h"
 #include "mitkDispatcher.h"
 
 #include <vtkRenderWindow.h>
 #include <vtkRenderer.h>
 
 #include <map>
 #include <set>
 
-// DEPRECATED
-#include <mitkTimeSlicedGeometry.h>
-
 namespace mitk
 {
   class NavigationController;
   class SliceNavigationController;
   class CameraRotationController;
   class CameraController;
   class DataStorage;
   class Mapper;
   class BaseLocalStorageHandler;
   class KeyEvent;
 
   //##Documentation
   //## @brief Organizes the rendering process
   //##
   //## Organizes the rendering process. A Renderer contains a reference to a
   //## DataStorage and asks the mappers of the data objects to render
   //## the data into the renderwindow it is associated to.
   //##
   //## \#Render() checks if rendering is currently allowed by calling
   //## RenderWindow::PrepareRendering(). Initialization of a rendering context
   //## can also be performed in this method.
   //##
   //## The actual rendering code has been moved to \#Repaint()
   //## Both \#Repaint() and \#Update() are declared protected now.
   //##
   //## Note: Separation of the Repaint and Update processes (rendering vs
   //## creating a vtk prop tree) still needs to be worked on. The whole
   //## rendering process also should be reworked to use VTK based classes for
   //## both 2D and 3D rendering.
   //## @ingroup Renderer
   class MITKCORE_EXPORT BaseRenderer : public itk::Object
   {
   public:
     typedef std::map<vtkRenderWindow *, BaseRenderer *> BaseRendererMapType;
     static BaseRendererMapType baseRendererMap;
 
     static BaseRenderer *GetInstance(vtkRenderWindow *renWin);
     static void AddInstance(vtkRenderWindow *renWin, BaseRenderer *baseRenderer);
     static void RemoveInstance(vtkRenderWindow *renWin);
 
     static BaseRenderer *GetByName(const std::string &name);
     static vtkRenderWindow *GetRenderWindowByName(const std::string &name);
 
 #pragma GCC visibility push(default)
     itkEventMacro(RendererResetEvent, itk::AnyEvent);
 #pragma GCC visibility pop
 
     /** Standard class typedefs. */
     mitkClassMacroItkParent(BaseRenderer, itk::Object);
 
     BaseRenderer(const char *name = nullptr, vtkRenderWindow *renWin = nullptr);
 
     //##Documentation
     //## @brief MapperSlotId defines which kind of mapper (e.g. 2D or 3D) should be used.
     typedef int MapperSlotId;
 
     enum StandardMapperSlot
     {
       Standard2D = 1,
       Standard3D = 2
     };
 
     //##Documentation
     //## @brief Possible view directions for render windows.
     enum class ViewDirection
     {
       AXIAL = 0,
       SAGITTAL,
       CORONAL,
       THREE_D
     };
 
     virtual void SetDataStorage(DataStorage *storage); ///< set the datastorage that will be used for rendering
 
     //##Documentation
     //## return the DataStorage that is used for rendering
     virtual DataStorage::Pointer GetDataStorage() const { return m_DataStorage.GetPointer(); }
     //##Documentation
     //## @brief Access the RenderWindow into which this renderer renders.
     vtkRenderWindow *GetRenderWindow() const { return m_RenderWindow; }
     vtkRenderer *GetVtkRenderer() const { return m_VtkRenderer; }
     //##Documentation
     //## @brief Returns the Dispatcher which handles Events for this BaseRenderer
     Dispatcher::Pointer GetDispatcher() const;
 
     //##Documentation
     //## @brief Default mapper id to use.
     static const MapperSlotId defaultMapper;
 
     //##Documentation
     //## @brief Do the rendering and flush the result.
     virtual void Paint();
 
     //##Documentation
     //## @brief Initialize the RenderWindow. Should only be called from RenderWindow.
     virtual void Initialize();
 
     //##Documentation
     //## @brief Called to inform the renderer that the RenderWindow has been resized.
     virtual void Resize(int w, int h);
 
     //##Documentation
     //## @brief Initialize the renderer with a RenderWindow (@a renderwindow).
     virtual void InitRenderer(vtkRenderWindow *renderwindow);
 
     //##Documentation
     //## @brief Set the initial size. Called by RenderWindow after it has become
     //## visible for the first time.
     virtual void InitSize(int w, int h);
 
     //##Documentation
     //## @brief Draws a point on the widget.
     //## Should be used during conferences to show the position of the remote mouse
     virtual void DrawOverlayMouse(Point2D &p2d);
 
     //##Documentation
     //## @brief Set/Get the WorldGeometry (m_WorldGeometry) for 3D and 2D rendering, that describing the
     //## (maximal) area to be rendered.
     //##
     //## Depending of the type of the passed BaseGeometry more or less information can be extracted:
     //## \li if it is a PlaneGeometry (which is a sub-class of BaseGeometry), m_CurrentWorldPlaneGeometry is
     //## also set to point to it. m_WorldTimeGeometry is set to nullptr.
     //## \li if it is a TimeGeometry, m_WorldTimeGeometry is also set to point to it.
     //## If m_WorldTimeGeometry contains instances of SlicedGeometry3D, m_CurrentWorldPlaneGeometry is set to
     //## one of geometries stored in the SlicedGeometry3D according to the value of m_Slice;  otherwise
     //## a PlaneGeometry describing the top of the bounding-box of the BaseGeometry is set as the
     //## m_CurrentWorldPlaneGeometry.
     //## \li otherwise a PlaneGeometry describing the top of the bounding-box of the BaseGeometry
     //## is set as the m_CurrentWorldPlaneGeometry. m_WorldTimeGeometry is set to nullptr.
     //## @todo add calculation of PlaneGeometry describing the top of the bounding-box of the BaseGeometry
     //## when the passed BaseGeometry is not sliced.
     //## \sa m_WorldGeometry
     //## \sa m_WorldTimeGeometry
     //## \sa m_CurrentWorldPlaneGeometry
     virtual void SetWorldGeometry3D(const BaseGeometry *geometry);
     virtual void SetWorldTimeGeometry(const mitk::TimeGeometry *geometry);
 
-    /**
-    * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see
-    * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-    */
-    DEPRECATED(void SetWorldGeometry3D(TimeSlicedGeometry *geometry));
-
     itkGetConstObjectMacro(WorldTimeGeometry, TimeGeometry);
 
       //##Documentation
       //## @brief Get the current 3D-worldgeometry (m_CurrentWorldGeometry) used for 3D-rendering
       itkGetConstObjectMacro(CurrentWorldGeometry, BaseGeometry);
 
       //##Documentation
       //## @brief Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering
       itkGetConstObjectMacro(CurrentWorldPlaneGeometry, PlaneGeometry)
       /**
       * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometry
       */
       DEPRECATED(const PlaneGeometry *GetCurrentWorldGeometry2D())
     {
       return GetCurrentWorldPlaneGeometry();
     };
 
     //##Documentation
     //## Calculates the bounds of the DataStorage (if it contains any valid data),
     //## creates a geometry from these bounds and sets it as world geometry of the renderer.
     //##
     //## Call this method to re-initialize the renderer to the current DataStorage
     //## (e.g. after loading an additional dataset), to ensure that the view is
     //## aligned correctly.
     //## \warning This is not implemented yet.
     virtual bool SetWorldGeometryToDataStorageBounds() { return false; }
     //##Documentation
     //## @brief Set/Get m_Slice which defines together with m_TimeStep the 2D geometry
     //## stored in m_WorldTimeGeometry used as m_CurrentWorldPlaneGeometry
     //##
     //## \sa m_Slice
     virtual void SetSlice(unsigned int slice);
 
     itkGetConstMacro(Slice, unsigned int);
 
       //##Documentation
       //## @brief Set/Get m_TimeStep which defines together with m_Slice the 2D geometry
       //## stored in m_WorldTimeGeometry used as m_CurrentWorldPlaneGeometry
       //##
       //## \sa m_TimeStep
       virtual void SetTimeStep(unsigned int timeStep);
 
     itkGetConstMacro(TimeStep, unsigned int);
 
       //##Documentation
       //## @brief Get the time-step of a BaseData object which
       //## exists at the time of the currently displayed content
       //##
       //## Returns -1 or mitk::BaseData::m_TimeSteps if there
       //## is no data at the current time.
       //## \sa GetTimeStep, m_TimeStep
       TimeStepType GetTimeStep(const BaseData *data) const;
 
     //##Documentation
     //## @brief Get the time in ms of the currently displayed content
     //##
     //## \sa GetTimeStep, m_TimeStep
     ScalarType GetTime() const;
 
     //##Documentation
     //## @brief SetWorldGeometry is called according to the geometrySliceEvent,
     //## which is supposed to be a SliceNavigationController::GeometrySendEvent
     virtual void SetGeometry(const itk::EventObject &geometrySliceEvent);
 
     //##Documentation
     //## @brief UpdateWorldGeometry is called to re-read the 2D geometry from the
     //## slice navigation controller
     virtual void UpdateGeometry(const itk::EventObject &geometrySliceEvent);
 
     //##Documentation
     //## @brief SetSlice is called according to the geometrySliceEvent,
     //## which is supposed to be a SliceNavigationController::GeometrySliceEvent
     virtual void SetGeometrySlice(const itk::EventObject &geometrySliceEvent);
 
     //##Documentation
     //## @brief SetTimeStep is called according to the geometrySliceEvent,
     //## which is supposed to be a SliceNavigationController::GeometryTimeEvent
     virtual void SetGeometryTime(const itk::EventObject &geometryTimeEvent);
 
     //##Documentation
     //## @brief Get a DataNode pointing to a data object containing the current 2D-worldgeometry
     // m_CurrentWorldPlaneGeometry (for 2D rendering)
     itkGetObjectMacro(CurrentWorldPlaneGeometryNode, DataNode)
       /**
       * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometryNode
       */
       DEPRECATED(DataNode *GetCurrentWorldGeometry2DNode())
     {
       return GetCurrentWorldPlaneGeometryNode();
     };
 
     //##Documentation
     //## @brief Sets timestamp of CurrentWorldPlaneGeometry and forces so reslicing in that renderwindow
     void SendUpdateSlice();
 
     //##Documentation
     //## @brief Get timestamp of last call of SetCurrentWorldPlaneGeometry
     unsigned long GetCurrentWorldPlaneGeometryUpdateTime() { return m_CurrentWorldPlaneGeometryUpdateTime; }
     /**
     * \deprecatedSince{2014_10} Please use GetCurrentWorldPlaneGeometryUpdateTime
     */
     DEPRECATED(unsigned long GetCurrentWorldGeometry2DUpdateTime())
     {
       return GetCurrentWorldPlaneGeometryUpdateTime();
     };
     //##Documentation
     //## @brief Get timestamp of last change of current TimeStep
     unsigned long GetTimeStepUpdateTime() { return m_TimeStepUpdateTime; }
     //##Documentation
     //## @brief Perform a picking: find the x,y,z world coordinate of a
     //## display x,y coordinate.
     //## @warning Has to be overwritten in subclasses for the 3D-case.
     //##
     //## Implemented here only for 2D-rendering
     virtual void PickWorldPoint(const Point2D &diplayPosition, Point3D &worldPosition) const = 0;
 
     /** \brief Determines the object (mitk::DataNode) closest to the current
     * position by means of picking
     *
     * \warning Implementation currently empty for 2D rendering; intended to be
     * implemented for 3D renderers */
     virtual DataNode *PickObject(const Point2D & /*displayPosition*/, Point3D & /*worldPosition*/) const
     {
       return nullptr;
     }
 
     //##Documentation
     //## @brief Get the MapperSlotId to use.
     itkGetMacro(MapperID, MapperSlotId);
     itkGetConstMacro(MapperID, MapperSlotId);
 
       //##Documentation
       //## @brief Set the MapperSlotId to use.
       virtual void SetMapperID(MapperSlotId id);
 
         virtual int *GetSize() const;
     virtual int *GetViewportSize() const;
 
     void SetSliceNavigationController(SliceNavigationController *SlicenavigationController);
     itkGetObjectMacro(CameraController, CameraController);
     itkGetObjectMacro(SliceNavigationController, SliceNavigationController);
     itkGetObjectMacro(CameraRotationController, CameraRotationController);
     itkGetMacro(EmptyWorldGeometry, bool);
 
       //##Documentation
       //## @brief Tells if the displayed region is shifted and rescaled if the render window is resized.
       itkGetMacro(KeepDisplayedRegion, bool)
       //##Documentation
       //## @brief Tells if the displayed region should be shifted and rescaled if the render window is resized.
       itkSetMacro(KeepDisplayedRegion, bool);
 
       //##Documentation
       //## @brief get the name of the Renderer
       //## @note
       const char *GetName() const
     {
       return m_Name.c_str();
     }
 
     //##Documentation
     //## @brief get the x_size of the RendererWindow
     //## @note
     int GetSizeX() const { return GetSize()[0]; }
     //##Documentation
     //## @brief get the y_size of the RendererWindow
     //## @note
     int GetSizeY() const { return GetSize()[1]; }
     const double *GetBounds() const;
 
     void RequestUpdate();
     void ForceImmediateUpdate();
 
     /** Returns number of mappers which are visible and have level-of-detail
     * rendering enabled */
     unsigned int GetNumberOfVisibleLODEnabledMappers() const;
 
     //##Documentation
     //## @brief This method converts a display point to the 3D world index
     //## using the geometry of the renderWindow.
     void DisplayToWorld(const Point2D &displayPoint, Point3D &worldIndex) const;
 
     //##Documentation
     //## @brief This method converts a display point to the 2D world index, mapped onto the display plane
     //## using the geometry of the renderWindow.
     void DisplayToPlane(const Point2D &displayPoint, Point2D &planePointInMM) const;
 
     //##Documentation
     //## @brief This method converts a 3D world index to the display point
     //## using the geometry of the renderWindow.
     void WorldToDisplay(const Point3D &worldIndex, Point2D &displayPoint) const;
 
     //##Documentation
     //## @brief This method converts a 3D world index to the point on the viewport
     //## using the geometry of the renderWindow.
     void WorldToView(const Point3D &worldIndex, Point2D &viewPoint) const;
 
     //##Documentation
     //## @brief This method converts a 2D plane coordinate to the display point
     //## using the geometry of the renderWindow.
     void PlaneToDisplay(const Point2D &planePointInMM, Point2D &displayPoint) const;
 
     //##Documentation
     //## @brief This method converts a 2D plane coordinate to the point on the viewport
     //## using the geometry of the renderWindow.
     void PlaneToView(const Point2D &planePointInMM, Point2D &viewPoint) const;
 
 
     double GetScaleFactorMMPerDisplayUnit() const;
 
     Point2D GetDisplaySizeInMM() const;
     Point2D GetViewportSizeInMM() const;
 
     Point2D GetOriginInMM() const;
 
     itkGetConstMacro(ConstrainZoomingAndPanning, bool) virtual void SetConstrainZoomingAndPanning(bool constrain);
 
     /**
     * \brief Provides (1) world coordinates for a given mouse position and (2)
     * translates mousePosition to Display coordinates
     * \deprecated Map2DRendererPositionTo3DWorldPosition is deprecated. Please use DisplayToWorld instead.
     */
     DEPRECATED(virtual Point3D Map2DRendererPositionTo3DWorldPosition(const Point2D &mousePosition) const);
 
   protected:
     ~BaseRenderer() override;
 
     //##Documentation
     //## @brief Call update of all mappers. To be implemented in subclasses.
     virtual void Update() = 0;
 
     vtkRenderWindow *m_RenderWindow;
     vtkRenderer *m_VtkRenderer;
 
     //##Documentation
     //## @brief MapperSlotId to use. Defines which kind of mapper (e.g., 2D or 3D) shoud be used.
     MapperSlotId m_MapperID;
 
     //##Documentation
     //## @brief The DataStorage that is used for rendering.
     DataStorage::Pointer m_DataStorage;
 
     //##Documentation
     //## @brief Timestamp of last call of Update().
     unsigned long m_LastUpdateTime;
 
     //##Documentation
     //## @brief CameraController for 3D rendering
     //## @note preliminary.
     itk::SmartPointer<CameraController> m_CameraController;
     SliceNavigationController::Pointer m_SliceNavigationController;
     CameraRotationController::Pointer m_CameraRotationController;
 
     //##Documentation
     //## @brief Sets m_CurrentWorldPlaneGeometry
     virtual void SetCurrentWorldPlaneGeometry(const PlaneGeometry *geometry2d);
     /**
     * \deprecatedSince{2014_10} Please use SetCurrentWorldPlaneGeometry
     */
     DEPRECATED(void SetCurrentWorldGeometry2D(PlaneGeometry *geometry2d)) { SetCurrentWorldPlaneGeometry(geometry2d); };
     //##Documentation
     //## @brief Sets m_CurrentWorldGeometry
     virtual void SetCurrentWorldGeometry(const BaseGeometry *geometry);
 
   private:
     //##Documentation
     //## m_WorldTimeGeometry is set by SetWorldGeometry if the passed BaseGeometry is a
     //## TimeGeometry (or a sub-class of it). If it contains instances of SlicedGeometry3D,
     //## m_Slice and m_TimeStep (set via SetSlice and SetTimeStep, respectively) define
     //## which 2D geometry stored in m_WorldTimeGeometry (if available)
     //## is used as m_CurrentWorldPlaneGeometry.
     //## \sa m_CurrentWorldPlaneGeometry
     TimeGeometry::ConstPointer m_WorldTimeGeometry;
 
     //##Documentation
     //## Pointer to the current 3D-worldgeometry.
     BaseGeometry::ConstPointer m_CurrentWorldGeometry;
 
     //##Documentation
     //## Pointer to the current 2D-worldgeometry. The 2D-worldgeometry
     //## describes the maximal area (2D manifold) to be rendered in case we
     //## are doing 2D-rendering.
     //## It is const, since we are not allowed to change it (it may be taken
     //## directly from the geometry of an image-slice and thus it would be
     //## very strange when suddenly the image-slice changes its geometry).
     PlaneGeometry::Pointer m_CurrentWorldPlaneGeometry;
 
     //##Documentation
     //## Defines together with m_Slice which 2D geometry stored in m_WorldTimeGeometry
     //## is used as m_CurrentWorldPlaneGeometry: m_WorldTimeGeometry->GetPlaneGeometry(m_Slice, m_TimeStep).
     //## \sa m_WorldTimeGeometry
     unsigned int m_Slice;
     //##Documentation
     //## Defines together with m_TimeStep which 2D geometry stored in m_WorldTimeGeometry
     //## is used as m_CurrentWorldPlaneGeometry: m_WorldTimeGeometry->GetPlaneGeometry(m_Slice, m_TimeStep).
     //## \sa m_WorldTimeGeometry
     unsigned int m_TimeStep;
 
     //##Documentation
     //## @brief timestamp of last call of SetWorldGeometry
     itk::TimeStamp m_CurrentWorldPlaneGeometryUpdateTime;
 
     //##Documentation
     //## @brief timestamp of last change of the current time step
     itk::TimeStamp m_TimeStepUpdateTime;
 
     //##Documentation
     //## @brief Helper class which establishes connection between Interactors and Dispatcher via a common DataStorage.
     BindDispatcherInteractor *m_BindDispatcherInteractor;
 
     //##Documentation
     //## @brief Tells if the displayed region should be shifted or rescaled if the render window is resized.
     bool m_KeepDisplayedRegion;
 
   protected:
     void PrintSelf(std::ostream &os, itk::Indent indent) const override;
 
     //##Documentation
     //## Data object containing the m_CurrentWorldPlaneGeometry defined above.
     PlaneGeometryData::Pointer m_CurrentWorldPlaneGeometryData;
 
     //##Documentation
     //## DataNode objects containing the m_CurrentWorldPlaneGeometryData defined above.
     DataNode::Pointer m_CurrentWorldPlaneGeometryNode;
 
     //##Documentation
     //## @brief test only
     unsigned long m_CurrentWorldPlaneGeometryTransformTime;
 
     std::string m_Name;
 
     double m_Bounds[6];
 
     bool m_EmptyWorldGeometry;
 
     typedef std::set<Mapper *> LODEnabledMappersType;
 
     /** Number of mappers which are visible and have level-of-detail
     * rendering enabled */
     unsigned int m_NumberOfVisibleLODEnabledMappers;
 
     // Local Storage Handling for mappers
 
   protected:
     std::list<mitk::BaseLocalStorageHandler *> m_RegisteredLocalStorageHandlers;
 
     bool m_ConstrainZoomingAndPanning;
 
   public:
     void RemoveAllLocalStorages();
     void RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh);
     void UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh);
   };
 } // namespace mitk
 
 #endif /* BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 */
diff --git a/Modules/Core/include/mitkImage.h b/Modules/Core/include/mitkImage.h
index fe8e646ebc..359b536d87 100644
--- a/Modules/Core/include/mitkImage.h
+++ b/Modules/Core/include/mitkImage.h
@@ -1,799 +1,644 @@
 /*============================================================================
 
 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 MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2
 #define MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2
 
 #include "mitkBaseData.h"
 #include "mitkImageAccessorBase.h"
 #include "mitkImageDataItem.h"
 #include "mitkImageDescriptor.h"
 #include "mitkImageVtkAccessor.h"
 #include "mitkLevelWindow.h"
 #include "mitkPlaneGeometry.h"
 #include "mitkSlicedData.h"
 #include <MitkCoreExports.h>
 #include <mitkProportionalTimeGeometry.h>
 
-// DEPRECATED
-#include <mitkTimeSlicedGeometry.h>
-
 #ifndef __itkHistogram_h
 #include <itkHistogram.h>
 #endif
 
 class vtkImageData;
 
 namespace itk
 {
   template <class T>
   class MutexLockHolder;
 }
 
 namespace mitk
 {
   class SubImageSelector;
   class ImageTimeSelector;
 
   class ImageStatisticsHolder;
 
   /**
     * @brief Image class for storing images
     *
     * Can be asked for header information, the data vector,
     * the mitkIpPicDescriptor struct or vtkImageData objects. If not the complete
     * data is required, the appropriate SubImageSelector class should be used
     * for access.
     * Image organizes sets of slices (s x 2D), volumes (t x 3D) and channels (n
     * x ND). Channels are for different kind of data, e.g., morphology in
     * channel 0, velocities in channel 1. All channels must have the same Geometry! In
     * particular, the dimensions of all channels are the same, only the pixel-type
     * may differ between channels.
     *
     * For importing ITK images use of mitk::ITKImageImport is recommended, see
     * \ref Adaptor.
     *
     * For ITK v3.8 and older: Converting coordinates from the ITK physical
     * coordinate system (which does not support rotated images) to the MITK world
     * coordinate system should be performed via the BaseGeometry of the Image, see
     * BaseGeometry::WorldToItkPhysicalPoint.
     *
     * For more information, see \ref MitkImagePage .
     * @ingroup Data
     */
   class MITKCORE_EXPORT Image : public SlicedData
   {
     friend class SubImageSelector;
 
     friend class ImageAccessorBase;
     friend class ImageVtkAccessor;
     friend class ImageVtkReadAccessor;
     friend class ImageVtkWriteAccessor;
     friend class ImageReadAccessor;
     friend class ImageWriteAccessor;
 
   public:
     mitkClassMacro(Image, SlicedData);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self);
 
     /** Smart Pointer type to a ImageDataItem. */
     typedef itk::SmartPointer<ImageDataItem> ImageDataItemPointer;
     typedef itk::Statistics::Histogram<double> HistogramType;
     typedef mitk::ImageStatisticsHolder *StatisticsHolderPointer;
 
     /** This enum is evaluated when setting new data to an image.
       */
     enum ImportMemoryManagementType
     {
       CopyMemory, /**< Data to be set is copied and assigned to a new memory block. Data memory block will be freed on deletion of mitk::Image. */
       ManageMemory, /**< Data to be set will be referenced, and Data memory block will be freed on deletion of mitk::Image. */
       ReferenceMemory, /**< Data to be set will be referenced, but Data memory block will not be freed on deletion of mitk::Image. */
       DontManageMemory = ReferenceMemory
     };
 
     /**
       * @brief Vector container of SmartPointers to ImageDataItems;
       * Class is only for internal usage to allow convenient access to all slices over iterators;
       * See documentation of ImageDataItem for details.
       */
     typedef std::vector<ImageDataItemPointer> ImageDataItemPointerArray;
 
   public:
     /**
       * @brief Returns the PixelType of channel @a n.
       */
     const mitk::PixelType GetPixelType(int n = 0) const;
 
     /**
       * @brief Get dimension of the image
       */
     unsigned int GetDimension() const;
 
     /**
       * @brief Get the size of dimension @a i (e.g., i=0 results in the number of pixels in x-direction).
       *
       * @sa GetDimensions()
       */
     unsigned int GetDimension(int i) const;
 
-    /** @brief Get the data vector of the complete image, i.e., of all channels linked together.
-
-    If you only want to access a slice, volume at a specific time or single channel
-    use one of the SubImageSelector classes.
-     \deprecatedSince{2012_09} Please use image accessors instead: See Doxygen/Related-Pages/Concepts/Image. This method
-    can be replaced by ImageWriteAccessor::GetData() or ImageReadAccessor::GetData() */
-    DEPRECATED(virtual void *GetData());
-
   public:
-    /** @brief Get the pixel value at one specific index position.
-
-    The pixel type is always being converted to double.
-     \deprecatedSince{2012_09} Please use image accessors instead: See Doxygen/Related-Pages/Concepts/Image. This method
-    can be replaced by a method from ImagePixelWriteAccessor or ImagePixelReadAccessor */
-    DEPRECATED(double GetPixelValueByIndex(const itk::Index<3> &position,
-                                           unsigned int timestep = 0,
-                                           unsigned int component = 0));
-
-    /** @brief Get the pixel value at one specific world position.
-
-    The pixel type is always being converted to double.
-    Please consider using image accessors instead: See Doxygen/Related-Pages/Concepts/Image. This method
-    can be replaced by a templated method from ImagePixelWriteAccessor or ImagePixelReadAccessor */
-    double GetPixelValueByWorldCoordinate(const mitk::Point3D &position,
-                                                     unsigned int timestep = 0,
-                                                     unsigned int component = 0);
-
     /**
       * @brief Get a volume at a specific time @a t of channel @a n as a vtkImageData.
       */
     virtual vtkImageData *GetVtkImageData(int t = 0, int n = 0);
     virtual const vtkImageData *GetVtkImageData(int t = 0, int n = 0) const;
 
     /**
       * @brief Check whether slice @a s at time @a t in channel @a n is set
       */
     bool IsSliceSet(int s = 0, int t = 0, int n = 0) const override;
 
     /**
       * @brief Check whether volume at time @a t in channel @a n is set
       */
     bool IsVolumeSet(int t = 0, int n = 0) const override;
 
     /**
       * @brief Check whether the channel @a n is set
       */
     bool IsChannelSet(int n = 0) const override;
 
     /**
       * @brief Set @a data as slice @a s at time @a t in channel @a n. It is in
       * the responsibility of the caller to ensure that the data vector @a data
       * is really a slice (at least is not smaller than a slice), since there is
       * no chance to check this.
       *
       * The data is copied to an array managed by the image. If the image shall
       * reference the data, use SetImportSlice with ImportMemoryManagementType
       * set to ReferenceMemory. For importing ITK images use of mitk::
       * ITKImageImport is recommended.
       * @sa SetPicSlice, SetImportSlice, SetImportVolume
       */
     virtual bool SetSlice(const void *data, int s = 0, int t = 0, int n = 0);
 
     /**
       * @brief Set @a data as volume at time @a t in channel @a n. It is in
       * the responsibility of the caller to ensure that the data vector @a data
       * is really a volume (at least is not smaller than a volume), since there is
       * no chance to check this.
       *
       * The data is copied to an array managed by the image. If the image shall
       * reference the data, use SetImportVolume with ImportMemoryManagementType
       * set to ReferenceMemory. For importing ITK images use of mitk::
       * ITKImageImport is recommended.
       * @sa SetPicVolume, SetImportVolume
       */
     virtual bool SetVolume(const void *data, int t = 0, int n = 0);
 
     /**
       * @brief Set @a data in channel @a n. It is in
       * the responsibility of the caller to ensure that the data vector @a data
       * is really a channel (at least is not smaller than a channel), since there is
       * no chance to check this.
       *
       * The data is copied to an array managed by the image. If the image shall
       * reference the data, use SetImportChannel with ImportMemoryManagementType
       * set to ReferenceMemory. For importing ITK images use of mitk::
       * ITKImageImport is recommended.
       * @sa SetPicChannel, SetImportChannel
       */
     virtual bool SetChannel(const void *data, int n = 0);
 
     /**
       * @brief Set @a data as slice @a s at time @a t in channel @a n. It is in
       * the responsibility of the caller to ensure that the data vector @a data
       * is really a slice (at least is not smaller than a slice), since there is
       * no chance to check this.
       *
       * The data is managed according to the parameter \a importMemoryManagement.
       * @sa SetPicSlice
       */
     virtual bool SetImportSlice(
       void *data, int s = 0, int t = 0, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory);
 
     /**
       * @brief Set @a data as volume at time @a t in channel @a n. It is in
       * the responsibility of the caller to ensure that the data vector @a data
       * is really a volume (at least is not smaller than a volume), since there is
       * no chance to check this.
       *
       * The data is managed according to the parameter \a importMemoryManagement.
       * @sa SetPicVolume
       */
     virtual bool SetImportVolume(void *data,
                                  int t = 0,
                                  int n = 0,
                                  ImportMemoryManagementType importMemoryManagement = CopyMemory);
 
     virtual bool SetImportVolume(const void *const_data, int t = 0, int n = 0);
 
     /**
       * @brief Set @a data in channel @a n. It is in
       * the responsibility of the caller to ensure that the data vector @a data
       * is really a channel (at least is not smaller than a channel), since there is
       * no chance to check this.
       *
       * The data is managed according to the parameter \a importMemoryManagement.
       * @sa SetPicChannel
       */
     virtual bool SetImportChannel(void *data,
                                   int n = 0,
                                   ImportMemoryManagementType importMemoryManagement = CopyMemory);
 
     /**
       * initialize new (or re-initialize) image information
       * @warning Initialize() by pic assumes a plane, evenly spaced geometry starting at (0,0,0).
       */
     virtual void Initialize(const mitk::PixelType &type,
                             unsigned int dimension,
                             const unsigned int *dimensions,
                             unsigned int channels = 1);
 
     /**
       * initialize new (or re-initialize) image information by a BaseGeometry
       *
       * \param type
       * \param geometry
       * \param channels
       * @param tDim defines the number of time steps for which the Image should be initialized
       */
     virtual void Initialize(const mitk::PixelType &type,
                             const mitk::BaseGeometry &geometry,
                             unsigned int channels = 1,
                             int tDim = 1);
 
-    /**
-    * initialize new (or re-initialize) image information by a TimeGeometry
-    *
-    * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see
-    * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-    */
-    DEPRECATED(virtual void Initialize(const mitk::PixelType & /*type*/,
-                                       const mitk::TimeSlicedGeometry * /*geometry*/,
-                                       unsigned int /*channels = 1*/,
-                                       int /*tDim=1*/))
-    {
-    }
-
     /**
     * \brief Initialize new (or re-initialize) image information by a TimeGeometry
     *
     * \param type
     * \param geometry
     * \param channels
     * \param tDim override time dimension if the value is bigger than 0 (Default -1)
     */
     virtual void Initialize(const mitk::PixelType &type,
                             const mitk::TimeGeometry &geometry,
                             unsigned int channels = 1,
                             int tDim = -1);
 
     /**
       * initialize new (or re-initialize) image information by a PlaneGeometry and number of slices
       *
       * Initializes the bounding box according to the width/height of the
       * PlaneGeometry and @a sDim via SlicedGeometry3D::InitializeEvenlySpaced.
       * The spacing is calculated from the PlaneGeometry.
       * \sa SlicedGeometry3D::InitializeEvenlySpaced
-      * \deprecatedSince{2016_11} Use a left-handed or right-handed PlaneGeometry to define the
-      * direction of the image stack instead of the flipped parameter
       */
-    DEPRECATED(virtual void Initialize(const mitk::PixelType &type,
-                            int sDim,
-                            const mitk::PlaneGeometry &geometry2d,
-                            bool flipped,
-                            unsigned int channels = 1,
-                            int tDim = 1));
-
     virtual void Initialize(const mitk::PixelType &type,
                             int sDim,
                             const mitk::PlaneGeometry &geometry2d,
                             unsigned int channels = 1,
                             int tDim = 1);
 
     /**
       * initialize new (or re-initialize) image information by another
       * mitk-image.
       * Only the header is used, not the data vector!
       */
     virtual void Initialize(const mitk::Image *image);
 
     virtual void Initialize(const mitk::ImageDescriptor::Pointer inDesc);
 
     /**
       * initialize new (or re-initialize) image information by @a vtkimagedata,
       * a vtk-image.
       * Only the header is used, not the data vector! Use
       * SetVolume(vtkimage->GetScalarPointer()) to set the data vector.
       *
       * @param vtkimagedata
       * @param channels
       * @param tDim override time dimension in @a vtkimagedata (if >0 and <)
       * @param sDim override z-space dimension in @a vtkimagedata (if >0 and <)
       * @param pDim override y-space dimension in @a vtkimagedata (if >0 and <)
       */
     virtual void Initialize(vtkImageData *vtkimagedata, int channels = 1, int tDim = -1, int sDim = -1, int pDim = -1);
 
     /**
       * initialize new (or re-initialize) image information by @a itkimage,
       * a templated itk-image.
       * Only the header is used, not the data vector! Use
       * SetVolume(itkimage->GetBufferPointer()) to set the data vector.
       *
       * @param itkimage
       * @param channels
       * @param tDim override time dimension in @a itkimage (if >0 and <)
       * @param sDim override z-space dimension in @a itkimage (if >0 and <)
       */
     template <typename itkImageType>
     void InitializeByItk(const itkImageType *itkimage, int channels = 1, int tDim = -1, int sDim = -1)
     {
       if (itkimage == nullptr)
         return;
 
       MITK_DEBUG << "Initializing MITK image from ITK image.";
       // build array with dimensions in each direction with at least 4 entries
       m_Dimension = itkimage->GetImageDimension();
       unsigned int i, *tmpDimensions = new unsigned int[m_Dimension > 4 ? m_Dimension : 4];
       for (i = 0; i < m_Dimension; ++i)
         tmpDimensions[i] = itkimage->GetLargestPossibleRegion().GetSize().GetSize()[i];
       if (m_Dimension < 4)
       {
         unsigned int *p;
         for (i = 0, p = tmpDimensions + m_Dimension; i < 4 - m_Dimension; ++i, ++p)
           *p = 1;
       }
 
       // overwrite number of slices if sDim is set
       if ((m_Dimension > 2) && (sDim >= 0))
         tmpDimensions[2] = sDim;
       // overwrite number of time points if tDim is set
       if ((m_Dimension > 3) && (tDim >= 0))
         tmpDimensions[3] = tDim;
 
       // rough initialization of Image
       // mitk::PixelType importType = ImportItkPixelType( itkimage::PixelType );
 
       Initialize(
         MakePixelType<itkImageType>(itkimage->GetNumberOfComponentsPerPixel()), m_Dimension, tmpDimensions, channels);
       const typename itkImageType::SpacingType &itkspacing = itkimage->GetSpacing();
 
       MITK_DEBUG << "ITK spacing " << itkspacing;
       // access spacing of itk::Image
       Vector3D spacing;
       FillVector3D(spacing, itkspacing[0], 1.0, 1.0);
       if (m_Dimension >= 2)
         spacing[1] = itkspacing[1];
       if (m_Dimension >= 3)
         spacing[2] = itkspacing[2];
 
       // access origin of itk::Image
       Point3D origin;
       const typename itkImageType::PointType &itkorigin = itkimage->GetOrigin();
       MITK_DEBUG << "ITK origin " << itkorigin;
       FillVector3D(origin, itkorigin[0], 0.0, 0.0);
       if (m_Dimension >= 2)
         origin[1] = itkorigin[1];
       if (m_Dimension >= 3)
         origin[2] = itkorigin[2];
 
       // access direction of itk::Imagm_PixelType = new mitk::PixelType(type);e and include spacing
       const typename itkImageType::DirectionType &itkdirection = itkimage->GetDirection();
       MITK_DEBUG << "ITK direction " << itkdirection;
       mitk::Matrix3D matrix;
       matrix.SetIdentity();
       unsigned int j, itkDimMax3 = (m_Dimension >= 3 ? 3 : m_Dimension);
       // check if spacing has no zero entry and itkdirection has no zero columns
       bool itkdirectionOk = true;
       mitk::ScalarType columnSum;
       for (j = 0; j < itkDimMax3; ++j)
       {
         columnSum = 0.0;
         for (i = 0; i < itkDimMax3; ++i)
         {
           columnSum += fabs(itkdirection[i][j]);
         }
         if (columnSum < mitk::eps)
         {
           itkdirectionOk = false;
         }
         if ((spacing[j] < -mitk::eps) // (normally sized) negative value
             &&
             (j == 2) && (m_Dimensions[2] == 1))
         {
           // Negative spacings can occur when reading single DICOM slices with ITK via GDCMIO
           // In these cases spacing is not determind by ITK correctly (because it distinguishes correctly
           // between slice thickness and inter slice distance -- slice distance is meaningless for
           // single slices).
           // I experienced that ITK produced something meaningful nonetheless because is is
           // evaluating the tag "(0018,0088) Spacing between slices" as a fallback. This tag is not
           // reliable (http://www.itk.org/pipermail/insight-users/2005-September/014711.html)
           // but gives at least a hint.
           // In real world cases I experienced that this tag contained the correct inter slice distance
           // with a negative sign, so we just invert such negative spacings.
           MITK_WARN << "Illegal value of itk::Image::GetSpacing()[" << j << "]=" << spacing[j]
                     << ". Using inverted value " << -spacing[j];
           spacing[j] = -spacing[j];
         }
         else if (spacing[j] < mitk::eps) // value near zero
         {
           MITK_ERROR << "Illegal value of itk::Image::GetSpacing()[" << j << "]=" << spacing[j]
                      << ". Using 1.0 instead.";
           spacing[j] = 1.0;
         }
       }
       if (itkdirectionOk == false)
       {
         MITK_ERROR << "Illegal matrix returned by itk::Image::GetDirection():" << itkdirection
                    << " Using identity instead.";
         for (i = 0; i < itkDimMax3; ++i)
           for (j = 0; j < itkDimMax3; ++j)
             if (i == j)
               matrix[i][j] = spacing[j];
             else
               matrix[i][j] = 0.0;
       }
       else
       {
         for (i = 0; i < itkDimMax3; ++i)
           for (j = 0; j < itkDimMax3; ++j)
             matrix[i][j] = itkdirection[i][j] * spacing[j];
       }
 
       // re-initialize PlaneGeometry with origin and direction
       PlaneGeometry *planeGeometry = static_cast<PlaneGeometry *>(GetSlicedGeometry(0)->GetPlaneGeometry(0));
       planeGeometry->SetOrigin(origin);
       planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix);
 
       // re-initialize SlicedGeometry3D
       SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(0);
       slicedGeometry->InitializeEvenlySpaced(planeGeometry, m_Dimensions[2]);
       slicedGeometry->SetSpacing(spacing);
 
       // re-initialize TimeGeometry
       ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
       timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]);
       SetTimeGeometry(timeGeometry);
 
       // clean-up
       delete[] tmpDimensions;
 
       this->Initialize();
     }
 
     /**
       * @brief Check whether slice @a s at time @a t in channel @a n is valid, i.e.,
       * is (or can be) inside of the image
       */
     virtual bool IsValidSlice(int s = 0, int t = 0, int n = 0) const;
 
     /**
       * @brief Check whether volume at time @a t in channel @a n is valid, i.e.,
       * is (or can be) inside of the image
       */
     virtual bool IsValidVolume(int t = 0, int n = 0) const;
 
     /**
       * @brief Check whether the channel @a n is valid, i.e.,
       * is (or can be) inside of the image
       */
     virtual bool IsValidChannel(int n = 0) const;
 
     /**
       * @brief Returns true if an image is rotated, i.e. its geometry's
       * transformation matrix has nonzero elements besides the diagonal.
       * Non-diagonal elements are checked if larger then 1/1000 of the matrix' trace.
       */
     bool IsRotated() const;
 
     /**
       * @brief Get the sizes of all dimensions as an integer-array.
       *
       * @sa GetDimension(int i);
       */
     unsigned int *GetDimensions() const;
 
     ImageDescriptor::Pointer GetImageDescriptor() const { return m_ImageDescriptor; }
     ChannelDescriptor GetChannelDescriptor(int id = 0) const { return m_ImageDescriptor->GetChannelDescriptor(id); }
     /** \brief Sets a geometry to an image.
       */
     void SetGeometry(BaseGeometry *aGeometry3D) override;
 
     /**
     * @warning for internal use only
     */
     virtual ImageDataItemPointer GetSliceData(int s = 0,
                                               int t = 0,
                                               int n = 0,
                                               void *data = nullptr,
                                               ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
 
     /**
     * @warning for internal use only
     */
     virtual ImageDataItemPointer GetVolumeData(int t = 0,
                                                int n = 0,
                                                void *data = nullptr,
                                                ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
 
     /**
     * @warning for internal use only
     */
     virtual ImageDataItemPointer GetChannelData(int n = 0,
                                                 void *data = nullptr,
                                                 ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
 
-    /**
-    \brief (DEPRECATED) Get the minimum for scalar images
-    */
-    DEPRECATED(ScalarType GetScalarValueMin(int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the maximum for scalar images
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetScalarValueMax(int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the second smallest value for scalar images
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetScalarValue2ndMin(int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the smallest value for scalar images, but do not recompute it first
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetScalarValueMinNoRecompute(unsigned int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the second smallest value for scalar images, but do not recompute it first
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetScalarValue2ndMinNoRecompute(unsigned int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the second largest value for scalar images
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetScalarValue2ndMax(int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the largest value for scalar images, but do not recompute it first
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetScalarValueMaxNoRecompute(unsigned int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the second largest value for scalar images, but do not recompute it first
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetScalarValue2ndMaxNoRecompute(unsigned int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the count of voxels with the smallest scalar value in the dataset
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetCountOfMinValuedVoxels(int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the count of voxels with the largest scalar value in the dataset
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(ScalarType GetCountOfMaxValuedVoxels(int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the count of voxels with the largest scalar value in the dataset
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(unsigned int GetCountOfMaxValuedVoxelsNoRecompute(unsigned int t = 0) const);
-
-    /**
-    \brief (DEPRECATED) Get the count of voxels with the smallest scalar value in the dataset
-
-    \warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
-    */
-    DEPRECATED(unsigned int GetCountOfMinValuedVoxelsNoRecompute(unsigned int t = 0) const);
-
     /**
       \brief Returns a pointer to the ImageStatisticsHolder object that holds all statistics information for the image.
 
       All Get-methods for statistics properties formerly accessible directly from an Image object are now moved to the
       new \a ImageStatisticsHolder object.
       */
     StatisticsHolderPointer GetStatistics() const { return m_ImageStatistics; }
+
   protected:
     mitkCloneMacro(Self);
 
     typedef itk::MutexLockHolder<itk::SimpleFastMutexLock> MutexHolder;
 
     int GetSliceIndex(int s = 0, int t = 0, int n = 0) const;
 
     int GetVolumeIndex(int t = 0, int n = 0) const;
 
     void ComputeOffsetTable();
 
     virtual bool IsValidTimeStep(int t) const;
 
     void Expand(unsigned int timeSteps) override;
 
     virtual ImageDataItemPointer AllocateSliceData(
       int s = 0,
       int t = 0,
       int n = 0,
       void *data = nullptr,
       ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
 
     virtual ImageDataItemPointer AllocateVolumeData(
       int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
 
     virtual ImageDataItemPointer AllocateChannelData(
       int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
 
     Image();
 
     Image(const Image &other);
 
     ~Image() override;
 
     void Clear() override;
 
     /** @warning Has to be called by every Initialize method! */
     void Initialize() override;
 
     void PrintSelf(std::ostream &os, itk::Indent indent) const override;
 
     mutable ImageDataItemPointerArray m_Channels;
     mutable ImageDataItemPointerArray m_Volumes;
     mutable ImageDataItemPointerArray m_Slices;
     mutable itk::SimpleFastMutexLock m_ImageDataArraysLock;
 
     unsigned int m_Dimension;
 
     unsigned int *m_Dimensions;
 
     ImageDescriptor::Pointer m_ImageDescriptor;
 
     size_t *m_OffsetTable;
     ImageDataItemPointer m_CompleteData;
 
     // Image statistics Holder replaces the former implementation directly inside this class
     friend class ImageStatisticsHolder;
     StatisticsHolderPointer m_ImageStatistics;
 
   private:
     ImageDataItemPointer GetSliceData_unlocked(
       int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const;
     ImageDataItemPointer GetVolumeData_unlocked(int t,
                                                 int n,
                                                 void *data,
                                                 ImportMemoryManagementType importMemoryManagement) const;
     ImageDataItemPointer GetChannelData_unlocked(int n,
                                                  void *data,
                                                  ImportMemoryManagementType importMemoryManagement) const;
 
     ImageDataItemPointer AllocateSliceData_unlocked(
       int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const;
     ImageDataItemPointer AllocateVolumeData_unlocked(int t,
                                                      int n,
                                                      void *data,
                                                      ImportMemoryManagementType importMemoryManagement) const;
     ImageDataItemPointer AllocateChannelData_unlocked(int n,
                                                       void *data,
                                                       ImportMemoryManagementType importMemoryManagement) const;
 
     bool IsSliceSet_unlocked(int s, int t, int n) const;
     bool IsVolumeSet_unlocked(int t, int n) const;
     bool IsChannelSet_unlocked(int n) const;
 
     /** Stores all existing ImageReadAccessors */
     mutable std::vector<ImageAccessorBase *> m_Readers;
     /** Stores all existing ImageWriteAccessors */
     mutable std::vector<ImageAccessorBase *> m_Writers;
     /** Stores all existing ImageVtkAccessors */
     mutable std::vector<ImageAccessorBase *> m_VtkReaders;
 
     /** A mutex, which needs to be locked to manage m_Readers and m_Writers */
     itk::SimpleFastMutexLock m_ReadWriteLock;
     /** A mutex, which needs to be locked to manage m_VtkReaders */
     itk::SimpleFastMutexLock m_VtkReadersLock;
   };
 
-  /**
-  * @brief Equal A function comparing two images for beeing equal in meta- and imagedata
-  * @warning This method is deprecated and will not be available in the future. Use the \a bool mitk::Equal(const
-  * mitk::Image& i1, const mitk::Image& i2) instead.
-  *
-  * @ingroup MITKTestingAPI
-  *
-  * Following aspects are tested for equality:
-  *  - dimension of the images
-  *  - size of the images
-  *  - pixel type
-  *  - pixel values : pixel values are expected to be identical at each position ( for other options see
-  * mitk::CompareImageFilter )
-  *
-  * @param rightHandSide An image to be compared
-  * @param leftHandSide An image to be compared
-  * @param eps Tolarence for comparison. You can use mitk::eps in most cases.
-  * @param verbose Flag indicating if the user wants detailed console output or not.
-  * @return true, if all subsequent comparisons are true, false otherwise
-  */
-  DEPRECATED(MITKCORE_EXPORT bool Equal(
-    const mitk::Image *leftHandSide, const mitk::Image *rightHandSide, ScalarType eps, bool verbose));
-
   /**
   * @brief Equal A function comparing two images for beeing equal in meta- and imagedata
   *
   * @ingroup MITKTestingAPI
   *
   * Following aspects are tested for equality:
   *  - dimension of the images
   *  - size of the images
   *  - pixel type
   *  - pixel values : pixel values are expected to be identical at each position ( for other options see
   * mitk::CompareImageFilter )
   *
   * @param rightHandSide An image to be compared
   * @param leftHandSide An image to be compared
   * @param eps Tolarence for comparison. You can use mitk::eps in most cases.
   * @param verbose Flag indicating if the user wants detailed console output or not.
   * @return true, if all subsequent comparisons are true, false otherwise
   */
   MITKCORE_EXPORT bool Equal(const mitk::Image &leftHandSide,
                              const mitk::Image &rightHandSide,
                              ScalarType eps,
                              bool verbose);
 
 } // namespace mitk
 
 #endif /* MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 */
diff --git a/Modules/Core/include/mitkImageDataItem.h b/Modules/Core/include/mitkImageDataItem.h
index f221d344a8..946879ff55 100644
--- a/Modules/Core/include/mitkImageDataItem.h
+++ b/Modules/Core/include/mitkImageDataItem.h
@@ -1,163 +1,166 @@
 /*============================================================================
 
 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 IMAGEDATAITEM_H
 #define IMAGEDATAITEM_H
 
 #include "mitkCommon.h"
 #include <MitkCoreExports.h>
 //#include <mitkIpPic.h>
 //#include "mitkPixelType.h"
 #include "mitkImageDescriptor.h"
 //#include "mitkImageVtkAccessor.h"
 
 class vtkImageData;
 
 namespace mitk
 {
   class PixelType;
   class ImageVtkReadAccessor;
   class ImageVtkWriteAccessor;
 
   class Image;
 
   //##Documentation
   //## @brief Internal class for managing references on sub-images
   //##
   //## ImageDataItem is a container for image data which is used internal in
   //## mitk::Image to handle the communication between the different data types for images
   //## used in MITK (ipPicDescriptor, mitk::Image, vtkImageData). Common for these image data
   //## types is the actual image data, but they differ in representation of pixel type etc.
   //## The class is also used to convert ipPic images to vtkImageData.
   //##
   //## The class is mainly used to extract sub-images inside of mitk::Image, like single slices etc.
   //## It should not be used outside of this.
   //##
   //## @param manageMemory Determines if image data is removed while destruction of ImageDataItem or not.
   //## @ingroup Data
   class MITKCORE_EXPORT ImageDataItem : public itk::LightObject
   {
     friend class ImageAccessorBase;
     friend class ImageWriteAccessor;
     friend class ImageReadAccessor;
 
     template <class TPixel, unsigned int VDimension>
     friend class ImagePixelAccessor;
 
     friend class Image;
 
     //  template<class TOutputImage>
     //  friend class ImageToItk;
 
   public:
     typedef itk::SmartPointer<mitk::Image> ImagePointer;
     typedef itk::SmartPointer<const mitk::Image> ImageConstPointer;
 
     mitkClassMacroItkParent(ImageDataItem, itk::LightObject);
 
     itkCloneMacro(ImageDataItem);
     itk::LightObject::Pointer InternalClone() const override;
 
     ImageDataItem(const ImageDataItem &aParent,
                   const mitk::ImageDescriptor::Pointer desc,
                   int timestep,
                   unsigned int dimension,
                   void *data = nullptr,
                   bool manageMemory = false,
                   size_t offset = 0);
 
     ~ImageDataItem() override;
 
     ImageDataItem(const mitk::ImageDescriptor::Pointer desc, int timestep, void *data, bool manageMemory);
 
     ImageDataItem(const mitk::PixelType &type,
                   int timestep,
                   unsigned int dimension,
                   unsigned int *dimensions,
                   void *data,
                   bool manageMemory);
 
     ImageDataItem(const ImageDataItem &other);
 
-    /**
-    \deprecatedSince{2012_09} Please use image accessors instead: See Doxygen/Related-Pages/Concepts/Image. This method
-    can be replaced by ImageWriteAccessor::GetData() or ImageReadAccessor::GetData() */
-    DEPRECATED(void *GetData() const) { return m_Data; }
     bool IsComplete() const { return m_IsComplete; }
     void SetComplete(bool complete) { m_IsComplete = complete; }
     int GetOffset() const { return m_Offset; }
     PixelType GetPixelType() const { return *m_PixelType; }
     void SetTimestep(int t) { m_Timestep = t; }
     void SetManageMemory(bool b) { m_ManageMemory = b; }
     int GetDimension() const { return m_Dimension; }
     int GetDimension(int i) const
     {
       int returnValue = 0;
 
       // return the true size if dimension available
       if (i < (int)m_Dimension)
         returnValue = m_Dimensions[i];
 
       return returnValue;
     }
 
     ImageDataItem::ConstPointer GetParent() const { return m_Parent; }
     /**
      * @brief GetVtkImageAccessor Returns a vtkImageDataItem, if none is present, a new one is constructed by the
      * ConstructVtkImageData method.
      *                            Due to historical development of MITK and VTK, the vtkImage origin is explicitly set
      * to
      * (0, 0, 0) for 3D images.
      *                            See bug 5050 for detailed information.
      * @return Pointer of type ImageVtkReadAccessor
      */
     ImageVtkReadAccessor *GetVtkImageAccessor(ImageConstPointer) const;
     ImageVtkWriteAccessor *GetVtkImageAccessor(ImagePointer);
 
     // Returns if image data should be deleted on destruction of ImageDataItem.
     bool GetManageMemory() const { return m_ManageMemory; }
     virtual void ConstructVtkImageData(ImageConstPointer) const;
 
     size_t GetSize() const { return m_Size; }
     virtual void Modified() const;
 
   protected:
+
+    /**Helper function to allow friend classes to access m_Data without changing their code.
+    * Moved to protected visibility because only friends are allowed to access m_Data directly.
+    * Other classes should used ImageWriteAccessor::GetData() or ImageReadAccessor::GetData()
+    * to get access.*/
+    void* GetData() const { return m_Data; }
+
     unsigned char *m_Data;
 
     PixelType *m_PixelType;
 
     bool m_ManageMemory;
 
     mutable vtkImageData *m_VtkImageData;
     mutable ImageVtkReadAccessor *m_VtkImageReadAccessor;
     ImageVtkWriteAccessor *m_VtkImageWriteAccessor;
     int m_Offset;
 
     bool m_IsComplete;
 
     size_t m_Size;
 
   private:
     void ComputeItemSize(const unsigned int *dimensions, unsigned int dimension);
 
     ImageDataItem::ConstPointer m_Parent;
 
     unsigned int m_Dimension;
 
     unsigned int m_Dimensions[MAX_IMAGE_DIMENSIONS];
 
     int m_Timestep;
   };
 
 } // namespace mitk
 
 #endif /* IMAGEDATAITEM_H */
diff --git a/Modules/Core/include/mitkPointSetVtkMapper2D.h b/Modules/Core/include/mitkPointSetVtkMapper2D.h
index 08a0524cc5..f8520be771 100644
--- a/Modules/Core/include/mitkPointSetVtkMapper2D.h
+++ b/Modules/Core/include/mitkPointSetVtkMapper2D.h
@@ -1,238 +1,238 @@
 /*============================================================================
 
 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 mitkPointSetVtkMapper2D_h
 #define mitkPointSetVtkMapper2D_h
 
 #include "mitkBaseRenderer.h"
 #include "mitkLocalStorageHandler.h"
 #include "mitkVtkMapper.h"
 #include <MitkCoreExports.h>
 #include <mitkPointSetShapeProperty.h>
 
 // VTK
 #include <vtkSmartPointer.h>
 class vtkActor;
 class vtkPropAssembly;
 class vtkPolyData;
 class vtkPolyDataMapper;
 class vtkGlyphSource2D;
 class vtkGlyph3D;
 class vtkFloatArray;
 class vtkCellArray;
 
 namespace mitk
 {
   class PointSet;
 
   /**
   * @brief Vtk-based 2D mapper for PointSet
   *
   * Due to the need of different colors for selected
   * and unselected points and the facts, that we also have a contour and
   * labels for the points, the vtk structure is build up the following way:
   *
   * We have three PolyData, one selected, and one unselected and one
   * for a contour between the points. Each one is connected to an own
   * PolyDataMapper and an Actor. The different color for the unselected and
   * selected state and for the contour is read from properties.
   *
   * This mapper has several additional functionalities, such as rendering
   * a contour between points, calculating and displaying distances or angles
   * between points.
   *
   * @section mitkPointSetVtkMapper2D_point_rep Point Representation
   *
   * The points are displayed as small glyphs of configurable shape
   * (see property "PointSet.2D.shape"). The size of these glyphs
   * is given in world units. That means, the size or shape of those
   * glyphs is independent of the BaseGeometry object that you assign
   * to the PointSet. As for all other objects, _positions_ of points
   * will be transformed into the world via the Geometry's index-to-world
   * transform.
   *
   * Then the three Actors are combined inside a vtkPropAssembly and this
   * object is returned in GetProp() and so hooked up into the rendering
   * pipeline.
   *
   * @section mitkPointSetVtkMapper2D_propertires Applicable Properties
   *
   * Properties that can be set for point sets and influence the PointSetVTKMapper2D are:
   *
   *   - \b "line width": (IntProperty 2)                      // line width of the line from one point to another
   *   - \b "point line width": (IntProperty 1)                // line width of the cross marking a point
   *   - \b "point 2D size": (FloatProperty 6)                 // size of the glyph marking a point (diameter, in world
   * units!)
   *   - \b "show contour": (BoolProperty false)               // enable contour rendering between points (lines)
   *   - \b "close contour": (BoolProperty false)              // if enabled, the open strip is closed (first point
   * connected with last point)
   *   - \b "show points": (BoolProperty true)                 // show or hide points
   *   - \b "show distances": (BoolProperty false)             // show or hide distance measure
   *   - \b "distance decimal digits": (IntProperty 2)         // set the number of decimal digits to be shown when
   * rendering the distance information
   *   - \b "show angles": (BoolProperty false)                // show or hide angle measurement
   *   - \b "show distant lines": (BoolProperty false)         // show the line between to points from a distant view
   * (equals "always on top" option)
   *   - \b "layer": (IntProperty 1)                           // default is drawing pointset above images (they have a
   * default layer of 0)
   *   - \b "PointSet.2D.shape" (EnumerationProperty Cross)    // provides different shapes marking a point
   *       0 = "None", 1 = "Vertex", 2 = "Dash", 3 = "Cross", 4 = "ThickCross", 5 = "Triangle", 6 = "Square", 7 =
   * "Circle",
   *       8 = "Diamond", 9 = "Arrow", 10 = "ThickArrow", 11 = "HookedArrow", 12 = "Cross"
   *   - \b "PointSet.2D.fill shape": (BoolProperty false)     // fill or do not fill the glyph shape
   *   - \b "Pointset.2D.distance to plane": (FloatProperty 4.0) //In the 2D render window, points are rendered which lie
   * within a certain distance
   *                                                             to the current plane. They are projected on the current
   * plane and scaled according to their distance.
   *                                                             Point markers appear smaller as the plane moves away
   * from
   * their true location.
   *                                                             The distance threshold can be adjusted by this float
   * property, which ables the user to delineate the points
   *                                                             that lie exactly on the plane. (+/- rounding error)
   *
   * Other Properties used here but not defined in this class:
   *
   *   - \b "selectedcolor": (ColorProperty (1.0f, 0.0f, 0.0f))  // default color of the selected pointset e.g. the
   * current
   * point is red
   *   - \b "contourcolor" : (ColorProperty (1.0f, 0.0f, 0.0f))  // default color for the contour is red
   *   - \b "color": (ColorProperty (1.0f, 1.0f, 0.0f))          // default color of the (unselected) pointset is yellow
   *   - \b "opacity": (FloatProperty 1.0)                       // opacity of point set, contours
   *   - \b "label": (StringProperty nullptr)     // a label can be defined for each point, which is rendered in proximity
   * to
   * the point
   *
   * @ingroup Mapper
   */
   class MITKCORE_EXPORT PointSetVtkMapper2D : public VtkMapper
   {
   public:
     mitkClassMacro(PointSetVtkMapper2D, VtkMapper);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self);
 
       virtual const mitk::PointSet *GetInput() const;
 
     /** \brief returns the a prop assembly */
     vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override;
 
     /** \brief set the default properties for this mapper */
     static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false);
 
     /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */
     class LocalStorage : public mitk::Mapper::BaseLocalStorage
     {
     public:
       /* constructor */
       LocalStorage();
 
       /* destructor */
       ~LocalStorage() override;
 
       // points
       vtkSmartPointer<vtkPoints> m_UnselectedPoints;
       vtkSmartPointer<vtkPoints> m_SelectedPoints;
       vtkSmartPointer<vtkPoints> m_ContourPoints;
 
       // scales
       vtkSmartPointer<vtkFloatArray> m_UnselectedScales;
       vtkSmartPointer<vtkFloatArray> m_SelectedScales;
 
       // distances
       vtkSmartPointer<vtkFloatArray> m_DistancesBetweenPoints;
 
       // lines
       vtkSmartPointer<vtkCellArray> m_ContourLines;
 
       // glyph source (provides different shapes for the points)
       vtkSmartPointer<vtkGlyphSource2D> m_UnselectedGlyphSource2D;
       vtkSmartPointer<vtkGlyphSource2D> m_SelectedGlyphSource2D;
 
       // glyph
       vtkSmartPointer<vtkGlyph3D> m_UnselectedGlyph3D;
       vtkSmartPointer<vtkGlyph3D> m_SelectedGlyph3D;
 
       // polydata
       vtkSmartPointer<vtkPolyData> m_VtkUnselectedPointListPolyData;
       vtkSmartPointer<vtkPolyData> m_VtkSelectedPointListPolyData;
       vtkSmartPointer<vtkPolyData> m_VtkContourPolyData;
 
       // actor
       vtkSmartPointer<vtkActor> m_UnselectedActor;
       vtkSmartPointer<vtkActor> m_SelectedActor;
       vtkSmartPointer<vtkActor> m_ContourActor;
       vtkSmartPointer<vtkTextActor> m_VtkTextActor;
 
       std::vector<vtkSmartPointer<vtkTextActor>> m_VtkTextLabelActors;
       std::vector<vtkSmartPointer<vtkTextActor>> m_VtkTextDistanceActors;
       std::vector<vtkSmartPointer<vtkTextActor>> m_VtkTextAngleActors;
 
       // mappers
       vtkSmartPointer<vtkPolyDataMapper> m_VtkUnselectedPolyDataMapper;
       vtkSmartPointer<vtkPolyDataMapper> m_VtkSelectedPolyDataMapper;
       vtkSmartPointer<vtkPolyDataMapper> m_VtkContourPolyDataMapper;
 
       // propassembly
       vtkSmartPointer<vtkPropAssembly> m_PropAssembly;
     };
 
     /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */
     mitk::LocalStorageHandler<LocalStorage> m_LSH;
 
   protected:
     /* constructor */
     PointSetVtkMapper2D();
 
     /* destructor */
     ~PointSetVtkMapper2D() override;
 
     /* \brief Applies the color and opacity properties and calls CreateVTKRenderObjects */
     void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override;
     /* \brief Called in mitk::Mapper::Update
-    * If TimeSlicedGeometry or time step is not valid of point set: reset mapper so that nothing is
+    * If TimeGeometry or time step is not valid of point set: reset mapper so that nothing is
     * displayed e.g. toggle visiblity of the propassembly */
     void ResetMapper(BaseRenderer *renderer) override;
 
     /* \brief Fills the vtk objects, thus it is only called when the point set has been changed.
    * This function iterates over the input point set and determines the glyphs which lie in a specific
    * range around the current slice. Those glyphs are rendered using a specific shape defined in vtk glyph source
    * to mark each point. The shape can be changed in MITK using the property "PointSet.2D.shape".
    *
    * There were issues when rendering vtk glyphs in the 2D-render windows. By default, the glyphs are
    * rendered within the x-y plane in each 2D-render window, so you would only see them from the
    * side in the saggital and coronal 2D-render window. The solution to this is to rotate the glyphs in order
    * to be ortogonal to the current view vector. To achieve this, the rotation (vtktransform) of the current
    * PlaneGeometry is applied to the orienation of the glyphs. */
     virtual void CreateVTKRenderObjects(mitk::BaseRenderer *renderer);
 
     // member variables holding the current value of the properties used in this mapper
     bool m_ShowContour;           // "show contour" property
     bool m_CloseContour;          // "close contour" property
     bool m_ShowPoints;            // "show points" property
     bool m_ShowDistances;         // "show distances" property
     int m_DistancesDecimalDigits; // "distance decimal digits" property
     bool m_ShowAngles;            // "show angles" property
     bool m_ShowDistantLines;      // "show distant lines" property
     int m_LineWidth;              // "line width" property
     int m_PointLineWidth;         // "point line width" property
     float m_Point2DSize;          // "point 2D size" property
     int m_IDShapeProperty;        // ID for mitkPointSetShape Enumeration Property "Pointset.2D.shape"
     bool m_FillShape;             // "Pointset.2D.fill shape" property
     float m_DistanceToPlane;      // "Pointset.2D.distance to plane" property
   };
 
 } // namespace mitk
 
 #endif /* mitkPointSetVtkMapper2D_h */
diff --git a/Modules/Core/include/mitkSurfaceVtkMapper2D.h b/Modules/Core/include/mitkSurfaceVtkMapper2D.h
index 1a0e357f42..9e52cbc226 100644
--- a/Modules/Core/include/mitkSurfaceVtkMapper2D.h
+++ b/Modules/Core/include/mitkSurfaceVtkMapper2D.h
@@ -1,215 +1,215 @@
 /*============================================================================
 
 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 mitkSurfaceVtkMapper2D_h
 #define mitkSurfaceVtkMapper2D_h
 
 #include "mitkBaseRenderer.h"
 #include "mitkLocalStorageHandler.h"
 #include "mitkVtkMapper.h"
 #include <MitkCoreExports.h>
 
 // VTK
 #include <vtkSmartPointer.h>
 class vtkAssembly;
 class vtkCutter;
 class vtkPlane;
 class vtkLookupTable;
 class vtkGlyph3D;
 class vtkArrowSource;
 class vtkReverseSense;
 
 namespace mitk
 {
   class Surface;
 
   /**
     * @brief Vtk-based mapper for cutting 2D slices out of Surfaces.
     *
     * The mapper uses a vtkCutter filter to cut out slices (contours) of the 3D
     * volume and render these slices as vtkPolyData. The data is transformed
     * according to its geometry before cutting, to support the geometry concept
     * of MITK.
     *
     * Properties:
     * \b Surface.2D.Line Width: Thickness of the rendered lines in 2D.
     * \b Surface.2D.Normals.Draw Normals: enables drawing of normals as 3D arrows
     * in the 2D render window. The normals are created with a vtkGlyph3D from
     * the vtkPolyData.
     * \b Surface.2D.Normals.Draw Inverse Normals: same as normals, but in the
     * other direction. The inverse normals are computed with a vtkReverseSense
     * filter.
     * \b Surface.2D.Normals.(Inverse) Normals Color: Color of the (inverse) normals.
     * \b Surface.2D.Normals.(Inverse) Normals Scale Factor: Regulates the size of the normals.
     *
     * @ingroup Mapper
     */
   class MITKCORE_EXPORT SurfaceVtkMapper2D : public VtkMapper
   {
   public:
     mitkClassMacro(SurfaceVtkMapper2D, VtkMapper);
 
     itkFactorylessNewMacro(Self);
 
     itkCloneMacro(Self);
 
       virtual const mitk::Surface *GetInput() const;
 
     /** \brief returns the prop assembly */
     vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) override;
 
     /** \brief set the default properties for this mapper */
     static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer = nullptr, bool overwrite = false);
 
     /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */
     class LocalStorage : public mitk::Mapper::BaseLocalStorage
     {
     public:
       /** \brief Timestamp of last update of stored data. */
       itk::TimeStamp m_LastUpdateTime;
       /**
          * @brief m_PropAssembly Contains all vtkProps for the final rendering.
          *
          * Consists of 3 actors:
          * The surface cut (the slice from the 3D surface).
          * The normals and the inverse normals.
          */
       vtkSmartPointer<vtkAssembly> m_PropAssembly;
 
       /**
        * @brief m_Actor actor for the surface cut.
        */
       vtkSmartPointer<vtkActor> m_Actor;
       /**
        * @brief m_NormalActor actor for the normals.
        */
       vtkSmartPointer<vtkActor> m_NormalActor;
       /**
        * @brief m_InverseNormalActor actor for the inverse normals.
        */
       vtkSmartPointer<vtkActor> m_InverseNormalActor;
       /**
          * @brief m_Mapper VTK mapper for all types of 2D polydata e.g. werewolves.
          */
       vtkSmartPointer<vtkPolyDataMapper> m_Mapper;
       /**
          * @brief m_Cutter Filter to cut out the 2D slice.
          */
       vtkSmartPointer<vtkCutter> m_Cutter;
       /**
          * @brief m_CuttingPlane The plane where to cut off the 2D slice.
          */
       vtkSmartPointer<vtkPlane> m_CuttingPlane;
 
       /**
        * @brief m_NormalMapper Mapper for the normals.
        */
       vtkSmartPointer<vtkPolyDataMapper> m_NormalMapper;
 
       /**
        * @brief m_InverseNormalMapper Mapper for the inverse normals.
        */
       vtkSmartPointer<vtkPolyDataMapper> m_InverseNormalMapper;
 
       /**
        * @brief m_NormalGlyph Glyph for creating normals.
        */
       vtkSmartPointer<vtkGlyph3D> m_NormalGlyph;
 
       /**
        * @brief m_InverseNormalGlyph Glyph for creating inverse normals.
        */
       vtkSmartPointer<vtkGlyph3D> m_InverseNormalGlyph;
 
       /**
        * @brief m_ArrowSource Arrow representation of the normals.
        */
       vtkSmartPointer<vtkArrowSource> m_ArrowSource;
 
       /**
        * @brief m_ReverseSense Filter to invert the normals.
        */
       vtkSmartPointer<vtkReverseSense> m_ReverseSense;
 
       /** \brief Default constructor of the local storage. */
       LocalStorage();
       /** \brief Default deconstructor of the local storage. */
       ~LocalStorage() override;
     };
 
     /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */
     mitk::LocalStorageHandler<LocalStorage> m_LSH;
 
     /**
      * @brief UpdateVtkTransform Overwrite the method of the base class.
      *
      * The base class transforms the actor according to the respective
      * geometry which is correct for most cases. This mapper, however,
      * uses a vtkCutter to cut out a contour. To cut out the correct
      * contour, the data has to be transformed beforehand. Else the
      * current plane geometry will point the cutter to en empty location
      * (if the surface does have a geometry, which is a rather rare case).
      */
     void UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) override {}
   protected:
     /**
        * @brief SurfaceVtkMapper2D default constructor.
        */
     SurfaceVtkMapper2D();
 
     /**
        * @brief ~SurfaceVtkMapper2D default destructor.
        */
     ~SurfaceVtkMapper2D() override;
 
     /**
        * @brief GenerateDataForRenderer produces all the data.
        * @param renderer The respective renderer of the mitkRenderWindow.
        */
     void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override;
 
     /**
        * @brief ResetMapper Called in mitk::Mapper::Update to hide objects.
-       * If TimeSlicedGeometry or time step is not valid, reset the mapper.
+       * If TimeGeometry or time step is not valid, reset the mapper.
        * so that nothing is displayed e.g. toggle visiblity of the propassembly.
        *
        * @param renderer The respective renderer of the mitkRenderWindow.
        */
     void ResetMapper(BaseRenderer *renderer) override;
 
     /**
      * @brief Updates legacy properties to current behavior/interpretation.
      * @param properties The property list which should be adapted to new behaviour.
      *
      * Whenever a mapper decides to change its property types or its
      * interpretation of certain values, it should add something to this
      * method and call it before methods like ApplyProperties();
      *
      * This is particularly helpful when dealing with data from
      * archive/scene files that were created before changes.
      */
     virtual void FixupLegacyProperties(PropertyList *properties);
 
     /**
      * @brief ApplyAllProperties Pass all the properties to VTK.
      * @param renderer The respective renderer of the mitkRenderWindow.
      */
     void ApplyAllProperties(BaseRenderer *renderer);
 
     /**
        * @brief Update Check if data should be generated.
        * @param renderer The respective renderer of the mitkRenderWindow.
        */
     void Update(BaseRenderer *renderer) override;
   };
 } // namespace mitk
 #endif /* mitkSurfaceVtkMapper2D_h */
diff --git a/Modules/Core/include/mitkTimeSlicedGeometry.h b/Modules/Core/include/mitkTimeSlicedGeometry.h
deleted file mode 100644
index 6d350b4689..0000000000
--- a/Modules/Core/include/mitkTimeSlicedGeometry.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*============================================================================
-
-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 mitkTimeSlicedGeometry_h
-#define mitkTimeSlicedGeometry_h
-
-#include <mitkCommon.h>
-
-namespace mitk
-{
-  /**
-  * \deprecatedSince{2013_09} Please use TimeGeometry instead. For more information see
-  * http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201
-  */
-  class TimeSlicedGeometry
-  {
-    DEPRECATED(TimeSlicedGeometry());
-  };
-}
-
-#endif
diff --git a/Modules/Core/src/DataManagement/mitkImage.cpp b/Modules/Core/src/DataManagement/mitkImage.cpp
index 4ed855b751..251e1ca36f 100644
--- a/Modules/Core/src/DataManagement/mitkImage.cpp
+++ b/Modules/Core/src/DataManagement/mitkImage.cpp
@@ -1,1547 +1,1369 @@
 /*============================================================================
 
 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.
 
 ============================================================================*/
 
 // MITK
 #include "mitkImage.h"
 #include "mitkCompareImageDataFilter.h"
 #include "mitkImageStatisticsHolder.h"
 #include "mitkImageVtkReadAccessor.h"
 #include "mitkImageVtkWriteAccessor.h"
 #include "mitkPixelTypeMultiplex.h"
 #include <mitkProportionalTimeGeometry.h>
 
 // VTK
 #include <vtkImageData.h>
 
 // ITK
 #include <itkMutexLockHolder.h>
 
 // Other
 #include <cmath>
 
 #define FILL_C_ARRAY(_arr, _size, _value)                                                                              \
   for (unsigned int i = 0u; i < _size; i++)                                                                            \
                                                                                                                        \
   {                                                                                                                    \
     _arr[i] = _value;                                                                                                  \
   }
 
 mitk::Image::Image()
   : m_Dimension(0),
     m_Dimensions(nullptr),
     m_ImageDescriptor(nullptr),
     m_OffsetTable(nullptr),
     m_CompleteData(nullptr),
     m_ImageStatistics(nullptr)
 {
   m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS];
   FILL_C_ARRAY(m_Dimensions, MAX_IMAGE_DIMENSIONS, 0u);
 
   m_Initialized = false;
 }
 
 mitk::Image::Image(const Image &other)
   : SlicedData(other),
     m_Dimension(0),
     m_Dimensions(nullptr),
     m_ImageDescriptor(nullptr),
     m_OffsetTable(nullptr),
     m_CompleteData(nullptr),
     m_ImageStatistics(nullptr)
 {
   m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS];
   FILL_C_ARRAY(m_Dimensions, MAX_IMAGE_DIMENSIONS, 0u);
 
   this->Initialize(other.GetPixelType(), other.GetDimension(), other.GetDimensions());
 
   // Since the above called "Initialize" method doesn't take the geometry into account we need to set it
   // here manually
   TimeGeometry::Pointer cloned = other.GetTimeGeometry()->Clone();
   this->SetTimeGeometry(cloned.GetPointer());
 
   if (this->GetDimension() > 3)
   {
     const unsigned int time_steps = this->GetDimension(3);
 
     for (unsigned int i = 0u; i < time_steps; ++i)
     {
       ImageDataItemPointer volume = other.GetVolumeData(i);
 
       this->SetVolume(volume->GetData(), i);
     }
   }
   else
   {
     ImageDataItemPointer volume = other.GetVolumeData(0);
 
     this->SetVolume(volume->GetData(), 0);
   }
 }
 
 mitk::Image::~Image()
 {
   this->Clear();
 
   m_ReferenceCount = 3;
   m_ReferenceCount = 0;
 
   delete[] m_OffsetTable;
   delete m_ImageStatistics;
 }
 
 const mitk::PixelType mitk::Image::GetPixelType(int n) const
 {
   return this->m_ImageDescriptor->GetChannelTypeById(n);
 }
 
 unsigned int mitk::Image::GetDimension() const
 {
   return m_Dimension;
 }
 
 unsigned int mitk::Image::GetDimension(int i) const
 {
   if ((i >= 0) && (i < (int)m_Dimension))
     return m_Dimensions[i];
   return 1;
 }
 
-void *mitk::Image::GetData()
-{
-  if (m_Initialized == false)
-  {
-    if (GetSource().IsNull())
-      return nullptr;
-    if (GetSource()->Updating() == false)
-      GetSource()->UpdateOutputInformation();
-  }
-  m_CompleteData = GetChannelData();
-
-  // update channel's data
-  // if data was not available at creation point, the m_Data of channel descriptor is nullptr
-  // if data present, it won't be overwritten
-  m_ImageDescriptor->GetChannelDescriptor(0).SetData(m_CompleteData->GetData());
-
-  return m_CompleteData->GetData();
-}
-
 template <class T>
 void AccessPixel(const mitk::PixelType ptype, void *data, const unsigned int offset, double &value)
 {
   value = 0.0;
   if (data == nullptr)
     return;
 
   if (ptype.GetBpe() != 24)
   {
     value = (double)(((T *)data)[offset]);
   }
   else
   {
     const unsigned int rgboffset = offset;
 
     double returnvalue = (((T *)data)[rgboffset]);
     returnvalue += (((T *)data)[rgboffset + 1]);
     returnvalue += (((T *)data)[rgboffset + 2]);
     value = returnvalue;
   }
 }
 
-double mitk::Image::GetPixelValueByIndex(const itk::Index<3> &position, unsigned int timestep, unsigned int component)
-{
-  double value = 0;
-  if (this->GetTimeSteps() < timestep)
-  {
-    timestep = this->GetTimeSteps();
-  }
-
-  value = 0.0;
-
-  const unsigned int *imageDims = this->m_ImageDescriptor->GetDimensions();
-  const mitk::PixelType ptype = this->m_ImageDescriptor->GetChannelTypeById(0);
-
-  // Comparison ?>=0 not needed since all position[i] and timestep are unsigned int
-  // (position[0]>=0 && position[1] >=0 && position[2]>=0 && timestep>=0)
-  // bug-11978 : we still need to catch index with negative values
-  if (position[0] < 0 || position[1] < 0 || position[2] < 0)
-  {
-    MITK_WARN << "Given position (" << position << ") is out of image range, returning 0.";
-  }
-  // check if the given position is inside the index range of the image, the 3rd dimension needs to be compared only if
-  // the dimension is not 0
-  else if ((unsigned int)position[0] >= imageDims[0] || (unsigned int)position[1] >= imageDims[1] ||
-           (imageDims[2] && (unsigned int)position[2] >= imageDims[2]))
-  {
-    MITK_WARN << "Given position (" << position << ") is out of image range, returning 0.";
-  }
-  else
-  {
-    const unsigned int offset = component +
-                                ptype.GetNumberOfComponents() * (position[0] + position[1] * imageDims[0] +
-                                                                 position[2] * imageDims[0] * imageDims[1] +
-                                                                 timestep * imageDims[0] * imageDims[1] * imageDims[2]);
-
-    mitkPixelTypeMultiplex3(AccessPixel, ptype, this->GetData(), offset, value);
-  }
-
-  return value;
-}
-
-double mitk::Image::GetPixelValueByWorldCoordinate(const mitk::Point3D &position,
-                                                   unsigned int timestep,
-                                                   unsigned int component)
-{
-  double value = 0.0;
-  if (this->GetTimeSteps() < timestep)
-  {
-    timestep = this->GetTimeSteps();
-  }
-
-  itk::Index<3> itkIndex;
-  this->GetGeometry()->WorldToIndex(position, itkIndex);
-
-  value = this->GetPixelValueByIndex(itkIndex, timestep, component);
-
-  return value;
-}
-
 vtkImageData *mitk::Image::GetVtkImageData(int t, int n)
 {
   if (m_Initialized == false)
   {
     if (GetSource().IsNull())
       return nullptr;
     if (GetSource()->Updating() == false)
       GetSource()->UpdateOutputInformation();
   }
   ImageDataItemPointer volume = GetVolumeData(t, n);
   return volume.GetPointer() == nullptr ? nullptr : volume->GetVtkImageAccessor(this)->GetVtkImageData();
 }
 
 const vtkImageData *mitk::Image::GetVtkImageData(int t, int n) const
 {
   if (m_Initialized == false)
   {
     if (GetSource().IsNull())
       return nullptr;
     if (GetSource()->Updating() == false)
       GetSource()->UpdateOutputInformation();
   }
   ImageDataItemPointer volume = GetVolumeData(t, n);
   return volume.GetPointer() == nullptr ? nullptr : volume->GetVtkImageAccessor(this)->GetVtkImageData();
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::GetSliceData(
   int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return GetSliceData_unlocked(s, t, n, data, importMemoryManagement);
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::GetSliceData_unlocked(
   int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   if (IsValidSlice(s, t, n) == false)
     return nullptr;
 
   const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
 
   // slice directly available?
   int pos = GetSliceIndex(s, t, n);
   if (m_Slices[pos].GetPointer() != nullptr)
   {
     return m_Slices[pos];
   }
 
   // is slice available as part of a volume that is available?
   ImageDataItemPointer sl, ch, vol;
   vol = m_Volumes[GetVolumeIndex(t, n)];
   if ((vol.GetPointer() != nullptr) && (vol->IsComplete()))
   {
     sl = new ImageDataItem(*vol,
                            m_ImageDescriptor,
                            t,
                            2,
                            data,
                            importMemoryManagement == ManageMemory,
                            ((size_t)s) * m_OffsetTable[2] * (ptypeSize));
     sl->SetComplete(true);
     return m_Slices[pos] = sl;
   }
 
   // is slice available as part of a channel that is available?
   ch = m_Channels[n];
   if ((ch.GetPointer() != nullptr) && (ch->IsComplete()))
   {
     sl = new ImageDataItem(*ch,
                            m_ImageDescriptor,
                            t,
                            2,
                            data,
                            importMemoryManagement == ManageMemory,
                            (((size_t)s) * m_OffsetTable[2] + ((size_t)t) * m_OffsetTable[3]) * (ptypeSize));
     sl->SetComplete(true);
     return m_Slices[pos] = sl;
   }
 
   // slice is unavailable. Can we calculate it?
   if ((GetSource().IsNotNull()) && (GetSource()->Updating() == false))
   {
     // ... wir mussen rechnen!!! ....
     m_RequestedRegion.SetIndex(0, 0);
     m_RequestedRegion.SetIndex(1, 0);
     m_RequestedRegion.SetIndex(2, s);
     m_RequestedRegion.SetIndex(3, t);
     m_RequestedRegion.SetIndex(4, n);
     m_RequestedRegion.SetSize(0, m_Dimensions[0]);
     m_RequestedRegion.SetSize(1, m_Dimensions[1]);
     m_RequestedRegion.SetSize(2, 1);
     m_RequestedRegion.SetSize(3, 1);
     m_RequestedRegion.SetSize(4, 1);
     m_RequestedRegionInitialized = true;
     GetSource()->Update();
     if (IsSliceSet_unlocked(s, t, n))
       // yes: now we can call ourselves without the risk of a endless loop (see "if" above)
       return GetSliceData_unlocked(s, t, n, data, importMemoryManagement);
     else
       return nullptr;
   }
   else
   {
     ImageDataItemPointer item = AllocateSliceData_unlocked(s, t, n, data, importMemoryManagement);
     item->SetComplete(true);
     return item;
   }
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::GetVolumeData(int t,
                                                              int n,
                                                              void *data,
                                                              ImportMemoryManagementType importMemoryManagement) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return GetVolumeData_unlocked(t, n, data, importMemoryManagement);
 }
 mitk::Image::ImageDataItemPointer mitk::Image::GetVolumeData_unlocked(
   int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   if (IsValidVolume(t, n) == false)
     return nullptr;
 
   ImageDataItemPointer ch, vol;
 
   // volume directly available?
   int pos = GetVolumeIndex(t, n);
   vol = m_Volumes[pos];
   if ((vol.GetPointer() != nullptr) && (vol->IsComplete()))
     return vol;
 
   const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
 
   // is volume available as part of a channel that is available?
   ch = m_Channels[n];
   if ((ch.GetPointer() != nullptr) && (ch->IsComplete()))
   {
     vol = new ImageDataItem(*ch,
                             m_ImageDescriptor,
                             t,
                             3,
                             data,
                             importMemoryManagement == ManageMemory,
                             (((size_t)t) * m_OffsetTable[3]) * (ptypeSize));
     vol->SetComplete(true);
     return m_Volumes[pos] = vol;
   }
 
   // let's see if all slices of the volume are set, so that we can (could) combine them to a volume
   bool complete = true;
   unsigned int s;
   for (s = 0; s < m_Dimensions[2]; ++s)
   {
     if (m_Slices[GetSliceIndex(s, t, n)].GetPointer() == nullptr)
     {
       complete = false;
       break;
     }
   }
   if (complete)
   {
     // if there is only single slice we do not need to combine anything
     if (m_Dimensions[2] <= 1)
     {
       ImageDataItemPointer sl;
       sl = GetSliceData_unlocked(0, t, n, data, importMemoryManagement);
       vol = new ImageDataItem(*sl, m_ImageDescriptor, t, 3, data, importMemoryManagement == ManageMemory);
       vol->SetComplete(true);
     }
     else
     {
       mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(n);
 
       vol = m_Volumes[pos];
       // ok, let's combine the slices!
       if (vol.GetPointer() == nullptr)
       {
         vol = new ImageDataItem(chPixelType, t, 3, m_Dimensions, nullptr, true);
       }
       vol->SetComplete(true);
       size_t size = m_OffsetTable[2] * (ptypeSize);
       for (s = 0; s < m_Dimensions[2]; ++s)
       {
         int posSl;
         ImageDataItemPointer sl;
         posSl = GetSliceIndex(s, t, n);
 
         sl = m_Slices[posSl];
         if (sl->GetParent() != vol)
         {
           // copy data of slices in volume
           size_t offset = ((size_t)s) * size;
           std::memcpy(static_cast<char *>(vol->GetData()) + offset, sl->GetData(), size);
 
           // FIXME mitkIpPicDescriptor * pic = sl->GetPicDescriptor();
 
           // replace old slice with reference to volume
           sl = new ImageDataItem(
             *vol, m_ImageDescriptor, t, 2, data, importMemoryManagement == ManageMemory, ((size_t)s) * size);
           sl->SetComplete(true);
           // mitkIpFuncCopyTags(sl->GetPicDescriptor(), pic);
           m_Slices[posSl] = sl;
         }
       }
       // if(vol->GetPicDescriptor()->info->tags_head==nullptr)
       //  mitkIpFuncCopyTags(vol->GetPicDescriptor(), m_Slices[GetSliceIndex(0,t,n)]->GetPicDescriptor());
     }
     return m_Volumes[pos] = vol;
   }
 
   // volume is unavailable. Can we calculate it?
   if ((GetSource().IsNotNull()) && (GetSource()->Updating() == false))
   {
     // ... wir muessen rechnen!!! ....
     m_RequestedRegion.SetIndex(0, 0);
     m_RequestedRegion.SetIndex(1, 0);
     m_RequestedRegion.SetIndex(2, 0);
     m_RequestedRegion.SetIndex(3, t);
     m_RequestedRegion.SetIndex(4, n);
     m_RequestedRegion.SetSize(0, m_Dimensions[0]);
     m_RequestedRegion.SetSize(1, m_Dimensions[1]);
     m_RequestedRegion.SetSize(2, m_Dimensions[2]);
     m_RequestedRegion.SetSize(3, 1);
     m_RequestedRegion.SetSize(4, 1);
     m_RequestedRegionInitialized = true;
     GetSource()->Update();
     if (IsVolumeSet_unlocked(t, n))
       // yes: now we can call ourselves without the risk of a endless loop (see "if" above)
       return GetVolumeData_unlocked(t, n, data, importMemoryManagement);
     else
       return nullptr;
   }
   else
   {
     ImageDataItemPointer item = AllocateVolumeData_unlocked(t, n, data, importMemoryManagement);
     item->SetComplete(true);
     return item;
   }
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::GetChannelData(int n,
                                                               void *data,
                                                               ImportMemoryManagementType importMemoryManagement) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return GetChannelData_unlocked(n, data, importMemoryManagement);
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::GetChannelData_unlocked(
   int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   if (IsValidChannel(n) == false)
     return nullptr;
   ImageDataItemPointer ch, vol;
   ch = m_Channels[n];
   if ((ch.GetPointer() != nullptr) && (ch->IsComplete()))
     return ch;
 
   // let's see if all volumes are set, so that we can (could) combine them to a channel
   if (IsChannelSet_unlocked(n))
   {
     // if there is only one time frame we do not need to combine anything
     if (m_Dimensions[3] <= 1)
     {
       vol = GetVolumeData_unlocked(0, n, data, importMemoryManagement);
       ch = new ImageDataItem(*vol,
                              m_ImageDescriptor,
                              0,
                              m_ImageDescriptor->GetNumberOfDimensions(),
                              data,
                              importMemoryManagement == ManageMemory);
       ch->SetComplete(true);
     }
     else
     {
       const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
 
       ch = m_Channels[n];
       // ok, let's combine the volumes!
       if (ch.GetPointer() == nullptr)
         ch = new ImageDataItem(this->m_ImageDescriptor, -1, nullptr, true);
       ch->SetComplete(true);
       size_t size = m_OffsetTable[m_Dimension - 1] * (ptypeSize);
       unsigned int t;
       auto slicesIt = m_Slices.begin() + n * m_Dimensions[2] * m_Dimensions[3];
       for (t = 0; t < m_Dimensions[3]; ++t)
       {
         int posVol;
         ImageDataItemPointer vol;
 
         posVol = GetVolumeIndex(t, n);
         vol = GetVolumeData_unlocked(t, n, data, importMemoryManagement);
 
         if (vol->GetParent() != ch)
         {
           // copy data of volume in channel
           size_t offset = ((size_t)t) * m_OffsetTable[3] * (ptypeSize);
           std::memcpy(static_cast<char *>(ch->GetData()) + offset, vol->GetData(), size);
 
           // REVEIW FIX mitkIpPicDescriptor * pic = vol->GetPicDescriptor();
 
           // replace old volume with reference to channel
           vol = new ImageDataItem(*ch, m_ImageDescriptor, t, 3, data, importMemoryManagement == ManageMemory, offset);
           vol->SetComplete(true);
           // mitkIpFuncCopyTags(vol->GetPicDescriptor(), pic);
 
           m_Volumes[posVol] = vol;
 
           // get rid of slices - they may point to old volume
           ImageDataItemPointer dnull = nullptr;
           for (unsigned int i = 0; i < m_Dimensions[2]; ++i, ++slicesIt)
           {
             assert(slicesIt != m_Slices.end());
             *slicesIt = dnull;
           }
         }
       }
       // REVIEW FIX
       //   if(ch->GetPicDescriptor()->info->tags_head==nullptr)
       //     mitkIpFuncCopyTags(ch->GetPicDescriptor(), m_Volumes[GetVolumeIndex(0,n)]->GetPicDescriptor());
     }
     return m_Channels[n] = ch;
   }
 
   // channel is unavailable. Can we calculate it?
   if ((GetSource().IsNotNull()) && (GetSource()->Updating() == false))
   {
     // ... wir muessen rechnen!!! ....
     m_RequestedRegion.SetIndex(0, 0);
     m_RequestedRegion.SetIndex(1, 0);
     m_RequestedRegion.SetIndex(2, 0);
     m_RequestedRegion.SetIndex(3, 0);
     m_RequestedRegion.SetIndex(4, n);
     m_RequestedRegion.SetSize(0, m_Dimensions[0]);
     m_RequestedRegion.SetSize(1, m_Dimensions[1]);
     m_RequestedRegion.SetSize(2, m_Dimensions[2]);
     m_RequestedRegion.SetSize(3, m_Dimensions[3]);
     m_RequestedRegion.SetSize(4, 1);
     m_RequestedRegionInitialized = true;
     GetSource()->Update();
     // did it work?
     if (IsChannelSet_unlocked(n))
       // yes: now we can call ourselves without the risk of a endless loop (see "if" above)
       return GetChannelData_unlocked(n, data, importMemoryManagement);
     else
       return nullptr;
   }
   else
   {
     ImageDataItemPointer item = AllocateChannelData_unlocked(n, data, importMemoryManagement);
     item->SetComplete(true);
     return item;
   }
 }
 
 bool mitk::Image::IsSliceSet(int s, int t, int n) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return IsSliceSet_unlocked(s, t, n);
 }
 
 bool mitk::Image::IsSliceSet_unlocked(int s, int t, int n) const
 {
   if (IsValidSlice(s, t, n) == false)
     return false;
 
   if (m_Slices[GetSliceIndex(s, t, n)].GetPointer() != nullptr)
   {
     return true;
   }
 
   ImageDataItemPointer ch, vol;
   vol = m_Volumes[GetVolumeIndex(t, n)];
   if ((vol.GetPointer() != nullptr) && (vol->IsComplete()))
   {
     return true;
   }
   ch = m_Channels[n];
   if ((ch.GetPointer() != nullptr) && (ch->IsComplete()))
   {
     return true;
   }
   return false;
 }
 
 bool mitk::Image::IsVolumeSet(int t, int n) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return IsVolumeSet_unlocked(t, n);
 }
 
 bool mitk::Image::IsVolumeSet_unlocked(int t, int n) const
 {
   if (IsValidVolume(t, n) == false)
     return false;
   ImageDataItemPointer ch, vol;
 
   // volume directly available?
   vol = m_Volumes[GetVolumeIndex(t, n)];
   if ((vol.GetPointer() != nullptr) && (vol->IsComplete()))
     return true;
 
   // is volume available as part of a channel that is available?
   ch = m_Channels[n];
   if ((ch.GetPointer() != nullptr) && (ch->IsComplete()))
     return true;
 
   // let's see if all slices of the volume are set, so that we can (could) combine them to a volume
   unsigned int s;
   for (s = 0; s < m_Dimensions[2]; ++s)
   {
     if (m_Slices[GetSliceIndex(s, t, n)].GetPointer() == nullptr)
     {
       return false;
     }
   }
   return true;
 }
 
 bool mitk::Image::IsChannelSet(int n) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return IsChannelSet_unlocked(n);
 }
 
 bool mitk::Image::IsChannelSet_unlocked(int n) const
 {
   if (IsValidChannel(n) == false)
     return false;
   ImageDataItemPointer ch, vol;
   ch = m_Channels[n];
   if ((ch.GetPointer() != nullptr) && (ch->IsComplete()))
 
     return true;
   // let's see if all volumes are set, so that we can (could) combine them to a channel
   unsigned int t;
   for (t = 0; t < m_Dimensions[3]; ++t)
   {
     if (IsVolumeSet_unlocked(t, n) == false)
     {
       return false;
     }
   }
   return true;
 }
 
 bool mitk::Image::SetSlice(const void *data, int s, int t, int n)
 {
   // const_cast is no risk for ImportMemoryManagementType == CopyMemory
   return SetImportSlice(const_cast<void *>(data), s, t, n, CopyMemory);
 }
 
 bool mitk::Image::SetVolume(const void *data, int t, int n)
 {
   // const_cast is no risk for ImportMemoryManagementType == CopyMemory
   return SetImportVolume(const_cast<void *>(data), t, n, CopyMemory);
 }
 
 bool mitk::Image::SetChannel(const void *data, int n)
 {
   // const_cast is no risk for ImportMemoryManagementType == CopyMemory
   return SetImportChannel(const_cast<void *>(data), n, CopyMemory);
 }
 
 bool mitk::Image::SetImportSlice(void *data, int s, int t, int n, ImportMemoryManagementType importMemoryManagement)
 {
   if (IsValidSlice(s, t, n) == false)
     return false;
   ImageDataItemPointer sl;
   const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
 
   if (IsSliceSet(s, t, n))
   {
     sl = GetSliceData(s, t, n, data, importMemoryManagement);
     if (sl->GetManageMemory() == false)
     {
       sl = AllocateSliceData(s, t, n, data, importMemoryManagement);
       if (sl.GetPointer() == nullptr)
         return false;
     }
     if (sl->GetData() != data)
       std::memcpy(sl->GetData(), data, m_OffsetTable[2] * (ptypeSize));
     sl->Modified();
     // we have changed the data: call Modified()!
     Modified();
   }
   else
   {
     sl = AllocateSliceData(s, t, n, data, importMemoryManagement);
     if (sl.GetPointer() == nullptr)
       return false;
     if (sl->GetData() != data)
       std::memcpy(sl->GetData(), data, m_OffsetTable[2] * (ptypeSize));
     // we just added a missing slice, which is not regarded as modification.
     // Therefore, we do not call Modified()!
   }
   return true;
 }
 
 bool mitk::Image::SetImportVolume(void *data, int t, int n, ImportMemoryManagementType importMemoryManagement)
 {
   if (IsValidVolume(t, n) == false)
     return false;
 
   const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
   ImageDataItemPointer vol;
   if (IsVolumeSet(t, n))
   {
     vol = GetVolumeData(t, n, data, importMemoryManagement);
     if (vol->GetManageMemory() == false)
     {
       vol = AllocateVolumeData(t, n, data, importMemoryManagement);
       if (vol.GetPointer() == nullptr)
         return false;
     }
     if (vol->GetData() != data)
       std::memcpy(vol->GetData(), data, m_OffsetTable[3] * (ptypeSize));
     vol->Modified();
     vol->SetComplete(true);
     // we have changed the data: call Modified()!
     Modified();
   }
   else
   {
     vol = AllocateVolumeData(t, n, data, importMemoryManagement);
     if (vol.GetPointer() == nullptr)
       return false;
     if (vol->GetData() != data)
     {
       std::memcpy(vol->GetData(), data, m_OffsetTable[3] * (ptypeSize));
     }
     vol->SetComplete(true);
     this->m_ImageDescriptor->GetChannelDescriptor(n).SetData(vol->GetData());
     // we just added a missing Volume, which is not regarded as modification.
     // Therefore, we do not call Modified()!
   }
   return true;
 }
 
 bool mitk::Image::SetImportVolume(const void *const_data, int t, int n)
 {
   return this->SetImportVolume(const_cast<void*>(const_data), t, n, CopyMemory);
 }
 
 bool mitk::Image::SetImportChannel(void *data, int n, ImportMemoryManagementType importMemoryManagement)
 {
   if (IsValidChannel(n) == false)
     return false;
 
   // channel descriptor
 
   const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
 
   ImageDataItemPointer ch;
   if (IsChannelSet(n))
   {
     ch = GetChannelData(n, data, importMemoryManagement);
     if (ch->GetManageMemory() == false)
     {
       ch = AllocateChannelData(n, data, importMemoryManagement);
       if (ch.GetPointer() == nullptr)
         return false;
     }
     if (ch->GetData() != data)
       std::memcpy(ch->GetData(), data, m_OffsetTable[4] * (ptypeSize));
     ch->Modified();
     ch->SetComplete(true);
     // we have changed the data: call Modified()!
     Modified();
   }
   else
   {
     ch = AllocateChannelData(n, data, importMemoryManagement);
     if (ch.GetPointer() == nullptr)
       return false;
     if (ch->GetData() != data)
       std::memcpy(ch->GetData(), data, m_OffsetTable[4] * (ptypeSize));
     ch->SetComplete(true);
 
     this->m_ImageDescriptor->GetChannelDescriptor(n).SetData(ch->GetData());
     // we just added a missing Channel, which is not regarded as modification.
     // Therefore, we do not call Modified()!
   }
   return true;
 }
 
 void mitk::Image::Initialize()
 {
   ImageDataItemPointerArray::iterator it, end;
   for (it = m_Slices.begin(), end = m_Slices.end(); it != end; ++it)
   {
     (*it) = nullptr;
   }
   for (it = m_Volumes.begin(), end = m_Volumes.end(); it != end; ++it)
   {
     (*it) = nullptr;
   }
   for (it = m_Channels.begin(), end = m_Channels.end(); it != end; ++it)
   {
     (*it) = nullptr;
   }
   m_CompleteData = nullptr;
 
   if (m_ImageStatistics == nullptr)
   {
     m_ImageStatistics = new mitk::ImageStatisticsHolder(this);
   }
 
   SetRequestedRegionToLargestPossibleRegion();
 }
 
 void mitk::Image::Initialize(const mitk::ImageDescriptor::Pointer inDesc)
 {
   // store the descriptor
   this->m_ImageDescriptor = inDesc;
 
   // initialize image
   this->Initialize(
     inDesc->GetChannelDescriptor(0).GetPixelType(), inDesc->GetNumberOfDimensions(), inDesc->GetDimensions(), 1);
 }
 
 void mitk::Image::Initialize(const mitk::PixelType &type,
                              unsigned int dimension,
                              const unsigned int *dimensions,
                              unsigned int channels)
 {
   Clear();
 
   m_Dimension = dimension;
 
   if (!dimensions)
     itkExceptionMacro(<< "invalid zero dimension image");
 
   unsigned int i;
   for (i = 0; i < dimension; ++i)
   {
     if (dimensions[i] < 1)
       itkExceptionMacro(<< "invalid dimension[" << i << "]: " << dimensions[i]);
   }
 
   // create new array since the old was deleted
   m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS];
 
   // initialize the first four dimensions to 1, the remaining 4 to 0
   FILL_C_ARRAY(m_Dimensions, 4, 1u);
   FILL_C_ARRAY((m_Dimensions + 4), 4, 0u);
 
   // copy in the passed dimension information
   std::memcpy(m_Dimensions, dimensions, sizeof(unsigned int) * m_Dimension);
 
   this->m_ImageDescriptor = mitk::ImageDescriptor::New();
   this->m_ImageDescriptor->Initialize(this->m_Dimensions, this->m_Dimension);
 
   for (i = 0; i < 4; ++i)
   {
     m_LargestPossibleRegion.SetIndex(i, 0);
     m_LargestPossibleRegion.SetSize(i, m_Dimensions[i]);
   }
   m_LargestPossibleRegion.SetIndex(i, 0);
   m_LargestPossibleRegion.SetSize(i, channels);
 
   if (m_LargestPossibleRegion.GetNumberOfPixels() == 0)
   {
     delete[] m_Dimensions;
     m_Dimensions = nullptr;
     return;
   }
 
   for (unsigned int i = 0u; i < channels; i++)
   {
     this->m_ImageDescriptor->AddNewChannel(type);
   }
 
   PlaneGeometry::Pointer planegeometry = PlaneGeometry::New();
   planegeometry->InitializeStandardPlane(m_Dimensions[0], m_Dimensions[1]);
 
   SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New();
   slicedGeometry->InitializeEvenlySpaced(planegeometry, m_Dimensions[2]);
 
   ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
   timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]);
   for (TimeStepType step = 0; step < timeGeometry->CountTimeSteps(); ++step)
   {
     timeGeometry->GetGeometryForTimeStep(step)->ImageGeometryOn();
   }
   SetTimeGeometry(timeGeometry);
 
   ImageDataItemPointer dnull = nullptr;
 
   m_Channels.assign(GetNumberOfChannels(), dnull);
 
   m_Volumes.assign(GetNumberOfChannels() * m_Dimensions[3], dnull);
 
   m_Slices.assign(GetNumberOfChannels() * m_Dimensions[3] * m_Dimensions[2], dnull);
 
   ComputeOffsetTable();
 
   Initialize();
 
   m_Initialized = true;
 }
 
 void mitk::Image::Initialize(const mitk::PixelType &type,
                              const mitk::BaseGeometry &geometry,
                              unsigned int channels,
                              int tDim)
 {
   mitk::ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
   timeGeometry->Initialize(geometry.Clone(), tDim);
   this->Initialize(type, *timeGeometry, channels, tDim);
 }
 
 void mitk::Image::Initialize(const mitk::PixelType &type,
                              const mitk::TimeGeometry &geometry,
                              unsigned int channels,
                              int tDim)
 {
   unsigned int dimensions[5];
   dimensions[0] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(0) + 0.5);
   dimensions[1] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(1) + 0.5);
   dimensions[2] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(2) + 0.5);
   dimensions[3] = (tDim > 0) ? tDim : geometry.CountTimeSteps();
   dimensions[4] = 0;
 
   unsigned int dimension = 2;
   if (dimensions[2] > 1)
     dimension = 3;
   if (dimensions[3] > 1)
     dimension = 4;
 
   Initialize(type, dimension, dimensions, channels);
   if (geometry.CountTimeSteps() > 1)
   {
     TimeGeometry::Pointer cloned = geometry.Clone();
     SetTimeGeometry(cloned.GetPointer());
 
     // make sure the image geometry flag is properly set for all time steps
     for (TimeStepType step = 0; step < cloned->CountTimeSteps(); ++step)
     {
       if (!cloned->GetGeometryCloneForTimeStep(step)->GetImageGeometry())
       {
         MITK_WARN("Image.3DnT.Initialize") << " Attempt to initialize an image with a non-image geometry. "
                                               "Re-interpretting the initialization geometry for timestep "
                                            << step << " as image geometry, the original geometry remains unchanged.";
         cloned->GetGeometryForTimeStep(step)->ImageGeometryOn();
       }
     }
   }
   else
   {
     // make sure the image geometry coming from outside has proper value of the image geometry flag
     BaseGeometry::Pointer cloned = geometry.GetGeometryCloneForTimeStep(0)->Clone();
     if (!cloned->GetImageGeometry())
     {
       MITK_WARN("Image.Initialize") << " Attempt to initialize an image with a non-image geometry. Re-interpretting "
                                        "the initialization geometry as image geometry, the original geometry remains "
                                        "unchanged.";
       cloned->ImageGeometryOn();
     }
 
     Superclass::SetGeometry(cloned);
   }
-  /* //Old //TODO_GOETZ Really necessary?
-    mitk::BoundingBox::BoundsArrayType bounds = geometry.GetBoundingBoxInWorld()->GetBounds();
-    if( (bounds[0] != 0.0) || (bounds[2] != 0.0) || (bounds[4] != 0.0) )
-    {
-      SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0);
-
-      mitk::Point3D origin; origin.Fill(0.0);
-      slicedGeometry->IndexToWorld(origin, origin);
-
-      bounds[1]-=bounds[0]; bounds[3]-=bounds[2]; bounds[5]-=bounds[4];
-      bounds[0] = 0.0;      bounds[2] = 0.0;      bounds[4] = 0.0;
-      this->m_ImageDescriptor->Initialize( this->m_Dimensions, this->m_Dimension );
-      slicedGeometry->SetBounds(bounds);
-      slicedGeometry->GetIndexToWorldTransform()->SetOffset(origin.GetVnlVector().data_block());
-
-      ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
-      timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]);
-      SetTimeGeometry(timeGeometry);
-    }*/
-}
-
-void mitk::Image::Initialize(const mitk::PixelType &,
-                             int,
-                             const mitk::PlaneGeometry &,
-                             bool,
-                             unsigned int,
-                             int)
-{
-  mitkThrow() << "Use this method without the flipped parameter (direction is specified by the handedness of the PlaneGeometry instead).";
 }
 
 void mitk::Image::Initialize(const mitk::PixelType &type,
                              int sDim,
                              const mitk::PlaneGeometry &geometry2d,
                              unsigned int channels,
                              int tDim)
 {
   SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New();
   slicedGeometry->InitializeEvenlySpaced(geometry2d.Clone(), sDim);
   Initialize(type, *slicedGeometry, channels, tDim);
 }
 
 void mitk::Image::Initialize(const mitk::Image *image)
 {
   Initialize(image->GetPixelType(), *image->GetTimeGeometry());
 }
 
 void mitk::Image::Initialize(vtkImageData *vtkimagedata, int channels, int tDim, int sDim, int pDim)
 {
   if (vtkimagedata == nullptr)
     return;
 
   m_Dimension = vtkimagedata->GetDataDimension();
   unsigned int i, *tmpDimensions = new unsigned int[m_Dimension > 4 ? m_Dimension : 4];
   for (i = 0; i < m_Dimension; ++i)
     tmpDimensions[i] = vtkimagedata->GetDimensions()[i];
   if (m_Dimension < 4)
   {
     unsigned int *p;
     for (i = 0, p = tmpDimensions + m_Dimension; i < 4 - m_Dimension; ++i, ++p)
       *p = 1;
   }
 
   if (pDim >= 0)
   {
     tmpDimensions[1] = pDim;
     if (m_Dimension < 2)
       m_Dimension = 2;
   }
   if (sDim >= 0)
   {
     tmpDimensions[2] = sDim;
     if (m_Dimension < 3)
       m_Dimension = 3;
   }
   if (tDim >= 0)
   {
     tmpDimensions[3] = tDim;
     if (m_Dimension < 4)
       m_Dimension = 4;
   }
 
   mitk::PixelType pixelType(MakePixelType(vtkimagedata));
   Initialize(pixelType, m_Dimension, tmpDimensions, channels);
 
   const double *spacinglist = vtkimagedata->GetSpacing();
   Vector3D spacing;
   FillVector3D(spacing, spacinglist[0], 1.0, 1.0);
   if (m_Dimension >= 2)
     spacing[1] = spacinglist[1];
   if (m_Dimension >= 3)
     spacing[2] = spacinglist[2];
 
   // access origin of vtkImage
   Point3D origin;
   double vtkorigin[3];
   vtkimagedata->GetOrigin(vtkorigin);
   FillVector3D(origin, vtkorigin[0], 0.0, 0.0);
   if (m_Dimension >= 2)
     origin[1] = vtkorigin[1];
   if (m_Dimension >= 3)
     origin[2] = vtkorigin[2];
 
   SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(0);
 
   // re-initialize PlaneGeometry with origin and direction
   auto *planeGeometry = static_cast<PlaneGeometry *>(slicedGeometry->GetPlaneGeometry(0));
   planeGeometry->SetOrigin(origin);
 
   // re-initialize SlicedGeometry3D
   slicedGeometry->SetOrigin(origin);
   slicedGeometry->SetSpacing(spacing);
 
   ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
   timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]);
   SetTimeGeometry(timeGeometry);
 
   delete[] tmpDimensions;
 }
 
 bool mitk::Image::IsValidSlice(int s, int t, int n) const
 {
   if (m_Initialized)
     return ((s >= 0) && (s < (int)m_Dimensions[2]) && (t >= 0) && (t < (int)m_Dimensions[3]) && (n >= 0) &&
             (n < (int)GetNumberOfChannels()));
   else
     return false;
 }
 
 bool mitk::Image::IsValidVolume(int t, int n) const
 {
   if (m_Initialized)
     return IsValidSlice(0, t, n);
   else
     return false;
 }
 
 bool mitk::Image::IsValidChannel(int n) const
 {
   if (m_Initialized)
     return IsValidSlice(0, 0, n);
   else
     return false;
 }
 
 void mitk::Image::ComputeOffsetTable()
 {
   if (m_OffsetTable != nullptr)
     delete[] m_OffsetTable;
 
   m_OffsetTable = new size_t[m_Dimension > 4 ? m_Dimension + 1 : 4 + 1];
 
   unsigned int i;
   size_t num = 1;
   m_OffsetTable[0] = 1;
   for (i = 0; i < m_Dimension; ++i)
   {
     num *= m_Dimensions[i];
     m_OffsetTable[i + 1] = num;
   }
   for (; i < 4; ++i)
     m_OffsetTable[i + 1] = num;
 }
 
 bool mitk::Image::IsValidTimeStep(int t) const
 {
   return ((m_Dimension >= 4 && t <= (int)m_Dimensions[3] && t > 0) || (t == 0));
 }
 
 void mitk::Image::Expand(unsigned int timeSteps)
 {
   if (timeSteps < 1)
     itkExceptionMacro(<< "Invalid timestep in Image!");
   Superclass::Expand(timeSteps);
 }
 
 int mitk::Image::GetSliceIndex(int s, int t, int n) const
 {
   if (IsValidSlice(s, t, n) == false)
     return false;
   return ((size_t)s) + ((size_t)t) * m_Dimensions[2] + ((size_t)n) * m_Dimensions[3] * m_Dimensions[2]; //??
 }
 
 int mitk::Image::GetVolumeIndex(int t, int n) const
 {
   if (IsValidVolume(t, n) == false)
     return false;
   return ((size_t)t) + ((size_t)n) * m_Dimensions[3]; //??
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::AllocateSliceData(
   int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return AllocateSliceData_unlocked(s, t, n, data, importMemoryManagement);
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::AllocateSliceData_unlocked(
   int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   int pos;
   pos = GetSliceIndex(s, t, n);
 
   const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
 
   // is slice available as part of a volume that is available?
   ImageDataItemPointer sl, ch, vol;
   vol = m_Volumes[GetVolumeIndex(t, n)];
   if (vol.GetPointer() != nullptr)
   {
     sl = new ImageDataItem(*vol,
                            m_ImageDescriptor,
                            t,
                            2,
                            data,
                            importMemoryManagement == ManageMemory,
                            ((size_t)s) * m_OffsetTable[2] * (ptypeSize));
     sl->SetComplete(true);
     return m_Slices[pos] = sl;
   }
 
   // is slice available as part of a channel that is available?
   ch = m_Channels[n];
   if (ch.GetPointer() != nullptr)
   {
     sl = new ImageDataItem(*ch,
                            m_ImageDescriptor,
                            t,
                            2,
                            data,
                            importMemoryManagement == ManageMemory,
                            (((size_t)s) * m_OffsetTable[2] + ((size_t)t) * m_OffsetTable[3]) * (ptypeSize));
     sl->SetComplete(true);
     return m_Slices[pos] = sl;
   }
 
   // allocate new volume (instead of a single slice to keep data together!)
   m_Volumes[GetVolumeIndex(t, n)] = vol = AllocateVolumeData_unlocked(t, n, nullptr, importMemoryManagement);
   sl = new ImageDataItem(*vol,
                          m_ImageDescriptor,
                          t,
                          2,
                          data,
                          importMemoryManagement == ManageMemory,
                          ((size_t)s) * m_OffsetTable[2] * (ptypeSize));
   sl->SetComplete(true);
   return m_Slices[pos] = sl;
 
   ////ALTERNATIVE:
   //// allocate new slice
   // sl=new ImageDataItem(*m_PixelType, 2, m_Dimensions);
   // m_Slices[pos]=sl;
   // return vol;
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::AllocateVolumeData(
   int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return AllocateVolumeData_unlocked(t, n, data, importMemoryManagement);
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::AllocateVolumeData_unlocked(
   int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   int pos;
   pos = GetVolumeIndex(t, n);
 
   const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
 
   // is volume available as part of a channel that is available?
   ImageDataItemPointer ch, vol;
   ch = m_Channels[n];
   if (ch.GetPointer() != nullptr)
   {
     vol = new ImageDataItem(*ch,
                             m_ImageDescriptor,
                             t,
                             3,
                             data,
                             importMemoryManagement == ManageMemory,
                             (((size_t)t) * m_OffsetTable[3]) * (ptypeSize));
     return m_Volumes[pos] = vol;
   }
 
   mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(n);
 
   // allocate new volume
   if (importMemoryManagement == CopyMemory)
   {
     vol = new ImageDataItem(chPixelType, t, 3, m_Dimensions, nullptr, true);
     if (data != nullptr)
       std::memcpy(vol->GetData(), data, m_OffsetTable[3] * (ptypeSize));
   }
   else
   {
     vol = new ImageDataItem(chPixelType, t, 3, m_Dimensions, data, importMemoryManagement == ManageMemory);
   }
   m_Volumes[pos] = vol;
   return vol;
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::AllocateChannelData(
   int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   MutexHolder lock(m_ImageDataArraysLock);
   return AllocateChannelData_unlocked(n, data, importMemoryManagement);
 }
 
 mitk::Image::ImageDataItemPointer mitk::Image::AllocateChannelData_unlocked(
   int n, void *data, ImportMemoryManagementType importMemoryManagement) const
 {
   ImageDataItemPointer ch;
   // allocate new channel
   if (importMemoryManagement == CopyMemory)
   {
     const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
 
     ch = new ImageDataItem(this->m_ImageDescriptor, -1, nullptr, true);
     if (data != nullptr)
       std::memcpy(ch->GetData(), data, m_OffsetTable[4] * (ptypeSize));
   }
   else
   {
     ch = new ImageDataItem(this->m_ImageDescriptor, -1, data, importMemoryManagement == ManageMemory);
   }
   m_Channels[n] = ch;
   return ch;
 }
 
 unsigned int *mitk::Image::GetDimensions() const
 {
   return m_Dimensions;
 }
 
 void mitk::Image::Clear()
 {
   Superclass::Clear();
   delete[] m_Dimensions;
   m_Dimensions = nullptr;
 }
 
 void mitk::Image::SetGeometry(BaseGeometry *aGeometry3D)
 {
   // Please be aware of the 0.5 offset/pixel-center issue! See Geometry documentation for further information
 
   if (aGeometry3D->GetImageGeometry() == false)
   {
     MITK_INFO << "WARNING: Applied a non-image geometry onto an image. Please be SURE that this geometry is "
                  "pixel-center-based! If it is not, you need to call "
                  "Geometry3D->ChangeImageGeometryConsideringOriginOffset(true) before calling image->setGeometry(..)\n";
   }
   Superclass::SetGeometry(aGeometry3D);
   for (TimeStepType step = 0; step < GetTimeGeometry()->CountTimeSteps(); ++step)
     GetTimeGeometry()->GetGeometryForTimeStep(step)->ImageGeometryOn();
 }
 
 void mitk::Image::PrintSelf(std::ostream &os, itk::Indent indent) const
 {
   if (m_Initialized)
   {
     unsigned char i;
     os << indent << " Dimension: " << m_Dimension << std::endl;
     os << indent << " Dimensions: ";
     for (i = 0; i < m_Dimension; ++i)
       os << GetDimension(i) << " ";
     os << std::endl;
 
     for (unsigned int ch = 0; ch < this->m_ImageDescriptor->GetNumberOfChannels(); ch++)
     {
       mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(ch);
 
       os << indent << " Channel: " << this->m_ImageDescriptor->GetChannelName(ch) << std::endl;
       os << indent << " PixelType: " << chPixelType.GetPixelTypeAsString() << std::endl;
       os << indent << " BytesPerElement: " << chPixelType.GetSize() << std::endl;
       os << indent << " ComponentType: " << chPixelType.GetComponentTypeAsString() << std::endl;
       os << indent << " NumberOfComponents: " << chPixelType.GetNumberOfComponents() << std::endl;
       os << indent << " BitsPerComponent: " << chPixelType.GetBitsPerComponent() << std::endl;
     }
   }
   else
   {
     os << indent << " Image not initialized: m_Initialized: false" << std::endl;
   }
 
   Superclass::PrintSelf(os, indent);
 }
 
 bool mitk::Image::IsRotated() const
 {
   const mitk::BaseGeometry *geo = this->GetGeometry();
   bool ret = false;
 
   if (geo)
   {
     const vnl_matrix_fixed<ScalarType, 3, 3> &mx = geo->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
     mitk::ScalarType ref = 0;
     for (short k = 0; k < 3; ++k)
       ref += mx[k][k];
     ref /= 1000; // Arbitrary value; if a non-diagonal (nd) element is bigger then this, matrix is considered nd.
 
     for (short i = 0; i < 3; ++i)
     {
       for (short j = 0; j < 3; ++j)
       {
         if (i != j)
         {
           if (std::abs(mx[i][j]) > ref) // matrix is nd
             ret = true;
         }
       }
     }
   }
   return ret;
 }
 
-mitk::ScalarType mitk::Image::GetScalarValueMin(int t) const
-{
-  return m_ImageStatistics->GetScalarValueMin(t);
-}
-
-//## \brief Get the maximum for scalar images
-mitk::ScalarType mitk::Image::GetScalarValueMax(int t) const
-{
-  return m_ImageStatistics->GetScalarValueMax(t);
-}
-
-//## \brief Get the second smallest value for scalar images
-mitk::ScalarType mitk::Image::GetScalarValue2ndMin(int t) const
-{
-  return m_ImageStatistics->GetScalarValue2ndMin(t);
-}
-
-mitk::ScalarType mitk::Image::GetScalarValueMinNoRecompute(unsigned int t) const
-{
-  return m_ImageStatistics->GetScalarValueMinNoRecompute(t);
-}
-
-mitk::ScalarType mitk::Image::GetScalarValue2ndMinNoRecompute(unsigned int t) const
-{
-  return m_ImageStatistics->GetScalarValue2ndMinNoRecompute(t);
-}
-
-mitk::ScalarType mitk::Image::GetScalarValue2ndMax(int t) const
-{
-  return m_ImageStatistics->GetScalarValue2ndMax(t);
-}
-
-mitk::ScalarType mitk::Image::GetScalarValueMaxNoRecompute(unsigned int t) const
-{
-  return m_ImageStatistics->GetScalarValueMaxNoRecompute(t);
-}
-
-mitk::ScalarType mitk::Image::GetScalarValue2ndMaxNoRecompute(unsigned int t) const
-{
-  return m_ImageStatistics->GetScalarValue2ndMaxNoRecompute(t);
-}
-
-mitk::ScalarType mitk::Image::GetCountOfMinValuedVoxels(int t) const
-{
-  return m_ImageStatistics->GetCountOfMinValuedVoxels(t);
-}
-
-mitk::ScalarType mitk::Image::GetCountOfMaxValuedVoxels(int t) const
-{
-  return m_ImageStatistics->GetCountOfMaxValuedVoxels(t);
-}
-
-unsigned int mitk::Image::GetCountOfMaxValuedVoxelsNoRecompute(unsigned int t) const
-{
-  return m_ImageStatistics->GetCountOfMaxValuedVoxelsNoRecompute(t);
-}
-
-unsigned int mitk::Image::GetCountOfMinValuedVoxelsNoRecompute(unsigned int t) const
-{
-  return m_ImageStatistics->GetCountOfMinValuedVoxelsNoRecompute(t);
-}
-
-bool mitk::Equal(const mitk::Image *leftHandSide, const mitk::Image *rightHandSide, ScalarType eps, bool verbose)
-{
-  if ((leftHandSide == nullptr) || (rightHandSide == nullptr))
-  {
-    MITK_ERROR << "mitk::Equal(const mitk::Image* leftHandSide, const mitk::Image* rightHandSide, ScalarType eps, bool "
-                  "verbose) does not work with nullptr pointer input.";
-    return false;
-  }
-  return mitk::Equal(*leftHandSide, *rightHandSide, eps, verbose);
-}
 
 bool mitk::Equal(const mitk::Image &leftHandSide, const mitk::Image &rightHandSide, ScalarType eps, bool verbose)
 {
   bool returnValue = true;
 
   // Dimensionality
   if (rightHandSide.GetDimension() != leftHandSide.GetDimension())
   {
     if (verbose)
     {
       MITK_INFO << "[( Image )] Dimensionality differs.";
       MITK_INFO << "leftHandSide is " << leftHandSide.GetDimension() << "rightHandSide is "
                 << rightHandSide.GetDimension();
     }
     returnValue = false;
   }
 
   // Pair-wise dimension (size) comparison
   unsigned int minDimensionality = std::min(rightHandSide.GetDimension(), leftHandSide.GetDimension());
   for (unsigned int i = 0; i < minDimensionality; ++i)
   {
     if (rightHandSide.GetDimension(i) != leftHandSide.GetDimension(i))
     {
       returnValue = false;
       if (verbose)
       {
         MITK_INFO << "[( Image )] dimension differs.";
         MITK_INFO << "leftHandSide->GetDimension(" << i << ") is " << leftHandSide.GetDimension(i)
                   << "rightHandSide->GetDimension(" << i << ") is " << rightHandSide.GetDimension(i);
       }
     }
   }
 
   // Pixeltype
   mitk::PixelType pixelTypeRightHandSide = rightHandSide.GetPixelType();
   mitk::PixelType pixelTypeLeftHandSide = leftHandSide.GetPixelType();
   if (!(pixelTypeRightHandSide == pixelTypeLeftHandSide))
   {
     if (verbose)
     {
       MITK_INFO << "[( Image )] PixelType differs.";
       MITK_INFO << "leftHandSide is " << pixelTypeLeftHandSide.GetTypeAsString() << "rightHandSide is "
                 << pixelTypeRightHandSide.GetTypeAsString();
     }
     returnValue = false;
   }
 
   // Geometries
   if (!mitk::Equal(*leftHandSide.GetGeometry(), *rightHandSide.GetGeometry(), eps, verbose))
   {
     if (verbose)
     {
       MITK_INFO << "[( Image )] Geometries differ.";
     }
     returnValue = false;
   }
 
   // Pixel values - default mode [ 0 threshold in difference ]
   // compare only if all previous checks were successfull, otherwise the ITK filter will throw an exception
   if (returnValue)
   {
     mitk::CompareImageDataFilter::Pointer compareFilter = mitk::CompareImageDataFilter::New();
 
     compareFilter->SetInput(0, &rightHandSide);
     compareFilter->SetInput(1, &leftHandSide);
     compareFilter->SetTolerance(eps);
     compareFilter->Update();
 
     if ((!compareFilter->GetResult()))
     {
       returnValue = false;
       if (verbose)
       {
         MITK_INFO << "[(Image)] Pixel values differ: ";
         compareFilter->GetCompareResults().PrintSelf();
       }
     }
   }
 
   return returnValue;
 }
diff --git a/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp b/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
index 56069a2be9..beb6d792ce 100644
--- a/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
+++ b/Modules/Multilabel/mitkLabelSetImageVtkMapper2D.cpp
@@ -1,650 +1,649 @@
 /*============================================================================
 
 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 "mitkLabelSetImageVtkMapper2D.h"
 
 // MITK
 #include <mitkAbstractTransformGeometry.h>
 #include <mitkDataNode.h>
 #include <mitkImageSliceSelector.h>
 #include <mitkImageStatisticsHolder.h>
 #include <mitkLevelWindowProperty.h>
 #include <mitkLookupTableProperty.h>
 #include <mitkPixelType.h>
 #include <mitkPlaneClipping.h>
 #include <mitkPlaneGeometry.h>
 #include <mitkProperties.h>
 #include <mitkResliceMethodProperty.h>
-#include <mitkTimeSlicedGeometry.h>
 #include <mitkTransferFunctionProperty.h>
 #include <mitkVtkResliceInterpolationProperty.h>
 
 // MITK Rendering
 #include "vtkMitkLevelWindowFilter.h"
 #include "vtkMitkThickSlicesFilter.h"
 #include "vtkNeverTranslucentTexture.h"
 
 // VTK
 #include <vtkCamera.h>
 #include <vtkCellArray.h>
 #include <vtkImageData.h>
 #include <vtkImageReslice.h>
 #include <vtkLookupTable.h>
 #include <vtkMatrix4x4.h>
 #include <vtkPlaneSource.h>
 #include <vtkPoints.h>
 #include <vtkPolyData.h>
 #include <vtkPolyDataMapper.h>
 #include <vtkProperty.h>
 #include <vtkTransform.h>
 //#include <vtkOpenGLTexture.h>
 
 // ITK
 #include <itkRGBAPixel.h>
 #include <mitkRenderingModeProperty.h>
 
 mitk::LabelSetImageVtkMapper2D::LabelSetImageVtkMapper2D()
 {
 }
 
 mitk::LabelSetImageVtkMapper2D::~LabelSetImageVtkMapper2D()
 {
 }
 
 vtkProp *mitk::LabelSetImageVtkMapper2D::GetVtkProp(mitk::BaseRenderer *renderer)
 {
   // return the actor corresponding to the renderer
   return m_LSH.GetLocalStorage(renderer)->m_Actors;
 }
 
 mitk::LabelSetImageVtkMapper2D::LocalStorage *mitk::LabelSetImageVtkMapper2D::GetLocalStorage(
   mitk::BaseRenderer *renderer)
 {
   return m_LSH.GetLocalStorage(renderer);
 }
 
 void mitk::LabelSetImageVtkMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   mitk::DataNode *node = this->GetDataNode();
   auto *image = dynamic_cast<mitk::LabelSetImage *>(node->GetData());
   assert(image && image->IsInitialized());
 
   // check if there is a valid worldGeometry
   const PlaneGeometry *worldGeometry = renderer->GetCurrentWorldPlaneGeometry();
   if ((worldGeometry == nullptr) || (!worldGeometry->IsValid()) || (!worldGeometry->HasReferenceGeometry()))
     return;
 
   image->Update();
 
   int numberOfLayers = image->GetNumberOfLayers();
   int activeLayer = image->GetActiveLayer();
 
   float opacity = 1.0f;
   node->GetOpacity(opacity, renderer, "opacity");
 
   if (numberOfLayers != localStorage->m_NumberOfLayers)
   {
     localStorage->m_NumberOfLayers = numberOfLayers;
     localStorage->m_ReslicedImageVector.clear();
     localStorage->m_ReslicerVector.clear();
     localStorage->m_LayerTextureVector.clear();
     localStorage->m_LevelWindowFilterVector.clear();
     localStorage->m_LayerMapperVector.clear();
     localStorage->m_LayerActorVector.clear();
 
     localStorage->m_Actors = vtkSmartPointer<vtkPropAssembly>::New();
 
     for (int lidx = 0; lidx < numberOfLayers; ++lidx)
     {
       localStorage->m_ReslicedImageVector.push_back(vtkSmartPointer<vtkImageData>::New());
       localStorage->m_ReslicerVector.push_back(mitk::ExtractSliceFilter::New());
       localStorage->m_LayerTextureVector.push_back(vtkSmartPointer<vtkNeverTranslucentTexture>::New());
       localStorage->m_LevelWindowFilterVector.push_back(vtkSmartPointer<vtkMitkLevelWindowFilter>::New());
       localStorage->m_LayerMapperVector.push_back(vtkSmartPointer<vtkPolyDataMapper>::New());
       localStorage->m_LayerActorVector.push_back(vtkSmartPointer<vtkActor>::New());
 
       // do not repeat the texture (the image)
       localStorage->m_LayerTextureVector[lidx]->RepeatOff();
 
       // set corresponding mappers for the actors
       localStorage->m_LayerActorVector[lidx]->SetMapper(localStorage->m_LayerMapperVector[lidx]);
 
       localStorage->m_Actors->AddPart(localStorage->m_LayerActorVector[lidx]);
     }
 
     localStorage->m_Actors->AddPart(localStorage->m_OutlineShadowActor);
     localStorage->m_Actors->AddPart(localStorage->m_OutlineActor);
   }
 
   // early out if there is no intersection of the current rendering geometry
   // and the geometry of the image that is to be rendered.
   if (!RenderingGeometryIntersectsImage(worldGeometry, image->GetSlicedGeometry()))
   {
     // set image to nullptr, to clear the texture in 3D, because
     // the latest image is used there if the plane is out of the geometry
     // see bug-13275
     for (int lidx = 0; lidx < numberOfLayers; ++lidx)
     {
       localStorage->m_ReslicedImageVector[lidx] = nullptr;
       localStorage->m_LayerMapperVector[lidx]->SetInputData(localStorage->m_EmptyPolyData);
       localStorage->m_OutlineActor->SetVisibility(false);
       localStorage->m_OutlineShadowActor->SetVisibility(false);
     }
     return;
   }
 
   for (int lidx = 0; lidx < numberOfLayers; ++lidx)
   {
     mitk::Image *layerImage = nullptr;
 
     // set main input for ExtractSliceFilter
     if (lidx == activeLayer)
       layerImage = image;
     else
       layerImage = image->GetLayerImage(lidx);
 
     localStorage->m_ReslicerVector[lidx]->SetInput(layerImage);
     localStorage->m_ReslicerVector[lidx]->SetWorldGeometry(worldGeometry);
     localStorage->m_ReslicerVector[lidx]->SetTimeStep(this->GetTimestep());
 
     // set the transformation of the image to adapt reslice axis
     localStorage->m_ReslicerVector[lidx]->SetResliceTransformByGeometry(
       layerImage->GetTimeGeometry()->GetGeometryForTimeStep(this->GetTimestep()));
 
     // is the geometry of the slice based on the image image or the worldgeometry?
     bool inPlaneResampleExtentByGeometry = false;
     node->GetBoolProperty("in plane resample extent by geometry", inPlaneResampleExtentByGeometry, renderer);
     localStorage->m_ReslicerVector[lidx]->SetInPlaneResampleExtentByGeometry(inPlaneResampleExtentByGeometry);
     localStorage->m_ReslicerVector[lidx]->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST);
     localStorage->m_ReslicerVector[lidx]->SetVtkOutputRequest(true);
 
     // this is needed when thick mode was enabled before. These variables have to be reset to default values
     localStorage->m_ReslicerVector[lidx]->SetOutputDimensionality(2);
     localStorage->m_ReslicerVector[lidx]->SetOutputSpacingZDirection(1.0);
     localStorage->m_ReslicerVector[lidx]->SetOutputExtentZDirection(0, 0);
 
     // Bounds information for reslicing (only required if reference geometry is present)
     // this used for generating a vtkPLaneSource with the right size
     double sliceBounds[6];
     sliceBounds[0] = 0.0;
     sliceBounds[1] = 0.0;
     sliceBounds[2] = 0.0;
     sliceBounds[3] = 0.0;
     sliceBounds[4] = 0.0;
     sliceBounds[5] = 0.0;
 
     localStorage->m_ReslicerVector[lidx]->GetClippedPlaneBounds(sliceBounds);
 
     // setup the textured plane
     this->GeneratePlane(renderer, sliceBounds);
 
     // get the spacing of the slice
     localStorage->m_mmPerPixel = localStorage->m_ReslicerVector[lidx]->GetOutputSpacing();
     localStorage->m_ReslicerVector[lidx]->Modified();
     // start the pipeline with updating the largest possible, needed if the geometry of the image has changed
     localStorage->m_ReslicerVector[lidx]->UpdateLargestPossibleRegion();
     localStorage->m_ReslicedImageVector[lidx] = localStorage->m_ReslicerVector[lidx]->GetVtkOutput();
 
     const auto *planeGeometry = dynamic_cast<const PlaneGeometry *>(worldGeometry);
 
     double textureClippingBounds[6];
     for (auto &textureClippingBound : textureClippingBounds)
     {
       textureClippingBound = 0.0;
     }
 
     // Calculate the actual bounds of the transformed plane clipped by the
     // dataset bounding box; this is required for drawing the texture at the
     // correct position during 3D mapping.
     mitk::PlaneClipping::CalculateClippedPlaneBounds(layerImage->GetGeometry(), planeGeometry, textureClippingBounds);
 
     textureClippingBounds[0] = static_cast<int>(textureClippingBounds[0] / localStorage->m_mmPerPixel[0] + 0.5);
     textureClippingBounds[1] = static_cast<int>(textureClippingBounds[1] / localStorage->m_mmPerPixel[0] + 0.5);
     textureClippingBounds[2] = static_cast<int>(textureClippingBounds[2] / localStorage->m_mmPerPixel[1] + 0.5);
     textureClippingBounds[3] = static_cast<int>(textureClippingBounds[3] / localStorage->m_mmPerPixel[1] + 0.5);
 
     // clipping bounds for cutting the imageLayer
     localStorage->m_LevelWindowFilterVector[lidx]->SetClippingBounds(textureClippingBounds);
 
     localStorage->m_LevelWindowFilterVector[lidx]->SetLookupTable(
       image->GetLabelSet(lidx)->GetLookupTable()->GetVtkLookupTable());
 
     // do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter)
     localStorage->m_LayerTextureVector[lidx]->SetColorModeToDirectScalars();
 
     // connect the imageLayer with the levelwindow filter
     localStorage->m_LevelWindowFilterVector[lidx]->SetInputData(localStorage->m_ReslicedImageVector[lidx]);
     // connect the texture with the output of the levelwindow filter
 
     // check for texture interpolation property
     bool textureInterpolation = false;
     node->GetBoolProperty("texture interpolation", textureInterpolation, renderer);
 
     // set the interpolation modus according to the property
     localStorage->m_LayerTextureVector[lidx]->SetInterpolate(textureInterpolation);
 
     localStorage->m_LayerTextureVector[lidx]->SetInputConnection(
       localStorage->m_LevelWindowFilterVector[lidx]->GetOutputPort());
 
     this->TransformActor(renderer);
 
     // set the plane as input for the mapper
     localStorage->m_LayerMapperVector[lidx]->SetInputConnection(localStorage->m_Plane->GetOutputPort());
 
     // set the texture for the actor
     localStorage->m_LayerActorVector[lidx]->SetTexture(localStorage->m_LayerTextureVector[lidx]);
     localStorage->m_LayerActorVector[lidx]->GetProperty()->SetOpacity(opacity);
   }
 
   mitk::Label* activeLabel = image->GetActiveLabel(activeLayer);
   if (nullptr != activeLabel)
   {
     bool contourActive = false;
     node->GetBoolProperty("labelset.contour.active", contourActive, renderer);
     if (contourActive && activeLabel->GetVisible()) //contour rendering
     {
       //generate contours/outlines
       localStorage->m_OutlinePolyData =
         this->CreateOutlinePolyData(renderer, localStorage->m_ReslicedImageVector[activeLayer], activeLabel->GetValue());
       localStorage->m_OutlineActor->SetVisibility(true);
       localStorage->m_OutlineShadowActor->SetVisibility(true);
       const mitk::Color& color = activeLabel->GetColor();
       localStorage->m_OutlineActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue());
       localStorage->m_OutlineShadowActor->GetProperty()->SetColor(0, 0, 0);
 
       float contourWidth(2.0);
       node->GetFloatProperty("labelset.contour.width", contourWidth, renderer);
       localStorage->m_OutlineActor->GetProperty()->SetLineWidth(contourWidth);
       localStorage->m_OutlineShadowActor->GetProperty()->SetLineWidth(contourWidth * 1.5);
 
       localStorage->m_OutlineActor->GetProperty()->SetOpacity(opacity);
       localStorage->m_OutlineShadowActor->GetProperty()->SetOpacity(opacity);
 
       localStorage->m_OutlineMapper->SetInputData(localStorage->m_OutlinePolyData);
       return;
     }
   }
   localStorage->m_OutlineActor->SetVisibility(false);
   localStorage->m_OutlineShadowActor->SetVisibility(false);
 }
 
 bool mitk::LabelSetImageVtkMapper2D::RenderingGeometryIntersectsImage(const PlaneGeometry *renderingGeometry,
                                                                       SlicedGeometry3D *imageGeometry)
 {
   // if either one of the two geometries is nullptr we return true
   // for safety reasons
   if (renderingGeometry == nullptr || imageGeometry == nullptr)
     return true;
 
   // get the distance for the first cornerpoint
   ScalarType initialDistance = renderingGeometry->SignedDistance(imageGeometry->GetCornerPoint(0));
   for (int i = 1; i < 8; i++)
   {
     mitk::Point3D cornerPoint = imageGeometry->GetCornerPoint(i);
 
     // get the distance to the other cornerpoints
     ScalarType distance = renderingGeometry->SignedDistance(cornerPoint);
 
     // if it has not the same signing as the distance of the first point
     if (initialDistance * distance < 0)
     {
       // we have an intersection and return true
       return true;
     }
   }
 
   // all distances have the same sign, no intersection and we return false
   return false;
 }
 
 vtkSmartPointer<vtkPolyData> mitk::LabelSetImageVtkMapper2D::CreateOutlinePolyData(mitk::BaseRenderer *renderer,
                                                                                    vtkImageData *image,
                                                                                    int pixelValue)
 {
   LocalStorage *localStorage = this->GetLocalStorage(renderer);
 
   // get the min and max index values of each direction
   int *extent = image->GetExtent();
   int xMin = extent[0];
   int xMax = extent[1];
   int yMin = extent[2];
   int yMax = extent[3];
 
   int *dims = image->GetDimensions(); // dimensions of the image
   int line = dims[0];                 // how many pixels per line?
   int x = xMin;                       // pixel index x
   int y = yMin;                       // pixel index y
 
   // get the depth for each contour
   float depth = this->CalculateLayerDepth(renderer);
 
   vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();      // the points to draw
   vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); // the lines to connect the points
 
   // We take the pointer to the first pixel of the image
   auto *currentPixel = static_cast<mitk::Label::PixelType *>(image->GetScalarPointer());
 
   while (y <= yMax)
   {
     // if the current pixel value is set to something
     if ((currentPixel) && (*currentPixel == pixelValue))
     {
       // check in which direction a line is necessary
       // a line is added if the neighbor of the current pixel has the value 0
       // and if the pixel is located at the edge of the image
 
       // if   vvvvv  not the first line vvvvv
       if (y > yMin && *(currentPixel - line) != pixelValue)
       { // x direction - bottom edge of the pixel
         // add the 2 points
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 =
           points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         // add the line between both points
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  not the last line vvvvv
       if (y < yMax && *(currentPixel + line) != pixelValue)
       { // x direction - top edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 = points->InsertNextPoint(
           (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  not the first pixel vvvvv
       if ((x > xMin || y > yMin) && *(currentPixel - 1) != pixelValue)
       { // y direction - left edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  not the last pixel vvvvv
       if ((y < yMax || (x < xMax)) && *(currentPixel + 1) != pixelValue)
       { // y direction - right edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 = points->InsertNextPoint(
           (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       /*  now consider pixels at the edge of the image  */
 
       // if   vvvvv  left edge of image vvvvv
       if (x == xMin)
       { // draw left edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  right edge of image vvvvv
       if (x == xMax)
       { // draw right edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 = points->InsertNextPoint(
           (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  bottom edge of image vvvvv
       if (y == yMin)
       { // draw bottom edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 =
           points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
 
       // if   vvvvv  top edge of image vvvvv
       if (y == yMax)
       { // draw top edge of the pixel
         vtkIdType p1 =
           points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         vtkIdType p2 = points->InsertNextPoint(
           (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
         lines->InsertNextCell(2);
         lines->InsertCellPoint(p1);
         lines->InsertCellPoint(p2);
       }
     } // end if currentpixel is set
 
     x++;
 
     if (x > xMax)
     { // reached end of line
       x = xMin;
       y++;
     }
 
     // Increase the pointer-position to the next pixel.
     // This is safe, as the while-loop and the x-reset logic above makes
     // sure we do not exceed the bounds of the image
     currentPixel++;
   } // end of while
 
   // Create a polydata to store everything in
   vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
   // Add the points to the dataset
   polyData->SetPoints(points);
   // Add the lines to the dataset
   polyData->SetLines(lines);
   return polyData;
 }
 
 void mitk::LabelSetImageVtkMapper2D::ApplyColor(mitk::BaseRenderer *renderer, const mitk::Color &color)
 {
   LocalStorage *localStorage = this->GetLocalStorage(renderer);
   localStorage->m_OutlineActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue());
   localStorage->m_OutlineShadowActor->GetProperty()->SetColor(0, 0, 0);
 }
 
 void mitk::LabelSetImageVtkMapper2D::ApplyOpacity(mitk::BaseRenderer *renderer, int layer)
 {
   LocalStorage *localStorage = this->GetLocalStorage(renderer);
   float opacity = 1.0f;
   this->GetDataNode()->GetOpacity(opacity, renderer, "opacity");
   localStorage->m_LayerActorVector[layer]->GetProperty()->SetOpacity(opacity);
   localStorage->m_OutlineActor->GetProperty()->SetOpacity(opacity);
   localStorage->m_OutlineShadowActor->GetProperty()->SetOpacity(opacity);
 }
 
 void mitk::LabelSetImageVtkMapper2D::ApplyLookuptable(mitk::BaseRenderer *renderer, int layer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   auto *input = dynamic_cast<mitk::LabelSetImage *>(this->GetDataNode()->GetData());
   localStorage->m_LevelWindowFilterVector[layer]->SetLookupTable(
     input->GetLabelSet(layer)->GetLookupTable()->GetVtkLookupTable());
 }
 
 void mitk::LabelSetImageVtkMapper2D::Update(mitk::BaseRenderer *renderer)
 {
   bool visible = true;
   const DataNode *node = this->GetDataNode();
   node->GetVisibility(visible, renderer, "visible");
 
   if (!visible)
     return;
 
   auto *image = dynamic_cast<mitk::LabelSetImage *>(node->GetData());
 
   if (image == nullptr || image->IsInitialized() == false)
     return;
 
   // Calculate time step of the image data for the specified renderer (integer value)
   this->CalculateTimeStep(renderer);
 
   // Check if time step is valid
   const TimeGeometry *dataTimeGeometry = image->GetTimeGeometry();
   if ((dataTimeGeometry == nullptr) || (dataTimeGeometry->CountTimeSteps() == 0) ||
       (!dataTimeGeometry->IsValidTimeStep(this->GetTimestep())))
   {
     return;
   }
 
   image->UpdateOutputInformation();
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   // check if something important has changed and we need to re-render
 
   if ((localStorage->m_LastDataUpdateTime < image->GetMTime()) ||
       (localStorage->m_LastDataUpdateTime < image->GetPipelineMTime()) ||
       (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometryUpdateTime()) ||
       (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime()))
   {
     this->GenerateDataForRenderer(renderer);
     localStorage->m_LastDataUpdateTime.Modified();
   }
   else if ((localStorage->m_LastPropertyUpdateTime < node->GetPropertyList()->GetMTime()) ||
            (localStorage->m_LastPropertyUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ||
            (localStorage->m_LastPropertyUpdateTime < image->GetPropertyList()->GetMTime()))
   {
     this->GenerateDataForRenderer(renderer);
     localStorage->m_LastPropertyUpdateTime.Modified();
   }
 }
 
 // set the two points defining the textured plane according to the dimension and spacing
 void mitk::LabelSetImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer *renderer, double planeBounds[6])
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
 
   float depth = this->CalculateLayerDepth(renderer);
   // Set the origin to (xMin; yMin; depth) of the plane. This is necessary for obtaining the correct
   // plane size in crosshair rotation and swivel mode.
   localStorage->m_Plane->SetOrigin(planeBounds[0], planeBounds[2], depth);
   // These two points define the axes of the plane in combination with the origin.
   // Point 1 is the x-axis and point 2 the y-axis.
   // Each plane is transformed according to the view (axial, coronal and saggital) afterwards.
   localStorage->m_Plane->SetPoint1(planeBounds[1], planeBounds[2], depth); // P1: (xMax, yMin, depth)
   localStorage->m_Plane->SetPoint2(planeBounds[0], planeBounds[3], depth); // P2: (xMin, yMax, depth)
 }
 
 float mitk::LabelSetImageVtkMapper2D::CalculateLayerDepth(mitk::BaseRenderer *renderer)
 {
   // get the clipping range to check how deep into z direction we can render images
   double maxRange = renderer->GetVtkRenderer()->GetActiveCamera()->GetClippingRange()[1];
 
   // Due to a VTK bug, we cannot use the whole clipping range. /100 is empirically determined
   float depth = -maxRange * 0.01; // divide by 100
   int layer = 0;
   GetDataNode()->GetIntProperty("layer", layer, renderer);
   // add the layer property for each image to render images with a higher layer on top of the others
   depth += layer * 10; //*10: keep some room for each image (e.g. for ODFs in between)
   if (depth > 0.0f)
   {
     depth = 0.0f;
     MITK_WARN << "Layer value exceeds clipping range. Set to minimum instead.";
   }
   return depth;
 }
 
 void mitk::LabelSetImageVtkMapper2D::TransformActor(mitk::BaseRenderer *renderer)
 {
   LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
   // get the transformation matrix of the reslicer in order to render the slice as axial, coronal or saggital
   vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
   vtkSmartPointer<vtkMatrix4x4> matrix = localStorage->m_ReslicerVector[0]->GetResliceAxes(); // same for all layers
   trans->SetMatrix(matrix);
 
   for (int lidx = 0; lidx < localStorage->m_NumberOfLayers; ++lidx)
   {
     // transform the plane/contour (the actual actor) to the corresponding view (axial, coronal or saggital)
     localStorage->m_LayerActorVector[lidx]->SetUserTransform(trans);
     // transform the origin to center based coordinates, because MITK is center based.
     localStorage->m_LayerActorVector[lidx]->SetPosition(
       -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
   }
   // same for outline actor
   localStorage->m_OutlineActor->SetUserTransform(trans);
   localStorage->m_OutlineActor->SetPosition(
     -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
   // same for outline shadow actor
   localStorage->m_OutlineShadowActor->SetUserTransform(trans);
   localStorage->m_OutlineShadowActor->SetPosition(
     -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
 }
 
 void mitk::LabelSetImageVtkMapper2D::SetDefaultProperties(mitk::DataNode *node,
                                                           mitk::BaseRenderer *renderer,
                                                           bool overwrite)
 {
   // add/replace the following properties
   node->SetProperty("opacity", FloatProperty::New(1.0f), renderer);
   node->SetProperty("binary", BoolProperty::New(false), renderer);
 
   mitk::RenderingModeProperty::Pointer renderingModeProperty =
     mitk::RenderingModeProperty::New(RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR);
   node->SetProperty("Image Rendering.Mode", renderingModeProperty, renderer);
 
   mitk::LevelWindow levelwindow(32767.5, 65535);
   mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(levelwindow);
 
   levWinProp->SetLevelWindow(levelwindow);
   node->SetProperty("levelwindow", levWinProp, renderer);
 
   node->SetProperty("labelset.contour.active", BoolProperty::New(true), renderer);
   node->SetProperty("labelset.contour.width", FloatProperty::New(2.0), renderer);
 
   Superclass::SetDefaultProperties(node, renderer, overwrite);
 }
 
 mitk::LabelSetImageVtkMapper2D::LocalStorage::~LocalStorage()
 {
 }
 
 mitk::LabelSetImageVtkMapper2D::LocalStorage::LocalStorage()
 {
   // Do as much actions as possible in here to avoid double executions.
   m_Plane = vtkSmartPointer<vtkPlaneSource>::New();
   m_Actors = vtkSmartPointer<vtkPropAssembly>::New();
   m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();
   m_EmptyPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_OutlineActor = vtkSmartPointer<vtkActor>::New();
   m_OutlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
   m_OutlineShadowActor = vtkSmartPointer<vtkActor>::New();
 
   m_NumberOfLayers = 0;
   m_mmPerPixel = nullptr;
 
   m_OutlineActor->SetMapper(m_OutlineMapper);
   m_OutlineShadowActor->SetMapper(m_OutlineMapper);
 
   m_OutlineActor->SetVisibility(false);
   m_OutlineShadowActor->SetVisibility(false);
 }
diff --git a/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.cpp b/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.cpp
index 64df08bc8b..63c827db0c 100644
--- a/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.cpp
@@ -1,204 +1,205 @@
 /*============================================================================
 
 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.
 
 ============================================================================*/
 
 // MITK
 #include "mitkAutoMLSegmentationWithPreviewTool.h"
 #include "mitkImageAccessByItk.h"
 #include "mitkToolManager.h"
 #include <mitkITKImageImport.h>
 #include <mitkImageCast.h>
 #include <mitkLevelWindowProperty.h>
 #include <mitkLookupTableProperty.h>
 #include <mitkRenderingModeProperty.h>
 #include <mitkSliceNavigationController.h>
+#include <mitkImageStatisticsHolder.h>
 
 // ITK
 #include <itkBinaryThresholdImageFilter.h>
 #include <itkOrImageFilter.h>
 
 mitk::AutoMLSegmentationWithPreviewTool::AutoMLSegmentationWithPreviewTool() : AutoSegmentationWithPreviewTool(true)
 {
 }
 
 void mitk::AutoMLSegmentationWithPreviewTool::SetSelectedLabels(const SelectedLabelVectorType& regions)
 {
   if (m_SelectedLabels != regions)
   {
     m_SelectedLabels = regions;
     //Note: we do not call this->Modified() on puprose. Reason: changing the
     //selected regions should not force to run otsu filter in DoUpdatePreview due to changed MTime.
   }
 }
 
 const mitk::LabelSetImage* mitk::AutoMLSegmentationWithPreviewTool::GetMLPreview() const
 {
   if (m_MLPreviewNode.IsNotNull())
   {
     const auto mlPreviewImage = dynamic_cast<const LabelSetImage*>(this->m_MLPreviewNode->GetData());
     return mlPreviewImage;
   }
 
   return nullptr;
 }
 
 mitk::AutoMLSegmentationWithPreviewTool::SelectedLabelVectorType mitk::AutoMLSegmentationWithPreviewTool::GetSelectedLabels() const
 {
   return this->m_SelectedLabels;
 }
 
 void mitk::AutoMLSegmentationWithPreviewTool::Activated()
 {
   Superclass::Activated();
 
   m_SelectedLabels = {};
 
   m_MLPreviewNode = mitk::DataNode::New();
   m_MLPreviewNode->SetProperty("name", StringProperty::New(std::string(this->GetName()) + "ML preview"));
   m_MLPreviewNode->SetProperty("helper object", BoolProperty::New(true));
   m_MLPreviewNode->SetVisibility(true);
   m_MLPreviewNode->SetOpacity(1.0);
 
   this->GetToolManager()->GetDataStorage()->Add(m_MLPreviewNode);
 }
 
 void mitk::AutoMLSegmentationWithPreviewTool::Deactivated()
 {
   this->GetToolManager()->GetDataStorage()->Remove(m_MLPreviewNode);
   m_MLPreviewNode = nullptr;
 
   Superclass::Deactivated();
 }
 
 void mitk::AutoMLSegmentationWithPreviewTool::UpdateCleanUp()
 {
   if (m_MLPreviewNode.IsNotNull())
     m_MLPreviewNode->SetVisibility(m_SelectedLabels.empty());
 
   if (nullptr != this->GetPreviewSegmentationNode())
     this->GetPreviewSegmentationNode()->SetVisibility(!m_SelectedLabels.empty());
 
   if (m_SelectedLabels.empty())
   {
     this->ResetPreviewNode();
   }
 }
 
 void mitk::AutoMLSegmentationWithPreviewTool::DoUpdatePreview(const Image* inputAtTimeStep, const Image* /*oldSegAtTimeStep*/, Image* previewImage, TimeStepType timeStep)
 {
   const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
 
   if (nullptr == m_MLPreviewNode->GetData()
       || this->GetMTime() > m_MLPreviewNode->GetData()->GetMTime()
       || this->m_LastMLTimeStep != timeStep //this covers the case where dynamic
                                             //segmentations have to compute a preview
                                             //for all time steps on confirmation
       || this->GetLastTimePointOfUpdate() != timePoint //this ensures that static seg
                                                        //previews work with dynamic images
                                                        //with avoiding unnecessary other computations
      )
   {
     if (nullptr == inputAtTimeStep)
     {
       MITK_WARN << "Cannot run segementation. Currently selected input image is not set.";
       return;
     }
 
     this->m_LastMLTimeStep = timeStep;
 
     auto newMLPreview = ComputeMLPreview(inputAtTimeStep, timeStep);
 
     if (newMLPreview.IsNotNull())
     {
       this->m_MLPreviewNode->SetData(newMLPreview);
       this->m_MLPreviewNode->SetProperty("binary", mitk::BoolProperty::New(false));
       mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New();
       renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR);
       this->m_MLPreviewNode->SetProperty("Image Rendering.Mode", renderingMode);
       mitk::LookupTable::Pointer lut = mitk::LookupTable::New();
       mitk::LookupTableProperty::Pointer prop = mitk::LookupTableProperty::New(lut);
       vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
       lookupTable->SetHueRange(1.0, 0.0);
       lookupTable->SetSaturationRange(1.0, 1.0);
       lookupTable->SetValueRange(1.0, 1.0);
       lookupTable->SetTableRange(-1.0, 1.0);
       lookupTable->Build();
       lut->SetVtkLookupTable(lookupTable);
       prop->SetLookupTable(lut);
       this->m_MLPreviewNode->SetProperty("LookupTable", prop);
       mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
       mitk::LevelWindow levelwindow;
-      levelwindow.SetRangeMinMax(0, newMLPreview->GetScalarValueMax());
+      levelwindow.SetRangeMinMax(0, newMLPreview->GetStatistics()->GetScalarValueMax());
       levWinProp->SetLevelWindow(levelwindow);
       this->m_MLPreviewNode->SetProperty("levelwindow", levWinProp);
     }
   }
 
   if (!m_SelectedLabels.empty())
   {
     const auto mlPreviewImage = this->GetMLPreview();
     if (nullptr != mlPreviewImage)
     {
       AccessByItk_n(mlPreviewImage, CalculateMergedSimplePreview, (previewImage, timeStep));
     }
   }
 }
 
 template <typename TPixel, unsigned int VImageDimension>
 void mitk::AutoMLSegmentationWithPreviewTool::CalculateMergedSimplePreview(const itk::Image<TPixel, VImageDimension>* itkImage, mitk::Image* segmentation, unsigned int timeStep)
 {
   typedef itk::Image<TPixel, VImageDimension> InputImageType;
   typedef itk::Image<mitk::Tool::DefaultSegmentationDataType, VImageDimension> OutputImageType;
 
   typedef itk::BinaryThresholdImageFilter<InputImageType, OutputImageType> FilterType;
 
   typename FilterType::Pointer filter = FilterType::New();
 
   // InputImageType::Pointer itkImage;
   typename OutputImageType::Pointer itkBinaryResultImage;
 
   filter->SetInput(itkImage);
   filter->SetLowerThreshold(m_SelectedLabels[0]);
   filter->SetUpperThreshold(m_SelectedLabels[0]);
   filter->SetInsideValue(1);
   filter->SetOutsideValue(0);
   filter->AddObserver(itk::ProgressEvent(), m_ProgressCommand);
   filter->Update();
   itkBinaryResultImage = filter->GetOutput();
   itkBinaryResultImage->DisconnectPipeline();
 
   // if more than one region id is used compute the union of all given binary regions
   for (const auto labelID : m_SelectedLabels)
   {
     if (labelID != m_SelectedLabels[0])
     {
       filter->SetLowerThreshold(labelID);
       filter->SetUpperThreshold(labelID);
       filter->SetInsideValue(1);
       filter->SetOutsideValue(0);
       filter->Update();
 
       typename OutputImageType::Pointer tempImage = filter->GetOutput();
 
       typename itk::OrImageFilter<OutputImageType, OutputImageType>::Pointer orFilter =
         itk::OrImageFilter<OutputImageType, OutputImageType>::New();
       orFilter->SetInput1(tempImage);
       orFilter->SetInput2(itkBinaryResultImage);
       orFilter->AddObserver(itk::ProgressEvent(), m_ProgressCommand);
 
       orFilter->UpdateLargestPossibleRegion();
       itkBinaryResultImage = orFilter->GetOutput();
     }
   }
   //----------------------------------------------------------------------------------------------------
 
   segmentation->SetVolume((void*)(itkBinaryResultImage->GetPixelContainer()->GetBufferPointer()), timeStep);
 }
diff --git a/Modules/Segmentation/Interactions/mitkSegmentationInteractor.cpp b/Modules/Segmentation/Interactions/mitkSegmentationInteractor.cpp
index 1b67d32f1f..f14f92c7a4 100644
--- a/Modules/Segmentation/Interactions/mitkSegmentationInteractor.cpp
+++ b/Modules/Segmentation/Interactions/mitkSegmentationInteractor.cpp
@@ -1,63 +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.
 
 ============================================================================*/
 
 #include "mitkSegmentationInteractor.h"
 #include "mitkInteractionPositionEvent.h"
 #include "mitkLabelSetImage.h"
 #include "mitkToolManager.h"
 #include "mitkToolManagerProvider.h"
 #include <mitkImagePixelReadAccessor.h>
 
 #include <cstring>
 
 void mitk::SegmentationInteractor::ConnectActionsAndFunctions()
 {
   Superclass::ConnectActionsAndFunctions();
 
   // CONNECT_FUNCTION("change_active_label", ChangeActiveLabel);
 }
 
 bool mitk::SegmentationInteractor::ChangeActiveLabel(StateMachineAction *, InteractionEvent *interactionEvent)
 {
   BaseRenderer::Pointer sender = interactionEvent->GetSender();
-  auto *positionEvent = static_cast<InteractionPositionEvent *>(interactionEvent);
+  auto positionEvent = static_cast<InteractionPositionEvent*>(interactionEvent);
 
-  // MLI TODO
-  // m_LastDisplayCoordinate = m_CurrentDisplayCoordinate;
-  // m_CurrentDisplayCoordinate = positionEvent->GetPointerPositionOnScreen();
-
-  auto *toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(
+  auto toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(
     mitk::ToolManagerProvider::MULTILABEL_SEGMENTATION);
 
   assert(toolManager);
 
   DataNode *workingNode(toolManager->GetWorkingData(0));
-  if (workingNode)
+  if (workingNode && positionEvent)
   {
-    auto *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
-    assert(workingImage);
+    //TODO T28561
+    //Code uses a deprecated method. deactivated whole code until the refactorization is done.
+    throw "TODO T28561. Was forgot to refactor in context of T28524. The new MultiLabelSegmentation class will have a dedicated function for querying the label of world position.";
+
+    //auto *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
+    //assert(workingImage);
+
+    //const auto timestep = positionEvent->GetSender()->GetTimeStep(workingImage);
 
-    const auto timestep = positionEvent->GetSender()->GetTimeStep(workingImage);
-    int pixelValue = static_cast<int>(workingImage->GetPixelValueByWorldCoordinate(positionEvent->GetPositionInWorld(), timestep));
+   //int pixelValue = static_cast<int>(workingImage->GetPixelValueByWorldCoordinate(positionEvent->GetPositionInWorld(), timestep));
+    //workingImage->GetActiveLabelSet()->SetActiveLabel(pixelValue); // can be the background
 
-    workingImage->GetActiveLabelSet()->SetActiveLabel(pixelValue); // can be the background
+    // // Call Events
+    // // workingImage->ActiveLabelEvent.Send(pixelValue);
 
-    // Call Events
-    // workingImage->ActiveLabelEvent.Send(pixelValue);
+    // // MLI TODO
+    // // toolManager->WorkingDataModified.Send();
 
-    // MLI TODO
-    // toolManager->WorkingDataModified.Send();
+    //TODO END Refactor with T28524
   }
 
   RenderingManager::GetInstance()->RequestUpdateAll();
   return true;
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp b/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp
index 81080382e7..d731966d1f 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkSliceBasedInterpolatorWidget.cpp
@@ -1,710 +1,710 @@
 /*============================================================================
 
 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 "QmitkSliceBasedInterpolatorWidget.h"
 
 #include <mitkColorProperty.h>
 #include <mitkDiffSliceOperation.h>
 #include <mitkDiffSliceOperationApplier.h>
 #include <mitkExtractSliceFilter.h>
 #include <mitkImageAccessByItk.h>
 #include <mitkImageCast.h>
 #include <mitkImageTimeSelector.h>
 #include <mitkLabelSetImage.h>
 #include <mitkOperationEvent.h>
 #include <mitkProgressBar.h>
 #include <mitkProperties.h>
 #include <mitkRenderingManager.h>
 #include <mitkSegTool2D.h>
 #include <mitkSliceNavigationController.h>
 #include <mitkToolManager.h>
 #include <mitkToolManagerProvider.h>
 #include <mitkUndoController.h>
 #include <mitkVtkImageOverwrite.h>
 
 #include "QmitkStdMultiWidget.h"
 
 #include <itkCommand.h>
 
 #include <QApplication>
 #include <QCursor>
 #include <QMenu>
 #include <QMessageBox>
 
 QmitkSliceBasedInterpolatorWidget::QmitkSliceBasedInterpolatorWidget(QWidget *parent, const char * /*name*/)
   : QWidget(parent),
     m_SliceInterpolatorController(mitk::SliceBasedInterpolationController::New()),
     m_ToolManager(nullptr),
     m_Activated(false),
     m_DataStorage(nullptr),
     m_LastSNC(nullptr),
     m_LastSliceIndex(0)
 {
   m_Controls.setupUi(this);
 
   m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(mitk::ToolManagerProvider::MULTILABEL_SEGMENTATION);
 
   m_ToolManager->WorkingDataChanged += mitk::MessageDelegate<QmitkSliceBasedInterpolatorWidget>(
     this, &QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified);
 
   connect(m_Controls.m_btStart, SIGNAL(toggled(bool)), this, SLOT(OnToggleWidgetActivation(bool)));
   connect(m_Controls.m_btApplyForCurrentSlice, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked()));
   connect(m_Controls.m_btApplyForAllSlices, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked()));
 
   itk::ReceptorMemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer command =
     itk::ReceptorMemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
   command->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceInterpolationInfoChanged);
   m_InterpolationInfoChangedObserverTag = m_SliceInterpolatorController->AddObserver(itk::ModifiedEvent(), command);
 
   // feedback node and its visualization properties
   m_PreviewNode = mitk::DataNode::New();
   m_PreviewNode->SetName("3D tool preview");
 
   m_PreviewNode->SetProperty("texture interpolation", mitk::BoolProperty::New(false));
   m_PreviewNode->SetProperty("layer", mitk::IntProperty::New(100));
   m_PreviewNode->SetProperty("binary", mitk::BoolProperty::New(true));
   m_PreviewNode->SetProperty("outline binary", mitk::BoolProperty::New(true));
   m_PreviewNode->SetProperty("outline binary shadow", mitk::BoolProperty::New(true));
   m_PreviewNode->SetProperty("helper object", mitk::BoolProperty::New(true));
   m_PreviewNode->SetOpacity(1.0);
   m_PreviewNode->SetColor(0.0, 1.0, 0.0);
 
   m_Controls.m_btApplyForCurrentSlice->setEnabled(false);
   m_Controls.m_btApplyForAllSlices->setEnabled(false);
 
   this->setEnabled(false);
 }
 
 QmitkSliceBasedInterpolatorWidget::~QmitkSliceBasedInterpolatorWidget()
 {
   m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate<QmitkSliceBasedInterpolatorWidget>(
     this, &QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified);
 
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToSliceObserverTag.keys())
   {
     slicer->RemoveObserver(m_ControllerToDeleteObserverTag.take(slicer));
     slicer->RemoveObserver(m_ControllerToTimeObserverTag.take(slicer));
     slicer->RemoveObserver(m_ControllerToSliceObserverTag.take(slicer));
   }
 
   m_ActionToSliceDimensionMap.clear();
 
   // remove observer
   m_SliceInterpolatorController->RemoveObserver(m_InterpolationInfoChangedObserverTag);
 }
 
 const QmitkSliceBasedInterpolatorWidget::ActionToSliceDimensionMapType
   QmitkSliceBasedInterpolatorWidget::CreateActionToSliceDimension()
 {
   ActionToSliceDimensionMapType actionToSliceDimension;
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToDeleteObserverTag.keys())
   {
     std::string name = slicer->GetRenderer()->GetName();
     if (name == "stdmulti.widget0")
       name = "Axial (red window)";
     else if (name == "stdmulti.widget1")
       name = "Sagittal (green window)";
     else if (name == "stdmulti.widget2")
       name = "Coronal (blue window)";
     actionToSliceDimension[new QAction(QString::fromStdString(name), nullptr)] = slicer;
   }
 
   return actionToSliceDimension;
 }
 
 void QmitkSliceBasedInterpolatorWidget::SetDataStorage(mitk::DataStorage &storage)
 {
   m_DataStorage = &storage;
 }
 
 void QmitkSliceBasedInterpolatorWidget::SetSliceNavigationControllers(
   const QList<mitk::SliceNavigationController *> &controllers)
 {
   Q_ASSERT(!controllers.empty());
 
   // connect to the slice navigation controller. after each change, call the interpolator
   foreach (mitk::SliceNavigationController *slicer, controllers)
   {
     // Has to be initialized
     m_LastSNC = slicer;
 
     m_TimePoints.insert(slicer, slicer->GetSelectedTimePoint());
 
     itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer deleteCommand =
       itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
     deleteCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceNavigationControllerDeleted);
     m_ControllerToDeleteObserverTag.insert(slicer, slicer->AddObserver(itk::DeleteEvent(), deleteCommand));
 
     itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer timeChangedCommand =
       itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
     timeChangedCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnTimeChanged);
     m_ControllerToTimeObserverTag.insert(
       slicer,
       slicer->AddObserver(mitk::SliceNavigationController::TimeGeometryEvent(nullptr, 0), timeChangedCommand));
 
     itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::Pointer sliceChangedCommand =
       itk::MemberCommand<QmitkSliceBasedInterpolatorWidget>::New();
     sliceChangedCommand->SetCallbackFunction(this, &QmitkSliceBasedInterpolatorWidget::OnSliceChanged);
     m_ControllerToSliceObserverTag.insert(
       slicer, slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), sliceChangedCommand));
   }
 
   m_ActionToSliceDimensionMap = this->CreateActionToSliceDimension();
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnToolManagerWorkingDataModified()
 {
   mitk::DataNode *workingNode = this->m_ToolManager->GetWorkingData(0);
   if (!workingNode)
   {
     this->setEnabled(false);
     return;
   }
 
   mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
   // TODO adapt tool manager so that this check is done there, e.g. convenience function
   //  Q_ASSERT(workingImage);
   if (!workingImage)
   {
     this->setEnabled(false);
     return;
   }
 
   if (workingImage->GetDimension() > 4 || workingImage->GetDimension() < 3)
   {
     this->setEnabled(false);
     return;
   }
 
   m_WorkingImage = workingImage;
 
   this->setEnabled(true);
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnTimeChanged(itk::Object *sender, const itk::EventObject &e)
 {
   // Check if we really have a GeometryTimeEvent
   if (!dynamic_cast<const mitk::SliceNavigationController::GeometryTimeEvent *>(&e))
     return;
 
   mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
   Q_ASSERT(slicer);
 
   m_TimePoints[slicer] = slicer->GetSelectedTimePoint();
 
   // TODO Macht das hier wirklich Sinn????
   if (m_LastSNC == slicer)
   {
     slicer->SendSlice(); // will trigger a new interpolation
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnSliceChanged(itk::Object *sender, const itk::EventObject &e)
 {
   if (m_Activated && m_WorkingImage.IsNotNull())
   {
     // Check whether we really have a GeometrySliceEvent
     if (!dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent *>(&e))
       return;
 
     mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
     if (slicer)
     {
       this->TranslateAndInterpolateChangedSlice(e, slicer);
       mitk::RenderingManager::GetInstance()->RequestUpdateAll();
       //  slicer->GetRenderer()->RequestUpdate();
     }
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::TranslateAndInterpolateChangedSlice(const itk::EventObject &e,
                                                                             mitk::SliceNavigationController *slicer)
 {
   if (m_Activated && m_WorkingImage.IsNotNull())
   {
     const mitk::SliceNavigationController::GeometrySliceEvent &geometrySliceEvent =
       dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent &>(e);
     mitk::TimeGeometry *timeGeometry = geometrySliceEvent.GetTimeGeometry();
     if (timeGeometry && m_TimePoints.contains(slicer) && timeGeometry->IsValidTimePoint(m_TimePoints[slicer]))
     {
       mitk::SlicedGeometry3D *slicedGeometry =
         dynamic_cast<mitk::SlicedGeometry3D *>(timeGeometry->GetGeometryForTimePoint(m_TimePoints[slicer]).GetPointer());
       if (slicedGeometry)
       {
         mitk::PlaneGeometry *plane = slicedGeometry->GetPlaneGeometry(geometrySliceEvent.GetPos());
         if (plane)
         {
           m_LastSNC = slicer;
           this->Interpolate(plane, m_TimePoints[slicer], slicer);
         }
       }
     }
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::Interpolate(mitk::PlaneGeometry *plane,
                                                     mitk::TimePointType timePoint,
                                                     mitk::SliceNavigationController *slicer)
 {
   int clickedSliceDimension(-1);
   int clickedSliceIndex(-1);
 
   if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint))
   {
     MITK_WARN << "Cannot interpolate WorkingImage. Passed time point is not within the time bounds of WorkingImage. Time point: " << timePoint;
     return;
   }
   const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
-  // calculate real slice position, i.e. slice of the image and not slice of the TimeSlicedGeometry
+  // calculate real slice position, i.e. slice of the image
   // see if timestep is needed here
   mitk::SegTool2D::DetermineAffectedImageSlice(m_WorkingImage, plane, clickedSliceDimension, clickedSliceIndex);
 
   mitk::Image::Pointer interpolation =
     m_SliceInterpolatorController->Interpolate(clickedSliceDimension, clickedSliceIndex, plane, timeStep);
 
   m_PreviewNode->SetData(interpolation);
 
   const mitk::Color &color = m_WorkingImage->GetActiveLabel()->GetColor();
   m_PreviewNode->SetColor(color);
 
   m_LastSNC = slicer;
   m_LastSliceIndex = clickedSliceIndex;
 }
 
 mitk::Image::Pointer QmitkSliceBasedInterpolatorWidget::GetWorkingSlice(const mitk::PlaneGeometry *planeGeometry)
 {
   const auto timePoint = m_LastSNC->GetSelectedTimePoint();
 
   if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint))
   {
     MITK_WARN << "Cannot get slice of WorkingImage. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint;
     return nullptr;
   }
 
   // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
   // reslicer
   vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
   // set to false to extract a slice
   reslice->SetOverwriteMode(false);
   reslice->Modified();
 
   // use ExtractSliceFilter with our specific vtkImageReslice for overwriting and extracting
   mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice);
   extractor->SetInput(m_WorkingImage);
   const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
   extractor->SetTimeStep(timeStep);
   extractor->SetWorldGeometry(planeGeometry);
   extractor->SetVtkOutputRequest(false);
   extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
 
   extractor->Modified();
 
   try
   {
     extractor->Update();
   }
   catch (itk::ExceptionObject &excep)
   {
     MITK_ERROR << "Exception caught: " << excep.GetDescription();
     return nullptr;
   }
 
   mitk::Image::Pointer slice = extractor->GetOutput();
 
   // specify the undo operation with the non edited slice
   // MLI TODO added code starts here
   mitk::SlicedGeometry3D *sliceGeometry = dynamic_cast<mitk::SlicedGeometry3D *>(slice->GetGeometry());
   // m_undoOperation = new mitk::DiffSliceOperation(m_WorkingImage, extractor->GetVtkOutput(), slice->GetGeometry(),
   // timeStep, const_cast<mitk::PlaneGeometry*>(planeGeometry));
   // added code ends here
   m_undoOperation = new mitk::DiffSliceOperation(
     m_WorkingImage, extractor->GetOutput(), sliceGeometry, timeStep, const_cast<mitk::PlaneGeometry *>(planeGeometry));
 
   slice->DisconnectPipeline();
 
   return slice;
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnToggleWidgetActivation(bool enabled)
 {
   Q_ASSERT(m_ToolManager);
 
   mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
   if (!workingNode)
     return;
 
   m_Controls.m_btApplyForCurrentSlice->setEnabled(enabled);
   m_Controls.m_btApplyForAllSlices->setEnabled(enabled);
 
   if (enabled)
     m_Controls.m_btStart->setText("Stop");
   else
     m_Controls.m_btStart->setText("Start");
 
   unsigned int numberOfExistingTools = m_ToolManager->GetTools().size();
   for (unsigned int i = 0; i < numberOfExistingTools; i++)
   {
     // mitk::SegTool2D* tool = dynamic_cast<mitk::SegTool2D*>(m_ToolManager->GetToolById(i));
     // MLI TODO
     // if (tool) tool->SetEnable2DInterpolation( enabled );
   }
 
   if (enabled)
   {
     if (!m_DataStorage->Exists(m_PreviewNode))
     {
       m_DataStorage->Add(m_PreviewNode);
     }
 
     m_SliceInterpolatorController->SetWorkingImage(m_WorkingImage);
     this->UpdateVisibleSuggestion();
   }
   else
   {
     if (m_DataStorage->Exists(m_PreviewNode))
     {
       m_DataStorage->Remove(m_PreviewNode);
     }
 
     mitk::UndoController::GetCurrentUndoModel()->Clear();
   }
 
   m_Activated = enabled;
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 template <typename TPixel, unsigned int VImageDimension>
 void QmitkSliceBasedInterpolatorWidget::WritePreviewOnWorkingImage(itk::Image<TPixel, VImageDimension> *targetSlice,
                                                                    const mitk::Image *sourceSlice,
                                                                    int overwritevalue)
 {
   typedef itk::Image<TPixel, VImageDimension> ImageType;
 
   typename ImageType::Pointer sourceSliceITK;
   mitk::CastToItkImage(sourceSlice, sourceSliceITK);
 
   // now the original slice and the ipSegmentation-painted slice are in the same format, and we can just copy all pixels
   // that are non-zero
   typedef itk::ImageRegionIterator<ImageType> OutputIteratorType;
   typedef itk::ImageRegionConstIterator<ImageType> InputIteratorType;
 
   InputIteratorType inputIterator(sourceSliceITK, sourceSliceITK->GetLargestPossibleRegion());
   OutputIteratorType outputIterator(targetSlice, targetSlice->GetLargestPossibleRegion());
 
   outputIterator.GoToBegin();
   inputIterator.GoToBegin();
 
   int activePixelValue = m_WorkingImage->GetActiveLabel()->GetValue();
 
   if (activePixelValue == 0) // if exterior is the active label
   {
     while (!outputIterator.IsAtEnd())
     {
       if (inputIterator.Get() != 0)
       {
         outputIterator.Set(overwritevalue);
       }
       ++outputIterator;
       ++inputIterator;
     }
   }
   else if (overwritevalue != 0) // if we are not erasing
   {
     while (!outputIterator.IsAtEnd())
     {
       int targetValue = static_cast<int>(outputIterator.Get());
       if (inputIterator.Get() != 0)
       {
         if (!m_WorkingImage->GetLabel(targetValue)->GetLocked())
           outputIterator.Set(overwritevalue);
       }
 
       ++outputIterator;
       ++inputIterator;
     }
   }
   else // if we are erasing
   {
     while (!outputIterator.IsAtEnd())
     {
       const int targetValue = outputIterator.Get();
       if (inputIterator.Get() != 0)
       {
         if (targetValue == activePixelValue)
           outputIterator.Set(overwritevalue);
       }
 
       ++outputIterator;
       ++inputIterator;
     }
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnAcceptInterpolationClicked()
 {
   if (m_WorkingImage.IsNotNull() && m_PreviewNode->GetData())
   {
     const mitk::PlaneGeometry *planeGeometry = m_LastSNC->GetCurrentPlaneGeometry();
     if (!planeGeometry)
       return;
 
     mitk::Image::Pointer sliceImage = this->GetWorkingSlice(planeGeometry);
     if (sliceImage.IsNull())
       return;
 
     mitk::Image::Pointer previewSlice = dynamic_cast<mitk::Image *>(m_PreviewNode->GetData());
 
     AccessFixedDimensionByItk_2(
       sliceImage, WritePreviewOnWorkingImage, 2, previewSlice, m_WorkingImage->GetActiveLabel()->GetValue());
 
     // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
     // reslicer
     vtkSmartPointer<mitkVtkImageOverwrite> overwrite = vtkSmartPointer<mitkVtkImageOverwrite>::New();
     overwrite->SetInputSlice(sliceImage->GetVtkImageData());
     // set overwrite mode to true to write back to the image volume
     overwrite->SetOverwriteMode(true);
     overwrite->Modified();
 
     const auto timePoint = m_LastSNC->GetSelectedTimePoint();
     if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint))
     {
       MITK_WARN << "Cannot accept interpolation. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint;
       return;
     }
 
     mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(overwrite);
     extractor->SetInput(m_WorkingImage);
     const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
     extractor->SetTimeStep(timeStep);
     extractor->SetWorldGeometry(planeGeometry);
     extractor->SetVtkOutputRequest(false);
     extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
 
     extractor->Modified();
 
     try
     {
       extractor->Update();
     }
     catch (itk::ExceptionObject &excep)
     {
       MITK_ERROR << "Exception caught: " << excep.GetDescription();
       return;
     }
 
     // the image was modified within the pipeline, but not marked so
     m_WorkingImage->Modified();
 
     int clickedSliceDimension(-1);
     int clickedSliceIndex(-1);
 
     mitk::SegTool2D::DetermineAffectedImageSlice(
       m_WorkingImage, planeGeometry, clickedSliceDimension, clickedSliceIndex);
 
     m_SliceInterpolatorController->SetChangedSlice(sliceImage, clickedSliceDimension, clickedSliceIndex, timeStep);
 
     // specify the undo operation with the edited slice
     // MLI TODO added code starts here
     mitk::SlicedGeometry3D *sliceGeometry = dynamic_cast<mitk::SlicedGeometry3D *>(sliceImage->GetGeometry());
     // m_undoOperation = new mitk::DiffSliceOperation(m_WorkingImage, extractor->GetVtkOutput(), slice->GetGeometry(),
     // timeStep, const_cast<mitk::PlaneGeometry*>(planeGeometry));
     // added code ends here
     m_doOperation = new mitk::DiffSliceOperation(m_WorkingImage,
                                                  extractor->GetOutput(),
                                                  sliceGeometry,
                                                  timeStep,
                                                  const_cast<mitk::PlaneGeometry *>(planeGeometry));
 
     // create an operation event for the undo stack
     mitk::OperationEvent *undoStackItem = new mitk::OperationEvent(
       mitk::DiffSliceOperationApplier::GetInstance(), m_doOperation, m_undoOperation, "Slice Interpolation");
 
     // add it to the undo controller
     mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent(undoStackItem);
 
     // clear the pointers as the operation are stored in the undo controller and also deleted from there
     m_undoOperation = nullptr;
     m_doOperation = nullptr;
 
     m_PreviewNode->SetData(nullptr);
 
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::AcceptAllInterpolations(mitk::SliceNavigationController *slicer)
 {
   // Since we need to shift the plane it must be clone so that the original plane isn't altered
   mitk::PlaneGeometry::Pointer reslicePlane = slicer->GetCurrentPlaneGeometry()->Clone();
   const auto timePoint = slicer->GetSelectedTimePoint();
   if (!m_WorkingImage->GetTimeGeometry()->IsValidTimePoint(timePoint))
   {
     MITK_WARN << "Cannot accept all interpolations. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint;
 
     return;
   }
   const auto timeStep = m_WorkingImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
   int sliceDimension(-1);
   int sliceIndex(-1);
 
   mitk::SegTool2D::DetermineAffectedImageSlice(m_WorkingImage, reslicePlane, sliceDimension, sliceIndex);
 
   unsigned int zslices = m_WorkingImage->GetDimension(sliceDimension);
 
   mitk::ProgressBar::GetInstance()->Reset();
   mitk::ProgressBar::GetInstance()->AddStepsToDo(zslices);
 
   mitk::Point3D origin = reslicePlane->GetOrigin();
 
   for (unsigned int idx = 0; idx < zslices; ++idx)
   {
     // Transforming the current origin of the reslice plane
     // so that it matches the one of the next slice
     m_WorkingImage->GetSlicedGeometry()->WorldToIndex(origin, origin);
     origin[sliceDimension] = idx;
     m_WorkingImage->GetSlicedGeometry()->IndexToWorld(origin, origin);
     reslicePlane->SetOrigin(origin);
 
     mitk::Image::Pointer interpolation =
       m_SliceInterpolatorController->Interpolate(sliceDimension, idx, reslicePlane, timeStep);
 
     if (interpolation.IsNotNull())
     {
       m_PreviewNode->SetData(interpolation);
 
       mitk::Image::Pointer sliceImage = this->GetWorkingSlice(reslicePlane);
       if (sliceImage.IsNull())
         return;
 
       AccessFixedDimensionByItk_2(
         sliceImage, WritePreviewOnWorkingImage, 2, interpolation, m_WorkingImage->GetActiveLabel()->GetValue());
 
       // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
       // reslicer
       vtkSmartPointer<mitkVtkImageOverwrite> overwrite = vtkSmartPointer<mitkVtkImageOverwrite>::New();
       overwrite->SetInputSlice(sliceImage->GetVtkImageData());
       // set overwrite mode to true to write back to the image volume
       overwrite->SetOverwriteMode(true);
       overwrite->Modified();
 
       mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(overwrite);
       extractor->SetInput(m_WorkingImage);
       extractor->SetTimeStep(timeStep);
       extractor->SetWorldGeometry(reslicePlane);
       extractor->SetVtkOutputRequest(true);
       extractor->SetResliceTransformByGeometry(m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
 
       extractor->Modified();
 
       try
       {
         extractor->Update();
       }
       catch (itk::ExceptionObject &excep)
       {
         MITK_ERROR << "Exception caught: " << excep.GetDescription();
         return;
       }
 
       m_WorkingImage->Modified();
 
       mitk::RenderingManager::GetInstance()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS);
     }
 
     mitk::ProgressBar::GetInstance()->Progress();
   }
 
   m_SliceInterpolatorController->SetWorkingImage(m_WorkingImage);
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnAcceptAllInterpolationsClicked()
 {
   QMenu orientationPopup(this);
   std::map<QAction *, mitk::SliceNavigationController *>::const_iterator it;
   for (it = m_ActionToSliceDimensionMap.begin(); it != m_ActionToSliceDimensionMap.end(); it++)
     orientationPopup.addAction(it->first);
 
   connect(&orientationPopup, SIGNAL(triggered(QAction *)), this, SLOT(OnAcceptAllPopupActivated(QAction *)));
 
   orientationPopup.exec(QCursor::pos());
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnAcceptAllPopupActivated(QAction *action)
 {
   ActionToSliceDimensionMapType::const_iterator iter = m_ActionToSliceDimensionMap.find(action);
   if (iter != m_ActionToSliceDimensionMap.end())
   {
     mitk::SliceNavigationController *slicer = iter->second;
     this->AcceptAllInterpolations(slicer);
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::UpdateVisibleSuggestion()
 {
   if (m_Activated && m_LastSNC)
   {
     // determine which one is the current view, try to do an initial interpolation
     mitk::BaseRenderer *renderer = m_LastSNC->GetRenderer();
     if (renderer && renderer->GetMapperID() == mitk::BaseRenderer::Standard2D)
     {
       const mitk::TimeGeometry *timeGeometry =
         dynamic_cast<const mitk::TimeGeometry *>(renderer->GetWorldTimeGeometry());
       if (timeGeometry)
       {
         mitk::SliceNavigationController::GeometrySliceEvent event(const_cast<mitk::TimeGeometry *>(timeGeometry),
                                                                   renderer->GetSlice());
         this->TranslateAndInterpolateChangedSlice(event, m_LastSNC);
         mitk::RenderingManager::GetInstance()->RequestUpdateAll();
       }
     }
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnSliceInterpolationInfoChanged(const itk::EventObject & /*e*/)
 {
   // something (e.g. undo) changed the interpolation info, we should refresh our display
   this->UpdateVisibleSuggestion();
 }
 
 void QmitkSliceBasedInterpolatorWidget::OnSliceNavigationControllerDeleted(const itk::Object *sender,
                                                                            const itk::EventObject & /*e*/)
 {
   // Don't know how to avoid const_cast here?!
   mitk::SliceNavigationController *slicer =
     dynamic_cast<mitk::SliceNavigationController *>(const_cast<itk::Object *>(sender));
   if (slicer)
   {
     m_ControllerToTimeObserverTag.remove(slicer);
     m_ControllerToSliceObserverTag.remove(slicer);
     m_ControllerToDeleteObserverTag.remove(slicer);
   }
 }
 
 void QmitkSliceBasedInterpolatorWidget::WaitCursorOn()
 {
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 }
 
 void QmitkSliceBasedInterpolatorWidget::WaitCursorOff()
 {
   this->RestoreOverrideCursor();
 }
 
 void QmitkSliceBasedInterpolatorWidget::RestoreOverrideCursor()
 {
   QApplication::restoreOverrideCursor();
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
index 6820efbc3b..8353719169 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
@@ -1,1405 +1,1405 @@
 /*============================================================================
 
 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 "QmitkSlicesInterpolator.h"
 
 #include "QmitkSelectableGLWidget.h"
 #include "QmitkStdMultiWidget.h"
 
 #include "mitkApplyDiffImageOperation.h"
 #include "mitkColorProperty.h"
 #include "mitkCoreObjectFactory.h"
 #include "mitkDiffImageApplier.h"
 #include "mitkInteractionConst.h"
 #include "mitkLevelWindowProperty.h"
 #include "mitkOperationEvent.h"
 #include "mitkOverwriteSliceImageFilter.h"
 #include "mitkProgressBar.h"
 #include "mitkProperties.h"
 #include "mitkRenderingManager.h"
 #include "mitkSegTool2D.h"
 #include "mitkSliceNavigationController.h"
 #include "mitkSurfaceToImageFilter.h"
 #include "mitkToolManager.h"
 #include "mitkUndoController.h"
 #include <mitkExtractSliceFilter.h>
 #include <mitkImageReadAccessor.h>
 #include <mitkImageTimeSelector.h>
 #include <mitkImageWriteAccessor.h>
 #include <mitkPlaneProposer.h>
 #include <mitkUnstructuredGridClusteringFilter.h>
 #include <mitkVtkImageOverwrite.h>
 
 #include <itkCommand.h>
 
 #include <QCheckBox>
 #include <QCursor>
 #include <QMenu>
 #include <QMessageBox>
 #include <QPushButton>
 #include <QVBoxLayout>
 
 #include <vtkPolyVertex.h>
 #include <vtkUnstructuredGrid.h>
 
 #include <array>
 
 namespace
 {
   template <typename T = mitk::BaseData>
   itk::SmartPointer<T> GetData(const mitk::DataNode* dataNode)
   {
     return nullptr != dataNode
       ? dynamic_cast<T*>(dataNode->GetData())
       : nullptr;
   }
 }
 
 float SURFACE_COLOR_RGB[3] = {0.49f, 1.0f, 0.16f};
 
 const std::map<QAction *, mitk::SliceNavigationController *> QmitkSlicesInterpolator::createActionToSliceDimension()
 {
   std::map<QAction *, mitk::SliceNavigationController *> actionToSliceDimension;
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToDeleteObserverTag.keys())
   {
     actionToSliceDimension[new QAction(QString::fromStdString(slicer->GetViewDirectionAsString()), nullptr)] = slicer;
   }
 
   return actionToSliceDimension;
 }
 
 QmitkSlicesInterpolator::QmitkSlicesInterpolator(QWidget *parent, const char * /*name*/)
   : QWidget(parent),
     //    ACTION_TO_SLICEDIMENSION( createActionToSliceDimension() ),
     m_Interpolator(mitk::SegmentationInterpolationController::New()),
     m_SurfaceInterpolator(mitk::SurfaceInterpolationController::GetInstance()),
     m_ToolManager(nullptr),
     m_Initialized(false),
     m_LastSNC(nullptr),
     m_LastSliceIndex(0),
     m_2DInterpolationEnabled(false),
     m_3DInterpolationEnabled(false),
     m_FirstRun(true)
 {
   m_GroupBoxEnableExclusiveInterpolationMode = new QGroupBox("Interpolation", this);
 
   QVBoxLayout *vboxLayout = new QVBoxLayout(m_GroupBoxEnableExclusiveInterpolationMode);
 
   m_EdgeDetector = mitk::FeatureBasedEdgeDetectionFilter::New();
   m_PointScorer = mitk::PointCloudScoringFilter::New();
 
   m_CmbInterpolation = new QComboBox(m_GroupBoxEnableExclusiveInterpolationMode);
   m_CmbInterpolation->addItem("Disabled");
   m_CmbInterpolation->addItem("2-Dimensional");
   m_CmbInterpolation->addItem("3-Dimensional");
   vboxLayout->addWidget(m_CmbInterpolation);
 
   m_BtnApply2D = new QPushButton("Confirm for single slice", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApply2D);
 
   m_BtnApplyForAllSlices2D = new QPushButton("Confirm for all slices", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApplyForAllSlices2D);
 
   m_BtnApply3D = new QPushButton("Confirm", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApply3D);
 
   // T28261
   // m_BtnSuggestPlane = new QPushButton("Suggest a plane", m_GroupBoxEnableExclusiveInterpolationMode);
   // vboxLayout->addWidget(m_BtnSuggestPlane);
 
   m_BtnReinit3DInterpolation = new QPushButton("Reinit Interpolation", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnReinit3DInterpolation);
 
   m_ChkShowPositionNodes = new QCheckBox("Show Position Nodes", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_ChkShowPositionNodes);
 
   this->HideAllInterpolationControls();
 
   connect(m_CmbInterpolation, SIGNAL(currentIndexChanged(int)), this, SLOT(OnInterpolationMethodChanged(int)));
   connect(m_BtnApply2D, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked()));
   connect(m_BtnApplyForAllSlices2D, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked()));
   connect(m_BtnApply3D, SIGNAL(clicked()), this, SLOT(OnAccept3DInterpolationClicked()));
 
   // T28261
   // connect(m_BtnSuggestPlane, SIGNAL(clicked()), this, SLOT(OnSuggestPlaneClicked()));
 
   connect(m_BtnReinit3DInterpolation, SIGNAL(clicked()), this, SLOT(OnReinit3DInterpolation()));
   connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SLOT(OnShowMarkers(bool)));
   connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SIGNAL(SignalShowMarkerNodes(bool)));
 
   QHBoxLayout *layout = new QHBoxLayout(this);
   layout->addWidget(m_GroupBoxEnableExclusiveInterpolationMode);
   this->setLayout(layout);
 
   itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::Pointer command =
     itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
   command->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnInterpolationInfoChanged);
   InterpolationInfoChangedObserverTag = m_Interpolator->AddObserver(itk::ModifiedEvent(), command);
 
   itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::Pointer command2 =
     itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
   command2->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged);
   SurfaceInterpolationInfoChangedObserverTag = m_SurfaceInterpolator->AddObserver(itk::ModifiedEvent(), command2);
 
   // feedback node and its visualization properties
   m_FeedbackNode = mitk::DataNode::New();
   mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(m_FeedbackNode);
 
   m_FeedbackNode->SetProperty("binary", mitk::BoolProperty::New(true));
   m_FeedbackNode->SetProperty("outline binary", mitk::BoolProperty::New(true));
   m_FeedbackNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 0.0));
   m_FeedbackNode->SetProperty("texture interpolation", mitk::BoolProperty::New(false));
   m_FeedbackNode->SetProperty("layer", mitk::IntProperty::New(20));
   m_FeedbackNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
   m_FeedbackNode->SetProperty("name", mitk::StringProperty::New("Interpolation feedback"));
   m_FeedbackNode->SetProperty("opacity", mitk::FloatProperty::New(0.8));
   m_FeedbackNode->SetProperty("helper object", mitk::BoolProperty::New(true));
 
   m_InterpolatedSurfaceNode = mitk::DataNode::New();
   m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
   m_InterpolatedSurfaceNode->SetProperty("name", mitk::StringProperty::New("Surface Interpolation feedback"));
   m_InterpolatedSurfaceNode->SetProperty("opacity", mitk::FloatProperty::New(0.5));
   m_InterpolatedSurfaceNode->SetProperty("line width", mitk::FloatProperty::New(4.0f));
   m_InterpolatedSurfaceNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
   m_InterpolatedSurfaceNode->SetProperty("helper object", mitk::BoolProperty::New(true));
   m_InterpolatedSurfaceNode->SetVisibility(false);
 
   m_3DContourNode = mitk::DataNode::New();
   m_3DContourNode->SetProperty("color", mitk::ColorProperty::New(0.0, 0.0, 0.0));
   m_3DContourNode->SetProperty("hidden object", mitk::BoolProperty::New(true));
   m_3DContourNode->SetProperty("name", mitk::StringProperty::New("Drawn Contours"));
   m_3DContourNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New(VTK_WIREFRAME));
   m_3DContourNode->SetProperty("material.wireframeLineWidth", mitk::FloatProperty::New(2.0f));
   m_3DContourNode->SetProperty("3DContourContainer", mitk::BoolProperty::New(true));
   m_3DContourNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
   m_3DContourNode->SetVisibility(
     false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget0")));
   m_3DContourNode->SetVisibility(
     false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")));
   m_3DContourNode->SetVisibility(
     false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2")));
   m_3DContourNode->SetVisibility(
     false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")));
 
   QWidget::setContentsMargins(0, 0, 0, 0);
   if (QWidget::layout() != nullptr)
   {
     QWidget::layout()->setContentsMargins(0, 0, 0, 0);
   }
 
   // For running 3D Interpolation in background
   // create a QFuture and a QFutureWatcher
 
   connect(&m_Watcher, SIGNAL(started()), this, SLOT(StartUpdateInterpolationTimer()));
   connect(&m_Watcher, SIGNAL(finished()), this, SLOT(OnSurfaceInterpolationFinished()));
   connect(&m_Watcher, SIGNAL(finished()), this, SLOT(StopUpdateInterpolationTimer()));
   m_Timer = new QTimer(this);
   connect(m_Timer, SIGNAL(timeout()), this, SLOT(ChangeSurfaceColor()));
 }
 
 void QmitkSlicesInterpolator::SetDataStorage(mitk::DataStorage::Pointer storage)
 {
   if (m_DataStorage == storage)
   {
     return;
   }
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.RemoveListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
   }
 
   m_DataStorage = storage;
   m_SurfaceInterpolator->SetDataStorage(storage);
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.AddListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
   }
 }
 
 mitk::DataStorage *QmitkSlicesInterpolator::GetDataStorage()
 {
   if (m_DataStorage.IsNotNull())
   {
     return m_DataStorage;
   }
   else
   {
     return nullptr;
   }
 }
 
 void QmitkSlicesInterpolator::Initialize(mitk::ToolManager *toolManager,
                                          const QList<mitk::SliceNavigationController *> &controllers)
 {
   Q_ASSERT(!controllers.empty());
 
   if (m_Initialized)
   {
     // remove old observers
     Uninitialize();
   }
 
   m_ToolManager = toolManager;
 
   if (m_ToolManager)
   {
     // set enabled only if a segmentation is selected
     mitk::DataNode *node = m_ToolManager->GetWorkingData(0);
     QWidget::setEnabled(node != nullptr);
 
     // react whenever the set of selected segmentation changes
     m_ToolManager->WorkingDataChanged +=
       mitk::MessageDelegate<QmitkSlicesInterpolator>(this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified);
     m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkSlicesInterpolator>(
       this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified);
 
     // connect to the slice navigation controller. after each change, call the interpolator
     foreach (mitk::SliceNavigationController *slicer, controllers)
     {
       // Has to be initialized
       m_LastSNC = slicer;
       m_TimePoints.insert(slicer, slicer->GetSelectedTimePoint());
 
       itk::MemberCommand<QmitkSlicesInterpolator>::Pointer deleteCommand =
         itk::MemberCommand<QmitkSlicesInterpolator>::New();
       deleteCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted);
       m_ControllerToDeleteObserverTag.insert(slicer, slicer->AddObserver(itk::DeleteEvent(), deleteCommand));
 
       itk::MemberCommand<QmitkSlicesInterpolator>::Pointer timeChangedCommand =
         itk::MemberCommand<QmitkSlicesInterpolator>::New();
       timeChangedCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnTimeChanged);
       m_ControllerToTimeObserverTag.insert(
         slicer, slicer->AddObserver(mitk::SliceNavigationController::TimeGeometryEvent(nullptr, 0), timeChangedCommand));
 
       itk::MemberCommand<QmitkSlicesInterpolator>::Pointer sliceChangedCommand =
         itk::MemberCommand<QmitkSlicesInterpolator>::New();
       sliceChangedCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSliceChanged);
       m_ControllerToSliceObserverTag.insert(
         slicer, slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), sliceChangedCommand));
     }
     ACTION_TO_SLICEDIMENSION = createActionToSliceDimension();
   }
 
   m_Initialized = true;
 }
 
 void QmitkSlicesInterpolator::Uninitialize()
 {
   if (m_ToolManager.IsNotNull())
   {
     m_ToolManager->WorkingDataChanged -=
       mitk::MessageDelegate<QmitkSlicesInterpolator>(this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified);
     m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkSlicesInterpolator>(
       this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified);
   }
 
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToSliceObserverTag.keys())
   {
     slicer->RemoveObserver(m_ControllerToDeleteObserverTag.take(slicer));
     slicer->RemoveObserver(m_ControllerToTimeObserverTag.take(slicer));
     slicer->RemoveObserver(m_ControllerToSliceObserverTag.take(slicer));
   }
 
   ACTION_TO_SLICEDIMENSION.clear();
 
   m_ToolManager = nullptr;
 
   m_Initialized = false;
 }
 
 QmitkSlicesInterpolator::~QmitkSlicesInterpolator()
 {
   if (m_Initialized)
   {
     // remove old observers
     Uninitialize();
   }
 
   WaitForFutures();
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.RemoveListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
     if (m_DataStorage->Exists(m_3DContourNode))
       m_DataStorage->Remove(m_3DContourNode);
     if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
       m_DataStorage->Remove(m_InterpolatedSurfaceNode);
   }
 
   // remove observer
   m_Interpolator->RemoveObserver(InterpolationInfoChangedObserverTag);
   m_SurfaceInterpolator->RemoveObserver(SurfaceInterpolationInfoChangedObserverTag);
 
   delete m_Timer;
 }
 
 /**
 External enableization...
 */
 void QmitkSlicesInterpolator::setEnabled(bool enable)
 {
   QWidget::setEnabled(enable);
 
   // Set the gui elements of the different interpolation modi enabled
   if (enable)
   {
     if (m_2DInterpolationEnabled)
     {
       this->Show2DInterpolationControls(true);
       m_Interpolator->Activate2DInterpolation(true);
     }
     else if (m_3DInterpolationEnabled)
     {
       this->Show3DInterpolationControls(true);
       this->Show3DInterpolationResult(true);
     }
   }
   // Set all gui elements of the interpolation disabled
   else
   {
     this->HideAllInterpolationControls();
     this->Show3DInterpolationResult(false);
   }
 }
 
 void QmitkSlicesInterpolator::On2DInterpolationEnabled(bool status)
 {
   OnInterpolationActivated(status);
   m_Interpolator->Activate2DInterpolation(status);
 }
 
 void QmitkSlicesInterpolator::On3DInterpolationEnabled(bool status)
 {
   On3DInterpolationActivated(status);
 }
 
 void QmitkSlicesInterpolator::OnInterpolationDisabled(bool status)
 {
   if (status)
   {
     OnInterpolationActivated(!status);
     On3DInterpolationActivated(!status);
     this->Show3DInterpolationResult(false);
   }
 }
 
 void QmitkSlicesInterpolator::HideAllInterpolationControls()
 {
   this->Show2DInterpolationControls(false);
   this->Show3DInterpolationControls(false);
 }
 
 void QmitkSlicesInterpolator::Show2DInterpolationControls(bool show)
 {
   m_BtnApply2D->setVisible(show);
   m_BtnApplyForAllSlices2D->setVisible(show);
 }
 
 void QmitkSlicesInterpolator::Show3DInterpolationControls(bool show)
 {
   m_BtnApply3D->setVisible(show);
 
   // T28261
   // m_BtnSuggestPlane->setVisible(show);
 
   m_ChkShowPositionNodes->setVisible(show);
   m_BtnReinit3DInterpolation->setVisible(show);
 }
 
 void QmitkSlicesInterpolator::OnInterpolationMethodChanged(int index)
 {
   switch (index)
   {
     case 0: // Disabled
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation");
       this->HideAllInterpolationControls();
       this->OnInterpolationActivated(false);
       this->On3DInterpolationActivated(false);
       this->Show3DInterpolationResult(false);
       m_Interpolator->Activate2DInterpolation(false);
       break;
 
     case 1: // 2D
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)");
       this->HideAllInterpolationControls();
       this->Show2DInterpolationControls(true);
       this->OnInterpolationActivated(true);
       this->On3DInterpolationActivated(false);
       m_Interpolator->Activate2DInterpolation(true);
       break;
 
     case 2: // 3D
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)");
       this->HideAllInterpolationControls();
       this->Show3DInterpolationControls(true);
       this->OnInterpolationActivated(false);
       this->On3DInterpolationActivated(true);
       m_Interpolator->Activate2DInterpolation(false);
       break;
 
     default:
       MITK_ERROR << "Unknown interpolation method!";
       m_CmbInterpolation->setCurrentIndex(0);
       break;
   }
 }
 
 void QmitkSlicesInterpolator::OnShowMarkers(bool state)
 {
   mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers =
     m_DataStorage->GetSubset(mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true)));
 
   for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End();
        ++it)
   {
     it->Value()->SetProperty("helper object", mitk::BoolProperty::New(!state));
   }
 }
 
 void QmitkSlicesInterpolator::OnToolManagerWorkingDataModified()
 {
   if (m_ToolManager->GetWorkingData(0) != nullptr)
   {
     m_Segmentation = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());
     m_BtnReinit3DInterpolation->setEnabled(true);
   }
   else
   {
     // If no workingdata is set, remove the interpolation feedback
     this->GetDataStorage()->Remove(m_FeedbackNode);
     m_FeedbackNode->SetData(nullptr);
     this->GetDataStorage()->Remove(m_3DContourNode);
     m_3DContourNode->SetData(nullptr);
     this->GetDataStorage()->Remove(m_InterpolatedSurfaceNode);
     m_InterpolatedSurfaceNode->SetData(nullptr);
     m_BtnReinit3DInterpolation->setEnabled(false);
     return;
   }
   // Updating the current selected segmentation for the 3D interpolation
   SetCurrentContourListID();
 
   if (m_2DInterpolationEnabled)
   {
     OnInterpolationActivated(true); // re-initialize if needed
   }
   this->CheckSupportedImageDimension();
 }
 
 void QmitkSlicesInterpolator::OnToolManagerReferenceDataModified()
 {
 }
 
 void QmitkSlicesInterpolator::OnTimeChanged(itk::Object *sender, const itk::EventObject &e)
 {
   // Check if we really have a GeometryTimeEvent
   if (!dynamic_cast<const mitk::SliceNavigationController::GeometryTimeEvent *>(&e))
     return;
 
   mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
   Q_ASSERT(slicer);
 
   const auto timePoint = slicer->GetSelectedTimePoint();
   m_TimePoints[slicer] = timePoint;
 
   m_SurfaceInterpolator->SetCurrentTimePoint(timePoint);
 
   if (m_LastSNC == slicer)
   {
     slicer->SendSlice(); // will trigger a new interpolation
   }
 }
 
 void QmitkSlicesInterpolator::OnSliceChanged(itk::Object *sender, const itk::EventObject &e)
 {
   // Check whether we really have a GeometrySliceEvent
   if (!dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent *>(&e))
     return;
 
   mitk::SliceNavigationController *slicer = dynamic_cast<mitk::SliceNavigationController *>(sender);
 
   if (TranslateAndInterpolateChangedSlice(e, slicer))
   {
     slicer->GetRenderer()->RequestUpdate();
   }
 }
 
 bool QmitkSlicesInterpolator::TranslateAndInterpolateChangedSlice(const itk::EventObject &e,
                                                                   mitk::SliceNavigationController *slicer)
 {
   if (!m_2DInterpolationEnabled)
     return false;
 
   try
   {
     const mitk::SliceNavigationController::GeometrySliceEvent &event =
       dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent &>(e);
 
     mitk::TimeGeometry *tsg = event.GetTimeGeometry();
     if (tsg && m_TimePoints.contains(slicer) && tsg->IsValidTimePoint(m_TimePoints[slicer]))
     {
       mitk::SlicedGeometry3D *slicedGeometry =
         dynamic_cast<mitk::SlicedGeometry3D *>(tsg->GetGeometryForTimePoint(m_TimePoints[slicer]).GetPointer());
       if (slicedGeometry)
       {
         m_LastSNC = slicer;
         mitk::PlaneGeometry *plane =
           dynamic_cast<mitk::PlaneGeometry *>(slicedGeometry->GetPlaneGeometry(event.GetPos()));
         if (plane)
           Interpolate(plane, m_TimePoints[slicer], slicer);
         return true;
       }
     }
   }
   catch (const std::bad_cast &)
   {
     return false; // so what
   }
 
   return false;
 }
 
 void QmitkSlicesInterpolator::Interpolate(mitk::PlaneGeometry *plane,
                                           mitk::TimePointType timePoint,
                                           mitk::SliceNavigationController *slicer)
 {
   if (m_ToolManager)
   {
     mitk::DataNode *node = m_ToolManager->GetWorkingData(0);
     if (node)
     {
       m_Segmentation = dynamic_cast<mitk::Image *>(node->GetData());
       if (m_Segmentation)
       {
         if (!m_Segmentation->GetTimeGeometry()->IsValidTimePoint(timePoint))
         {
           MITK_WARN << "Cannot interpolate segmentation. Passed time point is not within the time bounds of WorkingImage. Time point: " << timePoint;
           return;
         }
         const auto timeStep = m_Segmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
         int clickedSliceDimension(-1);
         int clickedSliceIndex(-1);
 
-        // calculate real slice position, i.e. slice of the image and not slice of the TimeSlicedGeometry
+        // calculate real slice position, i.e. slice of the image
         mitk::SegTool2D::DetermineAffectedImageSlice(m_Segmentation, plane, clickedSliceDimension, clickedSliceIndex);
 
         mitk::Image::Pointer interpolation =
           m_Interpolator->Interpolate(clickedSliceDimension, clickedSliceIndex, plane, timeStep);
         m_FeedbackNode->SetData(interpolation);
 
         m_LastSNC = slicer;
         m_LastSliceIndex = clickedSliceIndex;
       }
     }
   }
 }
 
 void QmitkSlicesInterpolator::OnSurfaceInterpolationFinished()
 {
   mitk::Surface::Pointer interpolatedSurface = m_SurfaceInterpolator->GetInterpolationResult();
   mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
 
   if (interpolatedSurface.IsNotNull() && workingNode &&
       workingNode->IsVisible(
         mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2"))))
   {
     m_BtnApply3D->setEnabled(true);
 
     // T28261
     // m_BtnSuggestPlane->setEnabled(true);
 
     m_InterpolatedSurfaceNode->SetData(interpolatedSurface);
     m_3DContourNode->SetData(m_SurfaceInterpolator->GetContoursAsSurface());
 
     this->Show3DInterpolationResult(true);
 
     if (!m_DataStorage->Exists(m_InterpolatedSurfaceNode))
     {
       m_DataStorage->Add(m_InterpolatedSurfaceNode);
     }
     if (!m_DataStorage->Exists(m_3DContourNode))
     {
       m_DataStorage->Add(m_3DContourNode, workingNode);
     }
   }
   else if (interpolatedSurface.IsNull())
   {
     m_BtnApply3D->setEnabled(false);
 
     // T28261
     // m_BtnSuggestPlane->setEnabled(false);
 
     if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
     {
       this->Show3DInterpolationResult(false);
     }
   }
 
   m_BtnReinit3DInterpolation->setEnabled(true);
 
   foreach (mitk::SliceNavigationController *slicer, m_ControllerToTimeObserverTag.keys())
   {
     slicer->GetRenderer()->RequestUpdate();
   }
 }
 
 void QmitkSlicesInterpolator::OnAcceptInterpolationClicked()
 {
   if (m_Segmentation && m_FeedbackNode->GetData())
   {
     // Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk
     // reslicer
     vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
 
     // Set slice as input
     mitk::Image::Pointer slice = dynamic_cast<mitk::Image *>(m_FeedbackNode->GetData());
     reslice->SetInputSlice(slice->GetSliceData()->GetVtkImageAccessor(slice)->GetVtkImageData());
     // set overwrite mode to true to write back to the image volume
     reslice->SetOverwriteMode(true);
     reslice->Modified();
 
     const auto timePoint = m_LastSNC->GetSelectedTimePoint();
     if (!m_Segmentation->GetTimeGeometry()->IsValidTimePoint(timePoint))
     {
       MITK_WARN << "Cannot accept interpolation. Time point selected by SliceNavigationController is not within the time bounds of segmentation. Time point: " << timePoint;
       return;
     }
 
     mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice);
     extractor->SetInput(m_Segmentation);
     const auto timeStep = m_Segmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
     extractor->SetTimeStep(timeStep);
     extractor->SetWorldGeometry(m_LastSNC->GetCurrentPlaneGeometry());
     extractor->SetVtkOutputRequest(true);
     extractor->SetResliceTransformByGeometry(m_Segmentation->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
 
     extractor->Modified();
     extractor->Update();
 
     // the image was modified within the pipeline, but not marked so
     m_Segmentation->Modified();
     m_Segmentation->GetVtkImageData()->Modified();
 
     m_FeedbackNode->SetData(nullptr);
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkSlicesInterpolator::AcceptAllInterpolations(mitk::SliceNavigationController *slicer)
 {
   /*
    * What exactly is done here:
    * 1. We create an empty diff image for the current segmentation
    * 2. All interpolated slices are written into the diff image
    * 3. Then the diffimage is applied to the original segmentation
    */
   if (m_Segmentation)
   {
     mitk::Image::Pointer image3D = m_Segmentation;
     unsigned int timeStep(0);
     const auto timePoint = slicer->GetSelectedTimePoint();
     if (m_Segmentation->GetDimension() == 4)
     {
       if (!m_Segmentation->GetTimeGeometry()->IsValidTimePoint(timePoint))
       {
         MITK_WARN << "Cannot accept all interpolations. Time point selected by passed SliceNavigationController is not within the time bounds of segmentation. Time point: " << timePoint;
         return;
       }
 
       timeStep = m_Segmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
       mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
       timeSelector->SetInput(m_Segmentation);
       timeSelector->SetTimeNr(timeStep);
       timeSelector->Update();
       image3D = timeSelector->GetOutput();
     }
     // create a empty diff image for the undo operation
     mitk::Image::Pointer diffImage = mitk::Image::New();
     diffImage->Initialize(image3D);
 
     // Create scope for ImageWriteAccessor so that the accessor is destroyed
     // after the image is initialized. Otherwise later image access will lead to an error
     {
       mitk::ImageWriteAccessor imAccess(diffImage);
 
       // Set all pixels to zero
       mitk::PixelType pixelType(mitk::MakeScalarPixelType<mitk::Tool::DefaultSegmentationDataType>());
 
       // For legacy purpose support former pixel type of segmentations (before multilabel)
       if (m_Segmentation->GetImageDescriptor()->GetChannelDescriptor().GetPixelType().GetComponentType() ==
           itk::ImageIOBase::UCHAR)
       {
         pixelType = mitk::MakeScalarPixelType<unsigned char>();
       }
 
       memset(imAccess.GetData(),
              0,
              (pixelType.GetBpe() >> 3) * diffImage->GetDimension(0) * diffImage->GetDimension(1) *
                diffImage->GetDimension(2));
     }
 
     // Since we need to shift the plane it must be clone so that the original plane isn't altered
     mitk::PlaneGeometry::Pointer reslicePlane = slicer->GetCurrentPlaneGeometry()->Clone();
 
     int sliceDimension(-1);
     int sliceIndex(-1);
     mitk::SegTool2D::DetermineAffectedImageSlice(m_Segmentation, reslicePlane, sliceDimension, sliceIndex);
 
     unsigned int zslices = m_Segmentation->GetDimension(sliceDimension);
     mitk::ProgressBar::GetInstance()->AddStepsToDo(zslices);
 
     mitk::Point3D origin = reslicePlane->GetOrigin();
     unsigned int totalChangedSlices(0);
 
     for (unsigned int sliceIndex = 0; sliceIndex < zslices; ++sliceIndex)
     {
       // Transforming the current origin of the reslice plane
       // so that it matches the one of the next slice
       m_Segmentation->GetSlicedGeometry()->WorldToIndex(origin, origin);
       origin[sliceDimension] = sliceIndex;
       m_Segmentation->GetSlicedGeometry()->IndexToWorld(origin, origin);
       reslicePlane->SetOrigin(origin);
       // Set the slice as 'input'
       mitk::Image::Pointer interpolation =
         m_Interpolator->Interpolate(sliceDimension, sliceIndex, reslicePlane, timeStep);
 
       if (interpolation.IsNotNull()) // we don't check if interpolation is necessary/sensible - but m_Interpolator does
       {
         // Setting up the reslicing pipeline which allows us to write the interpolation results back into
         // the image volume
         vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
 
         // set overwrite mode to true to write back to the image volume
         reslice->SetInputSlice(interpolation->GetSliceData()->GetVtkImageAccessor(interpolation)->GetVtkImageData());
         reslice->SetOverwriteMode(true);
         reslice->Modified();
 
         mitk::ExtractSliceFilter::Pointer diffslicewriter = mitk::ExtractSliceFilter::New(reslice);
         diffslicewriter->SetInput(diffImage);
         diffslicewriter->SetTimeStep(0);
         diffslicewriter->SetWorldGeometry(reslicePlane);
         diffslicewriter->SetVtkOutputRequest(true);
         diffslicewriter->SetResliceTransformByGeometry(diffImage->GetTimeGeometry()->GetGeometryForTimeStep(0));
 
         diffslicewriter->Modified();
         diffslicewriter->Update();
         ++totalChangedSlices;
       }
       mitk::ProgressBar::GetInstance()->Progress();
     }
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 
     if (totalChangedSlices > 0)
     {
       // store undo stack items
       if (true)
       {
         // create do/undo operations
         mitk::ApplyDiffImageOperation *doOp =
           new mitk::ApplyDiffImageOperation(mitk::OpTEST, m_Segmentation, diffImage, timeStep);
         mitk::ApplyDiffImageOperation *undoOp =
           new mitk::ApplyDiffImageOperation(mitk::OpTEST, m_Segmentation, diffImage, timeStep);
         undoOp->SetFactor(-1.0);
         std::stringstream comment;
         comment << "Confirm all interpolations (" << totalChangedSlices << ")";
         mitk::OperationEvent *undoStackItem =
           new mitk::OperationEvent(mitk::DiffImageApplier::GetInstanceForUndo(), doOp, undoOp, comment.str());
         mitk::OperationEvent::IncCurrGroupEventId();
         mitk::OperationEvent::IncCurrObjectEventId();
         mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent(undoStackItem);
 
         // acutally apply the changes here to the original image
         mitk::DiffImageApplier::GetInstanceForUndo()->ExecuteOperation(doOp);
       }
     }
 
     m_FeedbackNode->SetData(nullptr);
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkSlicesInterpolator::FinishInterpolation(mitk::SliceNavigationController *slicer)
 {
   // this redirect is for calling from outside
 
   if (slicer == nullptr)
     OnAcceptAllInterpolationsClicked();
   else
     AcceptAllInterpolations(slicer);
 }
 
 void QmitkSlicesInterpolator::OnAcceptAllInterpolationsClicked()
 {
   QMenu orientationPopup(this);
   std::map<QAction *, mitk::SliceNavigationController *>::const_iterator it;
   for (it = ACTION_TO_SLICEDIMENSION.begin(); it != ACTION_TO_SLICEDIMENSION.end(); it++)
     orientationPopup.addAction(it->first);
 
   connect(&orientationPopup, SIGNAL(triggered(QAction *)), this, SLOT(OnAcceptAllPopupActivated(QAction *)));
 
   orientationPopup.exec(QCursor::pos());
 }
 
 void QmitkSlicesInterpolator::OnAccept3DInterpolationClicked()
 {
   auto referenceImage = GetData<mitk::Image>(m_ToolManager->GetReferenceData(0));
 
   auto* segmentationDataNode = m_ToolManager->GetWorkingData(0);
   auto segmentation = GetData<mitk::Image>(segmentationDataNode);
 
   if (referenceImage.IsNull() || segmentation.IsNull())
     return;
 
   const auto* segmentationGeometry = segmentation->GetTimeGeometry();
   const auto timePoint = m_LastSNC->GetSelectedTimePoint();
 
   if (!referenceImage->GetTimeGeometry()->IsValidTimePoint(timePoint) ||
       !segmentationGeometry->IsValidTimePoint(timePoint))
   {
     MITK_WARN << "Cannot accept interpolation. Current time point is not within the time bounds of the patient image and segmentation.";
     return;
   }
 
   auto interpolatedSurface = GetData<mitk::Surface>(m_InterpolatedSurfaceNode);
 
   if (interpolatedSurface.IsNull())
     return;
 
   auto surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
 
   surfaceToImageFilter->SetImage(referenceImage);
   surfaceToImageFilter->SetMakeOutputBinary(true);
   surfaceToImageFilter->SetUShortBinaryPixelType(itk::ImageIOBase::USHORT == segmentation->GetPixelType().GetComponentType());
   surfaceToImageFilter->SetInput(interpolatedSurface);
   surfaceToImageFilter->Update();
 
   mitk::Image::Pointer interpolatedSegmentation = surfaceToImageFilter->GetOutput();
 
   auto timeStep = interpolatedSegmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
   mitk::ImageReadAccessor readAccessor(interpolatedSegmentation, interpolatedSegmentation->GetVolumeData(timeStep));
   const auto* dataPointer = readAccessor.GetData();
 
   if (nullptr == dataPointer)
     return;
 
   timeStep = segmentationGeometry->TimePointToTimeStep(timePoint);
   segmentation->SetVolume(dataPointer, timeStep, 0);
 
   m_CmbInterpolation->setCurrentIndex(0);
   this->Show3DInterpolationResult(false);
 
   std::string name = segmentationDataNode->GetName() + "_3D-interpolation";
   mitk::TimeBounds timeBounds;
 
   if (1 < interpolatedSurface->GetTimeSteps())
   {
     name += "_t" + std::to_string(timeStep);
 
     auto* polyData = vtkPolyData::New();
     polyData->DeepCopy(interpolatedSurface->GetVtkPolyData(timeStep));
 
     auto surface = mitk::Surface::New();
     surface->SetVtkPolyData(polyData);
 
     interpolatedSurface = surface;
     timeBounds = segmentationGeometry->GetTimeBounds(timeStep);
   }
   else
   {
     timeBounds = segmentationGeometry->GetTimeBounds(0);
   }
 
   auto* surfaceGeometry = static_cast<mitk::ProportionalTimeGeometry*>(interpolatedSurface->GetTimeGeometry());
   surfaceGeometry->SetFirstTimePoint(timeBounds[0]);
   surfaceGeometry->SetStepDuration(timeBounds[1] - timeBounds[0]);
 
   // Typical file formats for surfaces do not save any time-related information. As a workaround at least for MITK scene files, we have the
   // possibility to seralize this information as properties.
 
   interpolatedSurface->SetProperty("ProportionalTimeGeometry.FirstTimePoint", mitk::FloatProperty::New(surfaceGeometry->GetFirstTimePoint()));
   interpolatedSurface->SetProperty("ProportionalTimeGeometry.StepDuration", mitk::FloatProperty::New(surfaceGeometry->GetStepDuration()));
 
   auto interpolatedSurfaceDataNode = mitk::DataNode::New();
 
   interpolatedSurfaceDataNode->SetData(interpolatedSurface);
   interpolatedSurfaceDataNode->SetName(name);
   interpolatedSurfaceDataNode->SetOpacity(0.7f);
 
   std::array<float, 3> rgb;
   segmentationDataNode->GetColor(rgb.data());
   interpolatedSurfaceDataNode->SetColor(rgb.data());
 
   m_DataStorage->Add(interpolatedSurfaceDataNode, segmentationDataNode);
 }
 
 void ::QmitkSlicesInterpolator::OnSuggestPlaneClicked()
 {
   if (m_PlaneWatcher.isRunning())
     m_PlaneWatcher.waitForFinished();
   m_PlaneFuture = QtConcurrent::run(this, &QmitkSlicesInterpolator::RunPlaneSuggestion);
   m_PlaneWatcher.setFuture(m_PlaneFuture);
 }
 
 void ::QmitkSlicesInterpolator::RunPlaneSuggestion()
 {
   if (m_FirstRun)
     mitk::ProgressBar::GetInstance()->AddStepsToDo(7);
   else
     mitk::ProgressBar::GetInstance()->AddStepsToDo(3);
 
   m_EdgeDetector->SetSegmentationMask(m_Segmentation);
   m_EdgeDetector->SetInput(dynamic_cast<mitk::Image *>(m_ToolManager->GetReferenceData(0)->GetData()));
   m_EdgeDetector->Update();
 
   mitk::UnstructuredGrid::Pointer uGrid = mitk::UnstructuredGrid::New();
   uGrid->SetVtkUnstructuredGrid(m_EdgeDetector->GetOutput()->GetVtkUnstructuredGrid());
 
   mitk::ProgressBar::GetInstance()->Progress();
 
   mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface *>(m_InterpolatedSurfaceNode->GetData());
 
   vtkSmartPointer<vtkPolyData> vtkpoly = surface->GetVtkPolyData();
   vtkSmartPointer<vtkPoints> vtkpoints = vtkpoly->GetPoints();
 
   vtkSmartPointer<vtkUnstructuredGrid> vGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
   vtkSmartPointer<vtkPolyVertex> verts = vtkSmartPointer<vtkPolyVertex>::New();
 
   verts->GetPointIds()->SetNumberOfIds(vtkpoints->GetNumberOfPoints());
   for (int i = 0; i < vtkpoints->GetNumberOfPoints(); i++)
   {
     verts->GetPointIds()->SetId(i, i);
   }
 
   vGrid->Allocate(1);
   vGrid->InsertNextCell(verts->GetCellType(), verts->GetPointIds());
   vGrid->SetPoints(vtkpoints);
 
   mitk::UnstructuredGrid::Pointer interpolationGrid = mitk::UnstructuredGrid::New();
   interpolationGrid->SetVtkUnstructuredGrid(vGrid);
 
   m_PointScorer->SetInput(0, uGrid);
   m_PointScorer->SetInput(1, interpolationGrid);
   m_PointScorer->Update();
 
   mitk::UnstructuredGrid::Pointer scoredGrid = mitk::UnstructuredGrid::New();
   scoredGrid = m_PointScorer->GetOutput();
 
   mitk::ProgressBar::GetInstance()->Progress();
 
   double spacing = mitk::SurfaceInterpolationController::GetInstance()->GetDistanceImageSpacing();
   mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New();
   clusterFilter->SetInput(scoredGrid);
   clusterFilter->SetMeshing(false);
   clusterFilter->SetMinPts(4);
   clusterFilter->Seteps(spacing);
   clusterFilter->Update();
 
   mitk::ProgressBar::GetInstance()->Progress();
 
   // Create plane suggestion
   mitk::BaseRenderer::Pointer br =
     mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget0"));
   mitk::PlaneProposer planeProposer;
   std::vector<mitk::UnstructuredGrid::Pointer> grids = clusterFilter->GetAllClusters();
 
   planeProposer.SetUnstructuredGrids(grids);
   mitk::SliceNavigationController::Pointer snc = br->GetSliceNavigationController();
   planeProposer.SetSliceNavigationController(snc);
   planeProposer.SetUseDistances(true);
   try
   {
     planeProposer.CreatePlaneInfo();
   }
   catch (const mitk::Exception &e)
   {
     MITK_ERROR << e.what();
   }
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 
   m_FirstRun = false;
 }
 
 void QmitkSlicesInterpolator::OnReinit3DInterpolation()
 {
   mitk::NodePredicateProperty::Pointer pred =
     mitk::NodePredicateProperty::New("3DContourContainer", mitk::BoolProperty::New(true));
   mitk::DataStorage::SetOfObjects::ConstPointer contourNodes =
     m_DataStorage->GetDerivations(m_ToolManager->GetWorkingData(0), pred);
 
   if (contourNodes->Size() != 0)
   {
     m_BtnApply3D->setEnabled(true);
     m_3DContourNode = contourNodes->at(0);
     mitk::Surface::Pointer contours = dynamic_cast<mitk::Surface *>(m_3DContourNode->GetData());
     if (contours)
       mitk::SurfaceInterpolationController::GetInstance()->ReinitializeInterpolation(contours);
     m_BtnReinit3DInterpolation->setEnabled(false);
   }
   else
   {
     m_BtnApply3D->setEnabled(false);
     QMessageBox errorInfo;
     errorInfo.setWindowTitle("Reinitialize surface interpolation");
     errorInfo.setIcon(QMessageBox::Information);
     errorInfo.setText("No contours available for the selected segmentation!");
     errorInfo.exec();
   }
 }
 
 void QmitkSlicesInterpolator::OnAcceptAllPopupActivated(QAction *action)
 {
   try
   {
     std::map<QAction *, mitk::SliceNavigationController *>::const_iterator iter = ACTION_TO_SLICEDIMENSION.find(action);
     if (iter != ACTION_TO_SLICEDIMENSION.end())
     {
       mitk::SliceNavigationController *slicer = iter->second;
       AcceptAllInterpolations(slicer);
     }
   }
   catch (...)
   {
     /* Showing message box with possible memory error */
     QMessageBox errorInfo;
     errorInfo.setWindowTitle("Interpolation Process");
     errorInfo.setIcon(QMessageBox::Critical);
     errorInfo.setText("An error occurred during interpolation. Possible cause: Not enough memory!");
     errorInfo.exec();
 
     // additional error message on std::cerr
     std::cerr << "Ill construction in " __FILE__ " l. " << __LINE__ << std::endl;
   }
 }
 
 void QmitkSlicesInterpolator::OnInterpolationActivated(bool on)
 {
   m_2DInterpolationEnabled = on;
 
   try
   {
     if (m_DataStorage.IsNotNull())
     {
       if (on && !m_DataStorage->Exists(m_FeedbackNode))
       {
         m_DataStorage->Add(m_FeedbackNode);
       }
     }
   }
   catch (...)
   {
     // don't care (double add/remove)
   }
 
   if (m_ToolManager)
   {
     mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
     mitk::DataNode *referenceNode = m_ToolManager->GetReferenceData(0);
     QWidget::setEnabled(workingNode != nullptr);
 
     m_BtnApply2D->setEnabled(on);
     m_FeedbackNode->SetVisibility(on);
 
     if (!on)
     {
       mitk::RenderingManager::GetInstance()->RequestUpdateAll();
       return;
     }
 
     if (workingNode)
     {
       mitk::Image *segmentation = dynamic_cast<mitk::Image *>(workingNode->GetData());
       if (segmentation)
       {
         m_Interpolator->SetSegmentationVolume(segmentation);
 
         if (referenceNode)
         {
           mitk::Image *referenceImage = dynamic_cast<mitk::Image *>(referenceNode->GetData());
           m_Interpolator->SetReferenceVolume(referenceImage); // may be nullptr
         }
       }
     }
   }
 
   UpdateVisibleSuggestion();
 }
 
 void QmitkSlicesInterpolator::Run3DInterpolation()
 {
   m_SurfaceInterpolator->Interpolate();
 }
 
 void QmitkSlicesInterpolator::StartUpdateInterpolationTimer()
 {
   m_Timer->start(500);
 }
 
 void QmitkSlicesInterpolator::StopUpdateInterpolationTimer()
 {
   m_Timer->stop();
   m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
   mitk::RenderingManager::GetInstance()->RequestUpdate(
     mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3"))->GetRenderWindow());
 }
 
 void QmitkSlicesInterpolator::ChangeSurfaceColor()
 {
   float currentColor[3];
   m_InterpolatedSurfaceNode->GetColor(currentColor);
 
   if (currentColor[2] == SURFACE_COLOR_RGB[2])
   {
     m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 1.0f));
   }
   else
   {
     m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
   }
   m_InterpolatedSurfaceNode->Update();
   mitk::RenderingManager::GetInstance()->RequestUpdate(
     mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3"))->GetRenderWindow());
 }
 
 void QmitkSlicesInterpolator::On3DInterpolationActivated(bool on)
 {
   m_3DInterpolationEnabled = on;
 
   this->CheckSupportedImageDimension();
   try
   {
     if (m_DataStorage.IsNotNull() && m_ToolManager && m_3DInterpolationEnabled)
     {
       mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
 
       if (workingNode)
       {
         if ((workingNode->IsVisible(mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2")))))
         {
           int ret = QMessageBox::Yes;
 
           if (m_SurfaceInterpolator->EstimatePortionOfNeededMemory() > 0.5)
           {
             QMessageBox msgBox;
             msgBox.setText("Due to short handed system memory the 3D interpolation may be very slow!");
             msgBox.setInformativeText("Are you sure you want to activate the 3D interpolation?");
             msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
             ret = msgBox.exec();
           }
 
           if (m_Watcher.isRunning())
             m_Watcher.waitForFinished();
 
           if (ret == QMessageBox::Yes)
           {
             m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
             m_Watcher.setFuture(m_Future);
           }
           else
           {
             m_CmbInterpolation->setCurrentIndex(0);
           }
         }
       }
       else
       {
         QWidget::setEnabled(false);
         m_ChkShowPositionNodes->setEnabled(m_3DInterpolationEnabled);
       }
     }
     if (!m_3DInterpolationEnabled)
     {
       this->Show3DInterpolationResult(false);
       m_BtnApply3D->setEnabled(m_3DInterpolationEnabled);
 
       // T28261
       // m_BtnSuggestPlane->setEnabled(m_3DInterpolationEnabled);
     }
   }
   catch (...)
   {
     MITK_ERROR << "Error with 3D surface interpolation!";
   }
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::EnableInterpolation(bool on)
 {
   // only to be called from the outside world
   // just a redirection to OnInterpolationActivated
   OnInterpolationActivated(on);
 }
 
 void QmitkSlicesInterpolator::Enable3DInterpolation(bool on)
 {
   // only to be called from the outside world
   // just a redirection to OnInterpolationActivated
   On3DInterpolationActivated(on);
 }
 
 void QmitkSlicesInterpolator::UpdateVisibleSuggestion()
 {
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::OnInterpolationInfoChanged(const itk::EventObject & /*e*/)
 {
   // something (e.g. undo) changed the interpolation info, we should refresh our display
   UpdateVisibleSuggestion();
 }
 
 void QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged(const itk::EventObject & /*e*/)
 {
   if (m_3DInterpolationEnabled)
   {
     if (m_Watcher.isRunning())
       m_Watcher.waitForFinished();
     m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
     m_Watcher.setFuture(m_Future);
   }
 }
 
 void QmitkSlicesInterpolator::SetCurrentContourListID()
 {
   // New ContourList = hide current interpolation
   Show3DInterpolationResult(false);
 
   if (m_DataStorage.IsNotNull() && m_ToolManager && m_LastSNC)
   {
     mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
 
     if (workingNode)
     {
       QWidget::setEnabled(true);
 
       const auto timePoint = m_LastSNC->GetSelectedTimePoint();
       // In case the time is not valid use 0 to access the time geometry of the working node
       unsigned int time_position = 0;
       if (!workingNode->GetData()->GetTimeGeometry()->IsValidTimePoint(timePoint))
       {
         MITK_WARN << "Cannot accept interpolation. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << timePoint;
         return;
       }
       time_position = workingNode->GetData()->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
       mitk::Vector3D spacing = workingNode->GetData()->GetGeometry(time_position)->GetSpacing();
       double minSpacing(100);
       double maxSpacing(0);
       for (int i = 0; i < 3; i++)
       {
         if (spacing[i] < minSpacing)
         {
           minSpacing = spacing[i];
         }
         if (spacing[i] > maxSpacing)
         {
           maxSpacing = spacing[i];
         }
       }
 
       m_SurfaceInterpolator->SetMaxSpacing(maxSpacing);
       m_SurfaceInterpolator->SetMinSpacing(minSpacing);
       m_SurfaceInterpolator->SetDistanceImageVolume(50000);
 
       mitk::Image *segmentationImage = dynamic_cast<mitk::Image *>(workingNode->GetData());
 
       m_SurfaceInterpolator->SetCurrentInterpolationSession(segmentationImage);
       m_SurfaceInterpolator->SetCurrentTimePoint(timePoint);
 
       if (m_3DInterpolationEnabled)
       {
         if (m_Watcher.isRunning())
           m_Watcher.waitForFinished();
         m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
         m_Watcher.setFuture(m_Future);
       }
     }
     else
     {
       QWidget::setEnabled(false);
     }
   }
 }
 
 void QmitkSlicesInterpolator::Show3DInterpolationResult(bool status)
 {
   if (m_InterpolatedSurfaceNode.IsNotNull())
     m_InterpolatedSurfaceNode->SetVisibility(status);
 
   if (m_3DContourNode.IsNotNull())
     m_3DContourNode->SetVisibility(
       status, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")));
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::CheckSupportedImageDimension()
 {
   if (m_ToolManager->GetWorkingData(0))
     m_Segmentation = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());
 
   /*if (m_3DInterpolationEnabled && m_Segmentation && m_Segmentation->GetDimension() != 3)
   {
     QMessageBox info;
     info.setWindowTitle("3D Interpolation Process");
     info.setIcon(QMessageBox::Information);
     info.setText("3D Interpolation is only supported for 3D images at the moment!");
     info.exec();
     m_CmbInterpolation->setCurrentIndex(0);
   }*/
 }
 
 void QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted(const itk::Object *sender,
                                                                  const itk::EventObject & /*e*/)
 {
   // Don't know how to avoid const_cast here?!
   mitk::SliceNavigationController *slicer =
     dynamic_cast<mitk::SliceNavigationController *>(const_cast<itk::Object *>(sender));
   if (slicer)
   {
     m_ControllerToTimeObserverTag.remove(slicer);
     m_ControllerToSliceObserverTag.remove(slicer);
     m_ControllerToDeleteObserverTag.remove(slicer);
   }
 }
 
 void QmitkSlicesInterpolator::WaitForFutures()
 {
   if (m_Watcher.isRunning())
   {
     m_Watcher.waitForFinished();
   }
 
   if (m_PlaneWatcher.isRunning())
   {
     m_PlaneWatcher.waitForFinished();
   }
 }
 
 void QmitkSlicesInterpolator::NodeRemoved(const mitk::DataNode* node)
 {
   if ((m_ToolManager && m_ToolManager->GetWorkingData(0) == node) ||
       node == m_3DContourNode ||
       node == m_FeedbackNode ||
       node == m_InterpolatedSurfaceNode)
   {
     WaitForFutures();
   }
 }