diff --git a/Documentation/Doxygen/2-UserManual/MITKPluginGeneralManualsList.dox b/Documentation/Doxygen/2-UserManual/MITKPluginGeneralManualsList.dox
index 78f1b417e2..e72483a5cd 100644
--- a/Documentation/Doxygen/2-UserManual/MITKPluginGeneralManualsList.dox
+++ b/Documentation/Doxygen/2-UserManual/MITKPluginGeneralManualsList.dox
@@ -1,32 +1,32 @@
 /**
 \page PluginListGeneralPage  List of General Purpose Plugins
 
 
   \li \subpage org_mitk_views_basicimageprocessing
   \li \subpage org_mitk_views_datamanager
   \li \subpage org_mitk_views_properties
   \li \subpage org_mitk_editors_dicombrowser
   \li \subpage org_mitk_gui_qt_dicominspector
   \li \subpage org_mitk_views_imagecropper
   \li \subpage org_mitk_views_imagenavigator
-  \li \subpage org_blueberry_ui_qt_log
+  \li \subpage org_blueberry_views_logview
   \li \subpage org_mitk_gui_qt_matchpoint_algorithm_batch
   \li \subpage org_mitk_views_qt_matchpoint_algorithm_browser
   \li \subpage org_mitk_views_qt_matchpoint_algorithm_control
   \li \subpage org_mitk_views_matchpoint_evaluator
   \li \subpage org_mitk_views_qt_matchpoint_framereg
   \li \subpage org_mitk_views_qt_matchpoint_manipulator
   \li \subpage org_mitk_views_matchpoint_mapper
   \li \subpage org_mitk_views_qt_matchpoint_visualizer
   \li \subpage org_mitk_gui_qt_measurementtoolbox
   \li \subpage org_mitk_views_moviemaker
   \li \subpage org_mitk_views_multilabelsegmentation
   \li \subpage org_mitk_views_pointsetinteraction
   \li \subpage org_mitk_gui_qt_python
   \li \subpage org_mitk_gui_qt_remeshing
   \li \subpage org_mitk_views_screenshotmaker
   \li \subpage org_mitk_views_segmentation
   \li \subpage org_mitk_gui_qt_flow_segmentation
   \li \subpage org_mitk_gui_qt_viewnavigator
   \li \subpage org_mitk_views_volumevisualization
 */
diff --git a/Documentation/Doxygen/2-UserManual/MITKPluginManualsList.dox b/Documentation/Doxygen/2-UserManual/MITKPluginManualsList.dox
index 2bf2a11b12..2bb8e351e4 100644
--- a/Documentation/Doxygen/2-UserManual/MITKPluginManualsList.dox
+++ b/Documentation/Doxygen/2-UserManual/MITKPluginManualsList.dox
@@ -1,84 +1,84 @@
 /**
 \page PluginListPage MITK Plugin Manuals
 
 The plugins and bundles provide much of the extended functionality of MITK. Each encapsulates a solution to a problem and associated features. This way one can easily assemble the necessary capabilites for a workflow without adding a lot of bloat, by combining plugins as needed.
 
 
 \subpage PluginListGeneralPage
 
 <ul>
   <li> \ref  org_mitk_views_basicimageprocessing </li>
   <li> \ref  org_mitk_views_datamanager </li>
   <li> \ref  org_mitk_editors_dicombrowser </li>
   <li> \ref  org_mitk_gui_qt_dicominspector </li>
   <li> \ref  org_mitk_gui_qt_flowapplication </li>
   <li> \ref  org_mitk_views_imagecropper </li>
   <li> \ref  org_mitk_views_imagenavigator </li>
-  <li> \ref  org_blueberry_ui_qt_log </li>
+  <li> \ref  org_blueberry_views_logview </li>
   <li> \ref  org_mitk_views_matchpoint_algorithm_browser</li>
   <li> \ref  org_mitk_views_matchpoint_algorithm_control</li>
   <li> \ref  org_mitk_views_matchpoint_evaluator</li>
   <li> \ref  org_mitk_views_matchpoint_framereg</li>
   <li> \ref  org_mitk_views_matchpoint_manipulator</li>
   <li> \ref  org_mitk_views_matchpoint_mapper</li>
   <li> \ref  org_mitk_views_matchpoint_visualizer</li>
   <li> \ref  org_mitk_gui_qt_measurementtoolbox </li>
   <li> \ref  org_mitk_views_moviemaker </li>
   <li> \ref  org_mitk_views_multilabelsegmentation </li>
   <li> \ref  org_mitk_views_pointsetinteraction </li>
   <li> \ref  org_mitk_gui_qt_python </li>
   <li> \ref  org_mitk_gui_qt_remeshing </li>
   <li> \ref  org_mitk_views_screenshotmaker </li>
   <li> \ref  org_mitk_views_segmentation </li>
   <li> \ref  org_mitk_gui_qt_flow_segmentation </li>
   <li> \ref  org_mitk_gui_qt_viewnavigator </li>
   <li> \ref  org_mitk_views_volumevisualization</li>
 
 </ul>
 
 \subpage PluginListSpecificPage
 
 <ul>
   <li> \ref  org_mitk_views_properties </li>
   <li> \ref  org_mitk_gui_qt_aicpregistration </li>
   <li> \ref  org_mitk_gui_qt_cest </li>
   <li> \ref  org_mitk_gui_qt_classificationsegmentation </li>
   <li> \ref  org_mitk_views_cmdlinemodules </li>
   <li> \ref  org_mitk_gui_qt_pharmacokinetics_concentration_mri</li>
   <li> \ref  org_mitk_views_pharmacokinetics_mri</li>
   <li> \ref  org_mitk_gui_qt_pharmacokinetics_pet</li>
   <li> \ref  org_mitk_gui_qt_eventrecorder </li>
   <li> \ref  org_mitk_gui_qt_examples </li>
   <li> \ref  org_mitk_gui_qt_geometrytools </li>
   <li> \ref  org_mitk_gui_qt_igtexample </li>
   <li> \ref  org_mitk_gui_qt_igtlplugin</li>
   <li> \ref  org_mitk_gui_qt_igttracking</li>
   <li> \ref  org_mitk_gui_qt_igttrackingsemiautomaticmeasurement</li>
   <li> \ref  org_mitk_views_imagestatistics</li>
   <li> \ref  org_mitk_gui_qt_lasercontrol</li>
   <li> \ref  org_mitk_gui_qt_fit_demo </li>
   <li> \ref  org_mitk_gui_qt_fit_genericfitting </li>
   <li> \ref  org_mitk_gui_qt_fit_inspector </li>
   <li> \ref  org_mitkexamplesopencv</li>
   <li> \ref  org_mitk_gui_qt_overlaymanager</li>
   <li> \ref  org_mitk_gui_qt_mitkphenotyping</li>
   <li> \ref  org_mitk_gui_qt_photoacoustics_pausmotioncompensation</li>
   <li> \ref  org_mitk_example_gui_pcaexample</li>
   <li>  \ref org_mitk_gui_qt_preprocessing_resampling</li>
   <li> \ref  org_mitk_gui_qt_pharmacokinetics_curvedescriptor</li>
   <li> \ref  org_mitk_gui_qt_photoacoustics_imageprocessing</li>
   <li> \ref  org_mitk_gui_qt_pharmacokinetics_simulation</li>
   <li> \ref  org_mitk_gui_qt_pointsetinteractionmultispectrum</li>
   <li> \ref  org_mitk_gui_qt_renderwindowmanager</li>
   <li> \ref  org_mitk_gui_qt_photoacoustics_spectralunmixing</li>
   <li> \ref  org_mitk_gui_qt_spectrocamrecorder</li>
   <li> \ref  org_surfacematerialeditor</li>
   <li> \ref  org_toftutorial</li>
   <li> \ref  org_blueberry_ui_qt_objectinspector</li>
   <li> \ref  org_mitk_gui_qt_ultrasound</li>
   <li> \ref  org_mitk_gui_qt_igt_app_echotrack </li>
   <li> \ref  org_mitk_gui_qt_xnat</li>
 </ul>
 
 
 */
diff --git a/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.cpp b/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.cpp
new file mode 100644
index 0000000000..5451a67f34
--- /dev/null
+++ b/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.cpp
@@ -0,0 +1,204 @@
+/*============================================================================
+
+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>
+
+// 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);
+
+  m_ToolManager->GetDataStorage()->Add(m_MLPreviewNode);
+}
+
+void mitk::AutoMLSegmentationWithPreviewTool::Deactivated()
+{
+  m_ToolManager->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, 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());
+      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/mitkAutoMLSegmentationWithPreviewTool.h b/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.h
new file mode 100644
index 0000000000..94163df1ad
--- /dev/null
+++ b/Modules/Segmentation/Interactions/mitkAutoMLSegmentationWithPreviewTool.h
@@ -0,0 +1,82 @@
+/*============================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center (DKFZ)
+All rights reserved.
+
+Use of this source code is governed by a 3-clause BSD license that can be
+found in the LICENSE file.
+
+============================================================================*/
+#ifndef MITK_AUTO_ML_SEGMENTATION_WITH_PREVIEW_TOOL_H
+#define MITK_AUTO_ML_SEGMENTATION_WITH_PREVIEW_TOOL_H
+
+#include "mitkAutoSegmentationWithPreviewTool.h"
+#include "mitkDataNode.h"
+#include "mitkLabelSetImage.h"
+
+#include <MitkSegmentationExports.h>
+
+namespace mitk
+{
+  /**
+  \brief Base class for any auto segmentation tool that provides a preview of the new segmentation and generates
+  segmentations with multiple labels.
+
+  This tool class implements the basic logic to handle previews of multi label segmentations and
+  to allow to pick arbitrary labels as selected and merge them to a single segmentation to store this
+  segmentation as confirmed segmentation.
+
+  \ingroup ToolManagerEtAl
+  \sa mitk::Tool
+  \sa QmitkInteractiveSegmentation
+  */
+  class MITKSEGMENTATION_EXPORT AutoMLSegmentationWithPreviewTool : public AutoSegmentationWithPreviewTool
+  {
+  public:
+    mitkClassMacro(AutoMLSegmentationWithPreviewTool, AutoSegmentationWithPreviewTool);
+
+    void Activated() override;
+    void Deactivated() override;
+
+    using SelectedLabelVectorType = std::vector<Label::PixelType>;
+    void SetSelectedLabels(const SelectedLabelVectorType& regions);
+    SelectedLabelVectorType GetSelectedLabels() const;
+
+    const LabelSetImage* GetMLPreview() const;
+
+  protected:
+    AutoMLSegmentationWithPreviewTool();
+    ~AutoMLSegmentationWithPreviewTool() = default;
+
+    void UpdateCleanUp() override;
+    void DoUpdatePreview(const Image* inputAtTimeStep, Image* previewImage, TimeStepType timeStep) override;
+
+    /** Function to generate the new multi lable preview for a given time step input image.
+     * The function must be implemented by derived tools.
+     * This function is called by DoUpdatePreview if needed.
+     * Reasons are:
+     * - ML preview does not exist
+     * - Modify time of tools is newer then of ML preview
+     * - ML preview was not generated for the current selected timestep of input image or for the current selected timepoint.*/
+    virtual LabelSetImage::Pointer ComputeMLPreview(const Image* inputAtTimeStep, TimeStepType timeStep) = 0;
+
+  private:
+    /** Function to generate a simple (single lable) preview by merging all labels of the ML preview that are selected and
+     * copies that single label preview to the passed previewImage.
+     * This function is called by DoUpdatePreview if needed.
+     * @param mlPreviewImage Multi label preview that is the source.
+     * @param previewImage Pointer to the single label preview image that should receive the merged selected labels.
+     * @timeStep Time step of the previewImage that should be filled.*/
+    template <typename TPixel, unsigned int VImageDimension>
+    void CalculateMergedSimplePreview(const itk::Image<TPixel, VImageDimension>* mlImage, mitk::Image* segmentation, unsigned int timeStep);
+
+    SelectedLabelVectorType m_SelectedLabels = {};
+
+    // holds the multilabel result as a preview image
+    mitk::DataNode::Pointer m_MLPreviewNode;
+    TimeStepType m_LastMLTimeStep = 0;
+  };
+}
+#endif
diff --git a/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp b/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp
index 8e9b4291f7..e8554c2228 100644
--- a/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkAutoSegmentationWithPreviewTool.cpp
@@ -1,474 +1,478 @@
 /*============================================================================
 
 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 "mitkAutoSegmentationWithPreviewTool.h"
 
 #include "mitkToolManager.h"
 
 #include "mitkColorProperty.h"
 #include "mitkLevelWindowProperty.h"
 #include "mitkProperties.h"
 
 #include "mitkDataStorage.h"
 #include "mitkRenderingManager.h"
 #include <mitkSliceNavigationController.h>
 
 #include "mitkImageAccessByItk.h"
 #include "mitkImageCast.h"
 #include "mitkImageStatisticsHolder.h"
 #include "mitkImageTimeSelector.h"
 #include "mitkLabelSetImage.h"
 #include "mitkMaskAndCutRoiImageFilter.h"
 #include "mitkPadImageFilter.h"
 #include "mitkNodePredicateGeometry.h"
 
 mitk::AutoSegmentationWithPreviewTool::AutoSegmentationWithPreviewTool(bool lazyDynamicPreviews): m_LazyDynamicPreviews(lazyDynamicPreviews)
 {
   m_ProgressCommand = mitk::ToolCommand::New();
 }
 
 mitk::AutoSegmentationWithPreviewTool::~AutoSegmentationWithPreviewTool()
 {
 }
 
 bool mitk::AutoSegmentationWithPreviewTool::CanHandle(const BaseData* referenceData, const BaseData* workingData) const
 {
   if (!Superclass::CanHandle(referenceData, workingData))
     return false;
 
   if (workingData == nullptr)
     return true;
 
   auto* labelSet = dynamic_cast<const LabelSetImage*>(workingData);
 
   if (labelSet != nullptr)
     return true;
 
   auto* image = dynamic_cast<const Image*>(workingData);
 
   if (image == nullptr)
     return false;
 
   //if it is a normal image and not a label set image is used as working data
   //it must have the same pixel type as a label set.
   return MakeScalarPixelType< DefaultSegmentationDataType >() == image->GetPixelType();
 }
 
 void mitk::AutoSegmentationWithPreviewTool::Activated()
 {
   Superclass::Activated();
 
   m_ToolManager->RoiDataChanged +=
     mitk::MessageDelegate<mitk::AutoSegmentationWithPreviewTool>(this, &mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged);
 
   m_ToolManager->SelectedTimePointChanged +=
     mitk::MessageDelegate<mitk::AutoSegmentationWithPreviewTool>(this, &mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged);
 
   m_ReferenceDataNode = m_ToolManager->GetReferenceData(0);
   m_SegmentationInputNode = m_ReferenceDataNode;
 
   m_LastTimePointOfUpdate = 0;
 
   if (m_PreviewSegmentationNode.IsNull())
   {
     m_PreviewSegmentationNode = DataNode::New();
     m_PreviewSegmentationNode->SetProperty("color", ColorProperty::New(0.0, 1.0, 0.0));
     m_PreviewSegmentationNode->SetProperty("name", StringProperty::New(std::string(this->GetName())+" preview"));
     m_PreviewSegmentationNode->SetProperty("opacity", FloatProperty::New(0.3));
     m_PreviewSegmentationNode->SetProperty("binary", BoolProperty::New(true));
     m_PreviewSegmentationNode->SetProperty("helper object", BoolProperty::New(true));
   }
 
   if (m_SegmentationInputNode.IsNotNull())
   {
     this->ResetPreviewNode();
     this->InitiateToolByInput();
   }
   else
   {
     m_ToolManager->ActivateTool(-1);
   }
 }
 
 void mitk::AutoSegmentationWithPreviewTool::Deactivated()
 {
   m_ToolManager->RoiDataChanged -=
     mitk::MessageDelegate<mitk::AutoSegmentationWithPreviewTool>(this, &mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged);
 
   m_ToolManager->SelectedTimePointChanged -=
     mitk::MessageDelegate<mitk::AutoSegmentationWithPreviewTool>(this, &mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged);
 
   m_SegmentationInputNode = nullptr;
   m_ReferenceDataNode = nullptr;
 
   try
   {
     if (DataStorage *storage = m_ToolManager->GetDataStorage())
     {
       storage->Remove(m_PreviewSegmentationNode);
       RenderingManager::GetInstance()->RequestUpdateAll();
     }
   }
   catch (...)
   {
     // don't care
   }
 
-  m_PreviewSegmentationNode->SetData(nullptr);
+  if (m_PreviewSegmentationNode.IsNotNull())
+  {
+    m_PreviewSegmentationNode->SetData(nullptr);
+  }
 
   Superclass::Deactivated();
 }
 
 void mitk::AutoSegmentationWithPreviewTool::ConfirmSegmentation()
 {
   if (m_LazyDynamicPreviews && m_CreateAllTimeSteps)
   { // The tool should create all time steps but is currently in lazy mode,
     // thus ensure that a preview for all time steps is available.
     this->UpdatePreview(true);
   }
 
   CreateResultSegmentationFromPreview();
 
   RenderingManager::GetInstance()->RequestUpdateAll();
 
   if (!m_KeepActiveAfterAccept)
   {
     m_ToolManager->ActivateTool(-1);
   }
 }
 
 void  mitk::AutoSegmentationWithPreviewTool::InitiateToolByInput()
 {
   //default implementation does nothing.
   //implement in derived classes to change behavior
 }
 
 mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetPreviewSegmentation()
 {
   if (m_PreviewSegmentationNode.IsNull())
   {
     return nullptr;
   }
 
   return dynamic_cast<Image*>(m_PreviewSegmentationNode->GetData());
 }
 
 mitk::DataNode* mitk::AutoSegmentationWithPreviewTool::GetPreviewSegmentationNode()
 {
   return m_PreviewSegmentationNode;
 }
 
 const mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetSegmentationInput() const
 {
   if (m_SegmentationInputNode.IsNull())
   {
     return nullptr;
   }
 
   return dynamic_cast<const Image*>(m_SegmentationInputNode->GetData());
 }
 
 const mitk::Image* mitk::AutoSegmentationWithPreviewTool::GetReferenceData() const
 {
   if (m_ReferenceDataNode.IsNull())
   {
     return nullptr;
   }
 
   return dynamic_cast<const Image*>(m_ReferenceDataNode->GetData());
 }
 
 void mitk::AutoSegmentationWithPreviewTool::ResetPreviewNode()
 {
   itk::RGBPixel<float> previewColor;
   previewColor[0] = 0.0f;
   previewColor[1] = 1.0f;
   previewColor[2] = 0.0f;
 
   const auto image = this->GetSegmentationInput();
   if (nullptr != image)
   {
     mitk::LabelSetImage::ConstPointer workingImage =
       dynamic_cast<const mitk::LabelSetImage *>(m_ToolManager->GetWorkingData(0)->GetData());
 
     if (workingImage.IsNotNull())
     {
       auto newPreviewImage = workingImage->Clone();
       if (newPreviewImage.IsNull())
       {
         MITK_ERROR << "Cannot create preview helper objects. Unable to clone working image";
         return;
       }
 
       m_PreviewSegmentationNode->SetData(newPreviewImage);
 
       // Let's paint the feedback node green...
       newPreviewImage->GetActiveLabel()->SetColor(previewColor);
       newPreviewImage->GetActiveLabelSet()->UpdateLookupTable(newPreviewImage->GetActiveLabel()->GetValue());
     }
     else
     {
       mitk::Image::ConstPointer workingImageBin = dynamic_cast<const mitk::Image*>(m_ToolManager->GetWorkingData(0)->GetData());
       if (workingImageBin.IsNotNull())
       {
         auto newPreviewImage = workingImageBin->Clone();
         if (newPreviewImage.IsNull())
         {
           MITK_ERROR << "Cannot create preview helper objects. Unable to clone working image";
           return;
         }
 
         m_PreviewSegmentationNode->SetData(newPreviewImage->Clone());
       }
       else
       {
         mitkThrow() << "Tool is an invalid state. Cannot setup preview node. Working data is an unsupported class and should have not been accepted by CanHandle().";
       }
     }
 
     m_PreviewSegmentationNode->SetColor(previewColor);
     m_PreviewSegmentationNode->SetOpacity(0.5);
 
     int layer(50);
     m_ReferenceDataNode->GetIntProperty("layer", layer);
     m_PreviewSegmentationNode->SetIntProperty("layer", layer + 1);
 
     if (DataStorage *ds = m_ToolManager->GetDataStorage())
     {
       if (!ds->Exists(m_PreviewSegmentationNode))
         ds->Add(m_PreviewSegmentationNode, m_ReferenceDataNode);
     }
   }
 }
 
 template <typename TPixel, unsigned int VImageDimension>
 static void ITKSetVolume(const itk::Image<TPixel, VImageDimension> *originalImage,
                          mitk::Image *segmentation,
                          unsigned int timeStep)
 {
   auto constPixelContainer = originalImage->GetPixelContainer();
   //have to make a const cast because itk::PixelContainer does not provide a const correct access :(
   auto pixelContainer = const_cast<typename itk::Image<TPixel, VImageDimension>::PixelContainer*>(constPixelContainer);
 
   segmentation->SetVolume((void *)pixelContainer->GetBufferPointer(), timeStep);
 }
 
 void mitk::AutoSegmentationWithPreviewTool::TransferImageAtTimeStep(const Image* sourceImage, Image* destinationImage, const TimeStepType timeStep)
 {
   try
   {
     Image::ConstPointer image3D = this->GetImageByTimeStep(sourceImage, timeStep);
 
     if (image3D->GetPixelType() != destinationImage->GetPixelType())
     {
       mitkThrow() << "Cannot transfer images. Tool is in an invalid state, source image and destination image do not have the same pixel type. "
         << "Source pixel type: " << sourceImage->GetPixelType().GetTypeAsString()
         << "; destination pixel type: " << destinationImage->GetPixelType().GetTypeAsString();
     }
 
     if (!Equal(*(sourceImage->GetGeometry(timeStep)), *(destinationImage->GetGeometry(timeStep)), NODE_PREDICATE_GEOMETRY_DEFAULT_CHECK_PRECISION, false))
     {
       mitkThrow() << "Cannot transfer images. Tool is in an invalid state, source image and destination image do not have the same geometry.";
     }
 
     if (image3D->GetDimension() == 2)
     {
       AccessFixedDimensionByItk_2(
         image3D, ITKSetVolume, 2, destinationImage, timeStep);
     }
     else
     {
       AccessFixedDimensionByItk_2(
         image3D, ITKSetVolume, 3, destinationImage, timeStep);
     }
   }
   catch (...)
   {
     Tool::ErrorMessage("Error accessing single time steps of the original image. Cannot create segmentation.");
     throw;
   }
 }
 
 void mitk::AutoSegmentationWithPreviewTool::CreateResultSegmentationFromPreview()
 {
   const auto segInput = this->GetSegmentationInput();
   auto previewImage = this->GetPreviewSegmentation();
   if (nullptr != segInput && nullptr != previewImage)
   {
     DataNode::Pointer resultSegmentationNode = GetTargetSegmentationNode();
 
     if (resultSegmentationNode.IsNotNull())
     {
       const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
       auto resultSegmentation = dynamic_cast<Image*>(resultSegmentationNode->GetData());
 
       // REMARK: the following code in this scope assumes that previewImage and resultSegmentation
       // are clones of the working image (segmentation provided to the tool). Therefore they have
       // the same time geometry.
       if (previewImage->GetTimeSteps() != resultSegmentation->GetTimeSteps())
       {
         mitkThrow() << "Cannot perform threshold. Internal tool state is invalid."
           << " Preview segmentation and segmentation result image have different time geometries.";
       }
 
       if (m_CreateAllTimeSteps)
       {
         for (unsigned int timeStep = 0; timeStep < previewImage->GetTimeSteps(); ++timeStep)
         {
           TransferImageAtTimeStep(previewImage, resultSegmentation, timeStep);
         }
       }
       else
       {
         const auto timeStep = resultSegmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
         TransferImageAtTimeStep(previewImage, resultSegmentation, timeStep);
       }
 
       // since we are maybe working on a smaller image, pad it to the size of the original image
       if (m_ReferenceDataNode.GetPointer() != m_SegmentationInputNode.GetPointer())
       {
         mitk::PadImageFilter::Pointer padFilter = mitk::PadImageFilter::New();
 
         padFilter->SetInput(0, resultSegmentation);
         padFilter->SetInput(1, dynamic_cast<mitk::Image*>(m_ReferenceDataNode->GetData()));
         padFilter->SetBinaryFilter(true);
         padFilter->SetUpperThreshold(1);
         padFilter->SetLowerThreshold(1);
         padFilter->Update();
 
         resultSegmentationNode->SetData(padFilter->GetOutput());
       }
 
       m_ToolManager->SetWorkingData(resultSegmentationNode);
       m_ToolManager->GetWorkingData(0)->Modified();
     }
   }
 }
 
 void mitk::AutoSegmentationWithPreviewTool::OnRoiDataChanged()
 {
   mitk::DataNode::ConstPointer node = m_ToolManager->GetRoiData(0);
 
   if (node.IsNotNull())
   {
     mitk::MaskAndCutRoiImageFilter::Pointer roiFilter = mitk::MaskAndCutRoiImageFilter::New();
     mitk::Image::Pointer image = dynamic_cast<mitk::Image *>(m_SegmentationInputNode->GetData());
 
     if (image.IsNull())
       return;
 
     roiFilter->SetInput(image);
     roiFilter->SetRegionOfInterest(node->GetData());
     roiFilter->Update();
 
     mitk::DataNode::Pointer tmpNode = mitk::DataNode::New();
     tmpNode->SetData(roiFilter->GetOutput());
 
     m_SegmentationInputNode = tmpNode;
   }
   else
     m_SegmentationInputNode = m_ReferenceDataNode;
 
   this->ResetPreviewNode();
   this->InitiateToolByInput();
   this->UpdatePreview();
 }
 
 void mitk::AutoSegmentationWithPreviewTool::OnTimePointChanged()
 {
   if (m_IsTimePointChangeAware && m_PreviewSegmentationNode.IsNotNull() && m_SegmentationInputNode.IsNotNull())
   {
     const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
 
     const bool isStaticSegOnDynamicImage = m_PreviewSegmentationNode->GetData()->GetTimeSteps() == 1 && m_SegmentationInputNode->GetData()->GetTimeSteps() > 1;
     if (timePoint!=m_LastTimePointOfUpdate && (isStaticSegOnDynamicImage || m_LazyDynamicPreviews))
     { //we only need to update either because we are lazzy
       //or because we have a static segmentation with a dynamic image 
       this->UpdatePreview();
     }
   }
 }
 
 void mitk::AutoSegmentationWithPreviewTool::UpdatePreview(bool ignoreLazyPreviewSetting)
 {
   const auto inputImage = this->GetSegmentationInput();
   auto previewImage = this->GetPreviewSegmentation();
   int progress_steps = 200;
 
+  this->CurrentlyBusy.Send(true);
+
   this->UpdatePrepare();
 
   const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
 
   try
   {
-    this->CurrentlyBusy.Send(true);
     if (nullptr != inputImage && nullptr != previewImage)
     {
       m_ProgressCommand->AddStepsToDo(progress_steps);
 
       if (previewImage->GetTimeSteps() > 1 && (ignoreLazyPreviewSetting || !m_LazyDynamicPreviews))
       {
         for (unsigned int timeStep = 0; timeStep < inputImage->GetTimeSteps(); ++timeStep)
         {
           auto feedBackImage3D = this->GetImageByTimeStep(inputImage, timeStep);
 
           this->DoUpdatePreview(feedBackImage3D, previewImage, timeStep);
         }
       }
       else
       {
         auto feedBackImage3D = this->GetImageByTimePoint(inputImage, timePoint);
         auto timeStep = previewImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
         this->DoUpdatePreview(feedBackImage3D, previewImage, timeStep);
       }
       RenderingManager::GetInstance()->RequestUpdateAll();
     }
   }
   catch (itk::ExceptionObject & excep)
   {
     MITK_ERROR << "Exception caught: " << excep.GetDescription();
 
     m_ProgressCommand->SetProgress(progress_steps);
 
     std::string msg = excep.GetDescription();
     ErrorMessage.Send(msg);
   }
   catch (...)
   {
     m_ProgressCommand->SetProgress(progress_steps);
     CurrentlyBusy.Send(false);
     throw;
   }
 
   this->UpdateCleanUp();
   m_LastTimePointOfUpdate = timePoint;
   m_ProgressCommand->SetProgress(progress_steps);
   CurrentlyBusy.Send(false);
 }
 
 void mitk::AutoSegmentationWithPreviewTool::UpdatePrepare()
 {
   // default implementation does nothing
   //reimplement in derived classes for special behavior
 }
 
 void mitk::AutoSegmentationWithPreviewTool::UpdateCleanUp()
 {
   // default implementation does nothing
   //reimplement in derived classes for special behavior
 }
 
 mitk::TimePointType mitk::AutoSegmentationWithPreviewTool::GetLastTimePointOfUpdate() const
 {
   return m_LastTimePointOfUpdate;
 }
diff --git a/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp b/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp
index 9a5f4cc388..ec02f6a346 100644
--- a/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp
+++ b/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp
@@ -1,253 +1,86 @@
 /*============================================================================
 
 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 "mitkOtsuTool3D.h"
-#include "mitkImageAccessByItk.h"
-#include "mitkLabelSetImage.h"
 #include "mitkOtsuSegmentationFilter.h"
-#include "mitkRenderingManager.h"
-#include "mitkToolManager.h"
-#include <mitkITKImageImport.h>
-#include <mitkImageCast.h>
-#include <mitkLevelWindowProperty.h>
-#include <mitkLookupTableProperty.h>
-#include <mitkRenderingModeProperty.h>
-#include <mitkSliceNavigationController.h>
-
-// ITK
-#include <itkBinaryThresholdImageFilter.h>
-#include <itkOrImageFilter.h>
-#include <itkOtsuMultipleThresholdsImageFilter.h>
 
 // us
 #include <usGetModuleContext.h>
 #include <usModule.h>
 #include <usModuleContext.h>
 #include <usModuleResource.h>
 
 #include <mitkImageStatisticsHolder.h>
 
 namespace mitk
 {
   MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, OtsuTool3D, "Otsu Segmentation");
 }
 
-mitk::OtsuTool3D::OtsuTool3D() : AutoSegmentationWithPreviewTool(true)
-{
-}
-
-mitk::OtsuTool3D::~OtsuTool3D()
-{
-}
-
-void mitk::OtsuTool3D::SetSelectedRegions(const SelectedRegionVectorType& regions)
-{
-  if (m_SelectedRegions != regions)
-  {
-    m_SelectedRegions = 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.
-  }
-}
-
-mitk::OtsuTool3D::SelectedRegionVectorType mitk::OtsuTool3D::GetSelectedRegions() const
-{
-  return this->m_SelectedRegions;
-}
-
 void mitk::OtsuTool3D::Activated()
 {
   Superclass::Activated();
 
-  m_SelectedRegions = {};
   m_NumberOfBins = 128;
   m_NumberOfRegions = 2;
   m_UseValley = false;
-
-  m_OtsuResultNode = mitk::DataNode::New();
-  m_OtsuResultNode->SetName("Otsu_Preview");
-  // m_MultiLabelResultNode->SetBoolProperty("helper object", true);
-  m_OtsuResultNode->SetVisibility(true);
-  m_OtsuResultNode->SetOpacity(1.0);
-
-  m_ToolManager->GetDataStorage()->Add(m_OtsuResultNode);
-}
-
-void mitk::OtsuTool3D::Deactivated()
-{
-  m_ToolManager->GetDataStorage()->Remove(m_OtsuResultNode);
-  m_OtsuResultNode = nullptr;
-
-  Superclass::Deactivated();
 }
 
 const char **mitk::OtsuTool3D::GetXPM() const
 {
   return nullptr;
 }
 
 us::ModuleResource mitk::OtsuTool3D::GetIconResource() const
 {
   us::Module *module = us::GetModuleContext()->GetModule();
   us::ModuleResource resource = module->GetResource("Otsu_48x48.png");
   return resource;
 }
 
 const char* mitk::OtsuTool3D::GetName() const
 {
   return "Otsu";
 }
 
-void mitk::OtsuTool3D::UpdateCleanUp()
-{
-  if (m_OtsuResultNode.IsNotNull())
-    m_OtsuResultNode->SetVisibility(m_SelectedRegions.empty());
-
-  if (nullptr != this->GetPreviewSegmentationNode())
-    this->GetPreviewSegmentationNode()->SetVisibility(!m_SelectedRegions.empty());
-
-  if (m_SelectedRegions.empty())
-  {
-    this->ResetPreviewNode();
-  }
-}
-
-void mitk::OtsuTool3D::DoUpdatePreview(const Image* inputAtTimeStep, Image* previewImage, TimeStepType timeStep)
+mitk::LabelSetImage::Pointer mitk::OtsuTool3D::ComputeMLPreview(const Image* inputAtTimeStep, TimeStepType /*timeStep*/)
 {
   int numberOfThresholds = m_NumberOfRegions - 1;
 
-  const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
-  mitk::LabelSetImage::Pointer otsuResultImage = dynamic_cast<LabelSetImage*>(this->m_OtsuResultNode->GetData());
-
-  if (nullptr == m_OtsuResultNode->GetData()
-      || this->GetMTime() > m_OtsuResultNode->GetData()->GetMTime()
-      || this->m_LastOtsuTimeStep != 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 otsu computations
-     )
-  {
-    if (nullptr == inputAtTimeStep)
-    {
-      MITK_WARN << "Cannot run segementation. Currently selected input image is not set.";
-      return;
-    }
-
-    this->m_LastOtsuTimeStep = timeStep;
-
-    mitk::OtsuSegmentationFilter::Pointer otsuFilter = mitk::OtsuSegmentationFilter::New();
-    otsuFilter->SetNumberOfThresholds(numberOfThresholds);
-    otsuFilter->SetValleyEmphasis(m_UseValley);
-    otsuFilter->SetNumberOfBins(m_NumberOfBins);
-    otsuFilter->SetInput(inputAtTimeStep);
-    otsuFilter->AddObserver(itk::ProgressEvent(), m_ProgressCommand);
-
-    try
-    {
-      otsuFilter->Update();
-    }
-    catch (...)
-    {
-      mitkThrow() << "itkOtsuFilter error (image dimension must be in {2, 3} and image must not be RGB)";
-    }
-
-    otsuResultImage = mitk::LabelSetImage::New();
-    otsuResultImage->InitializeByLabeledImage(otsuFilter->GetOutput());
-    this->m_OtsuResultNode->SetData(otsuResultImage);
-    this->m_OtsuResultNode->SetProperty("binary", mitk::BoolProperty::New(false));
-    mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New();
-    renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR);
-    this->m_OtsuResultNode->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_OtsuResultNode->SetProperty("LookupTable", prop);
-    mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
-    mitk::LevelWindow levelwindow;
-    levelwindow.SetRangeMinMax(0, numberOfThresholds + 1);
-    levWinProp->SetLevelWindow(levelwindow);
-    this->m_OtsuResultNode->SetProperty("levelwindow", levWinProp);
-  }
+  mitk::OtsuSegmentationFilter::Pointer otsuFilter = mitk::OtsuSegmentationFilter::New();
+  otsuFilter->SetNumberOfThresholds(numberOfThresholds);
+  otsuFilter->SetValleyEmphasis(m_UseValley);
+  otsuFilter->SetNumberOfBins(m_NumberOfBins);
+  otsuFilter->SetInput(inputAtTimeStep);
+  otsuFilter->AddObserver(itk::ProgressEvent(), m_ProgressCommand);
 
-  if (!m_SelectedRegions.empty())
+  try
   {
-    AccessByItk_n(otsuResultImage, CalculatePreview, (previewImage, timeStep));
+    otsuFilter->Update();
   }
-}
-
-template <typename TPixel, unsigned int VImageDimension>
-void mitk::OtsuTool3D::CalculatePreview(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_SelectedRegions[0]);
-  filter->SetUpperThreshold(m_SelectedRegions[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 regionID : m_SelectedRegions)
+  catch (...)
   {
-    if (regionID != m_SelectedRegions[0])
-    {
-      filter->SetLowerThreshold(regionID);
-      filter->SetUpperThreshold(regionID);
-      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();
-    }
+    mitkThrow() << "itkOtsuFilter error (image dimension must be in {2, 3} and image must not be RGB)";
   }
-  //----------------------------------------------------------------------------------------------------
 
-  segmentation->SetVolume((void*)(itkBinaryResultImage->GetPixelContainer()->GetBufferPointer()), timeStep);
+  auto otsuResultImage = mitk::LabelSetImage::New();
+  otsuResultImage->InitializeByLabeledImage(otsuFilter->GetOutput());
+  return otsuResultImage;
 }
 
 unsigned int mitk::OtsuTool3D::GetMaxNumberOfBins() const
 {
   const auto min = this->GetReferenceData()->GetStatistics()->GetScalarValueMin();
   const auto max = this->GetReferenceData()->GetStatistics()->GetScalarValueMaxNoRecompute();
   return static_cast<unsigned int>(max - min) + 1;
 }
diff --git a/Modules/Segmentation/Interactions/mitkOtsuTool3D.h b/Modules/Segmentation/Interactions/mitkOtsuTool3D.h
index 7761ec60dd..3703b237a6 100644
--- a/Modules/Segmentation/Interactions/mitkOtsuTool3D.h
+++ b/Modules/Segmentation/Interactions/mitkOtsuTool3D.h
@@ -1,80 +1,64 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 #ifndef MITKOTSUTOOL3D_H
 #define MITKOTSUTOOL3D_H
 
-#include "itkImage.h"
-#include "mitkAutoSegmentationWithPreviewTool.h"
-#include "mitkDataNode.h"
+#include "mitkAutoMLSegmentationWithPreviewTool.h"
 #include <MitkSegmentationExports.h>
 
 namespace us
 {
   class ModuleResource;
 }
 
 namespace mitk
 {
   class Image;
 
-  class MITKSEGMENTATION_EXPORT OtsuTool3D : public AutoSegmentationWithPreviewTool
+  class MITKSEGMENTATION_EXPORT OtsuTool3D : public AutoMLSegmentationWithPreviewTool
   {
   public:
-    mitkClassMacro(OtsuTool3D, AutoSegmentationWithPreviewTool);
+    mitkClassMacro(OtsuTool3D, AutoMLSegmentationWithPreviewTool);
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self);
 
     const char *GetName() const override;
     const char **GetXPM() const override;
     us::ModuleResource GetIconResource() const override;
 
     void Activated() override;
-    void Deactivated() override;
 
     itkSetMacro(NumberOfBins, unsigned int);
     itkGetConstMacro(NumberOfBins, unsigned int);
 
     itkSetMacro(NumberOfRegions, unsigned int);
     itkGetConstMacro(NumberOfRegions, unsigned int);
 
     itkSetMacro(UseValley, bool);
     itkGetConstMacro(UseValley, bool);
     itkBooleanMacro(UseValley);
 
-    using SelectedRegionVectorType = std::vector<int>;
-    void SetSelectedRegions(const SelectedRegionVectorType& regions);
-    SelectedRegionVectorType GetSelectedRegions() const;
-
     /**Returns the number of max bins based on the current input image.*/
     unsigned int GetMaxNumberOfBins() const;
 
   protected:
-    OtsuTool3D();
-    ~OtsuTool3D() override;
-
-    void UpdateCleanUp() override;
-    void DoUpdatePreview(const Image* inputAtTimeStep, Image* previewImage, TimeStepType timeStep) override;
+    OtsuTool3D() = default;
+    ~OtsuTool3D() = default;
 
-    template <typename TPixel, unsigned int VImageDimension>
-    void CalculatePreview(itk::Image<TPixel, VImageDimension> *itkImage, mitk::Image* segmentation, unsigned int timeStep);
+    LabelSetImage::Pointer ComputeMLPreview(const Image* inputAtTimeStep, TimeStepType timeStep) override;
 
     unsigned int m_NumberOfBins = 128;
     unsigned int m_NumberOfRegions = 2;
     bool m_UseValley = false;
-    SelectedRegionVectorType m_SelectedRegions = {};
-
-    // holds the multilabel result as a preview image
-    mitk::DataNode::Pointer m_OtsuResultNode;
-    TimeStepType m_LastOtsuTimeStep = 0;
   }; // class
 } // namespace
 #endif
diff --git a/Modules/Segmentation/Interactions/mitkWatershedTool.cpp b/Modules/Segmentation/Interactions/mitkWatershedTool.cpp
index 47e29e4da4..b533bbe242 100644
--- a/Modules/Segmentation/Interactions/mitkWatershedTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkWatershedTool.cpp
@@ -1,188 +1,163 @@
 /*============================================================================
 
 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 "mitkWatershedTool.h"
 
 #include "mitkIOUtil.h"
 #include "mitkITKImageImport.h"
 #include "mitkImage.h"
 #include "mitkLabelSetImage.h"
 #include "mitkImageAccessByItk.h"
 #include "mitkImageCast.h"
 #include "mitkImageStatisticsHolder.h"
 #include "mitkLevelWindowManager.h"
 #include "mitkLookupTable.h"
 #include "mitkLookupTableProperty.h"
 #include "mitkProgressBar.h"
 #include "mitkRenderingManager.h"
 #include "mitkRenderingModeProperty.h"
 #include "mitkToolCommand.h"
 #include "mitkToolManager.h"
 #include <mitkSliceNavigationController.h>
 
 #include <usGetModuleContext.h>
 #include <usModule.h>
 #include <usModuleContext.h>
 #include <usModuleResource.h>
 
 #include <vtkLookupTable.h>
 
 #include <itkExceptionObject.h>
 #include <itkGradientMagnitudeRecursiveGaussianImageFilter.h>
 #include <itkWatershedImageFilter.h>
 
 namespace mitk
 {
   MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, WatershedTool, "Watershed tool");
 }
 
-mitk::WatershedTool::WatershedTool() : m_Threshold(0.0), m_Level(0.0)
-{
-}
-
-mitk::WatershedTool::~WatershedTool()
-{
-}
 
 void mitk::WatershedTool::Activated()
 {
   Superclass::Activated();
-}
 
-void mitk::WatershedTool::Deactivated()
-{
-  Superclass::Deactivated();
+  m_Level = 0.0;
+  m_Threshold = 0.0;
+
+  m_MagFilter = nullptr;
+  m_WatershedFilter = nullptr;
+  m_LastFilterInput = nullptr;
 }
 
 us::ModuleResource mitk::WatershedTool::GetIconResource() const
 {
   us::Module *module = us::GetModuleContext()->GetModule();
   us::ModuleResource resource = module->GetResource("Watershed_48x48.png");
   return resource;
 }
 
 const char **mitk::WatershedTool::GetXPM() const
 {
   return nullptr;
 }
 
 const char *mitk::WatershedTool::GetName() const
 {
   return "Watershed";
 }
 
-void mitk::WatershedTool::DoIt()
+mitk::LabelSetImage::Pointer mitk::WatershedTool::ComputeMLPreview(const Image* inputAtTimeStep, TimeStepType /*timeStep*/)
 {
-  // get image from tool manager
-  mitk::DataNode::Pointer referenceData = m_ToolManager->GetReferenceData(0);
-  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image *>(referenceData->GetData());
-  if (input.IsNull())
-    return;
-
-  const auto timePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
-  input = GetImageByTimePoint(input, timePoint);
-
-  if (nullptr == input)
-  {
-    MITK_WARN << "Cannot run segementation. Currently selected timepoint is not in the time bounds of the selected reference image. Time point: " << timePoint;
-    return;
-  }
-
-  mitk::Image::Pointer output;
+  mitk::LabelSetImage::Pointer labelSetOutput;
 
   try
   {
+    mitk::Image::Pointer output;
+    bool inputChanged = inputAtTimeStep != m_LastFilterInput;
     // create and run itk filter pipeline
-    AccessByItk_1(input.GetPointer(), ITKWatershed, output);
+    AccessByItk_2(inputAtTimeStep, ITKWatershed, output, inputChanged);
 
-    mitk::LabelSetImage::Pointer labelSetOutput = mitk::LabelSetImage::New();
+    labelSetOutput = mitk::LabelSetImage::New();
     labelSetOutput->InitializeByLabeledImage(output);
-
-    // create a new datanode for output
-    mitk::DataNode::Pointer dataNode = mitk::DataNode::New();
-    dataNode->SetData(labelSetOutput);
-
-    // set name of data node
-    std::string name = referenceData->GetName() + "_Watershed";
-    dataNode->SetName(name);
-
-    // look, if there is already a node with this name
-    mitk::DataStorage::SetOfObjects::ConstPointer children =
-      m_ToolManager->GetDataStorage()->GetDerivations(referenceData);
-    mitk::DataStorage::SetOfObjects::ConstIterator currentNode = children->Begin();
-    mitk::DataNode::Pointer removeNode;
-    while (currentNode != children->End())
-    {
-      if (dataNode->GetName().compare(currentNode->Value()->GetName()) == 0)
-      {
-        removeNode = currentNode->Value();
-      }
-      currentNode++;
-    }
-    // remove node with same name
-    if (removeNode.IsNotNull())
-      m_ToolManager->GetDataStorage()->Remove(removeNode);
-
-    // add output to the data storage
-    m_ToolManager->GetDataStorage()->Add(dataNode, referenceData);
   }
-  catch (itk::ExceptionObject &e)
+  catch (itk::ExceptionObject & e)
   {
+    //force reset of filters as they might be in an invalid state now.
+    m_MagFilter = nullptr;
+    m_WatershedFilter = nullptr;
+    m_LastFilterInput = nullptr;
+
     MITK_ERROR << "Watershed Filter Error: " << e.GetDescription();
   }
+  
+  m_LastFilterInput = inputAtTimeStep;
 
-  RenderingManager::GetInstance()->RequestUpdateAll();
+  return labelSetOutput;
 }
 
 template <typename TPixel, unsigned int VImageDimension>
-void mitk::WatershedTool::ITKWatershed(const itk::Image<TPixel, VImageDimension> *originalImage,
-                                       mitk::Image::Pointer &segmentation)
+void mitk::WatershedTool::ITKWatershed(const itk::Image<TPixel, VImageDimension>* originalImage,
+  mitk::Image::Pointer& segmentation, bool inputChanged)
 {
   typedef itk::WatershedImageFilter<itk::Image<float, VImageDimension>> WatershedFilter;
   typedef itk::GradientMagnitudeRecursiveGaussianImageFilter<itk::Image<TPixel, VImageDimension>,
-                                                             itk::Image<float, VImageDimension>>
+    itk::Image<float, VImageDimension>>
     MagnitudeFilter;
 
+  // We create the filter pipeline only once (if needed) and not everytime we
+  // generate the ml image preview.
+  // Reason: If only the levels are changed the update of the pipe line is very
+  // fast and we want to profit from this feature.
+
   // at first add a gradient magnitude filter
-  typename MagnitudeFilter::Pointer magnitude = MagnitudeFilter::New();
-  magnitude->SetInput(originalImage);
-  magnitude->SetSigma(1.0);
+  typename MagnitudeFilter::Pointer magnitude = dynamic_cast<MagnitudeFilter*>(m_MagFilter.GetPointer());
+  if (magnitude.IsNull())
+  {
+    magnitude = MagnitudeFilter::New();
+    magnitude->SetSigma(1.0);
+    magnitude->AddObserver(itk::ProgressEvent(), m_ProgressCommand);
+    m_MagFilter = magnitude.GetPointer();
+  }
 
-  // use the progress bar
-  mitk::ToolCommand::Pointer command = mitk::ToolCommand::New();
-  command->AddStepsToDo(60);
+  if (inputChanged)
+  {
+    magnitude->SetInput(originalImage);
+  }
 
   // then add the watershed filter to the pipeline
-  typename WatershedFilter::Pointer watershed = WatershedFilter::New();
-  watershed->SetInput(magnitude->GetOutput());
+  typename WatershedFilter::Pointer watershed = dynamic_cast<WatershedFilter*>(m_WatershedFilter.GetPointer());
+  if (watershed.IsNull())
+  {
+    watershed = WatershedFilter::New();
+    watershed->SetInput(magnitude->GetOutput());
+    watershed->AddObserver(itk::ProgressEvent(), m_ProgressCommand);
+    m_WatershedFilter = watershed.GetPointer();
+  }
+
   watershed->SetThreshold(m_Threshold);
   watershed->SetLevel(m_Level);
-  watershed->AddObserver(itk::ProgressEvent(), command);
   watershed->Update();
 
   // then make sure, that the output has the desired pixel type
   typedef itk::CastImageFilter<typename WatershedFilter::OutputImageType,
-                               itk::Image<Tool::DefaultSegmentationDataType, VImageDimension>>
+    itk::Image<Tool::DefaultSegmentationDataType, VImageDimension>>
     CastFilter;
   typename CastFilter::Pointer cast = CastFilter::New();
   cast->SetInput(watershed->GetOutput());
 
   // start the whole pipeline
   cast->Update();
 
-  // reset the progress bar by setting progress
-  command->SetProgress(10);
-
   // since we obtain a new image from our pipeline, we have to make sure, that our mitk::Image::Pointer
   // is responsible for the memory management of the output image
   segmentation = mitk::GrabItkImageMemory(cast->GetOutput());
 }
diff --git a/Modules/Segmentation/Interactions/mitkWatershedTool.h b/Modules/Segmentation/Interactions/mitkWatershedTool.h
index f50734141b..a4bea005ec 100644
--- a/Modules/Segmentation/Interactions/mitkWatershedTool.h
+++ b/Modules/Segmentation/Interactions/mitkWatershedTool.h
@@ -1,88 +1,84 @@
 /*============================================================================
 
 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 mitkWatershedTool_h_Included
 #define mitkWatershedTool_h_Included
 
-#include "mitkAutoSegmentationTool.h"
+#include "mitkAutoMLSegmentationWithPreviewTool.h"
 #include "mitkCommon.h"
 #include <MitkSegmentationExports.h>
-#include <itkImage.h>
 
 namespace us
 {
   class ModuleResource;
 }
 
 namespace mitk
 {
-  class Image;
-
   /**
     \brief Simple watershed segmentation tool.
 
     \ingroup Interaction
     \ingroup ToolManagerEtAl
 
     Wraps ITK Watershed Filter into tool concept of MITK. For more information look into ITK documentation.
 
     \warning Only to be instantiated by mitk::ToolManager.
-
-    $Darth Vader$
   */
-  class MITKSEGMENTATION_EXPORT WatershedTool : public AutoSegmentationTool
+  class MITKSEGMENTATION_EXPORT WatershedTool : public AutoMLSegmentationWithPreviewTool
   {
   public:
-    mitkClassMacro(WatershedTool, AutoSegmentationTool);
+    mitkClassMacro(WatershedTool, AutoMLSegmentationWithPreviewTool);
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self);
 
-      void SetThreshold(double t)
-    {
-      m_Threshold = t;
-    }
+    const char** GetXPM() const override;
+    const char* GetName() const override;
+    us::ModuleResource GetIconResource() const override;
+
+    void Activated() override;
+
+    itkSetMacro(Threshold, double);
+    itkGetConstMacro(Threshold, double);
+
+    itkSetMacro(Level, double);
+    itkGetConstMacro(Level, double);
+
+  protected:
+    WatershedTool() = default;
+    ~WatershedTool() = default;
+
+    LabelSetImage::Pointer ComputeMLPreview(const Image* inputAtTimeStep, TimeStepType timeStep) override;
 
-    void SetLevel(double l) { m_Level = l; }
-    /** \brief Grabs the tool reference data and creates an ITK pipeline consisting of a GradientMagnitude
-      * image filter followed by a Watershed image filter. The output of the filter pipeline is then added
-      * to the data storage. */
-    void DoIt();
+    /** \brief Threshold parameter of the ITK Watershed Image Filter. See ITK Documentation for more information. */
+    double m_Threshold = 0.0;
+    /** \brief Threshold parameter of the ITK Watershed Image Filter. See ITK Documentation for more information. */
+    double m_Level = 0.0;
 
+private:
     /** \brief Creates and runs an ITK filter pipeline consisting of the filters: GradientMagnitude-, Watershed- and
      * CastImageFilter.
       *
       * \param originalImage The input image, which is delivered by the AccessByItk macro.
       * \param segmentation A pointer to the output image, which will point to the pipeline output after execution.
       */
     template <typename TPixel, unsigned int VImageDimension>
-    void ITKWatershed(const itk::Image<TPixel, VImageDimension> *originalImage, itk::SmartPointer<mitk::Image> &segmentation);
-
-    const char **GetXPM() const override;
-    const char *GetName() const override;
-    us::ModuleResource GetIconResource() const override;
-
-  protected:
-    WatershedTool(); // purposely hidden
-    ~WatershedTool() override;
-
-    void Activated() override;
-    void Deactivated() override;
+    void ITKWatershed(const itk::Image<TPixel, VImageDimension>* originalImage, itk::SmartPointer<mitk::Image>& segmentation, bool inputChanged);
 
-    /** \brief Threshold parameter of the ITK Watershed Image Filter. See ITK Documentation for more information. */
-    double m_Threshold;
-    /** \brief Threshold parameter of the ITK Watershed Image Filter. See ITK Documentation for more information. */
-    double m_Level;
+    itk::ProcessObject::Pointer m_MagFilter;
+    itk::ProcessObject::Pointer m_WatershedFilter;
+    mitk::Image::ConstPointer m_LastFilterInput;
   };
 
 } // namespace
 
 #endif
diff --git a/Modules/Segmentation/files.cmake b/Modules/Segmentation/files.cmake
index 1deb993fd5..3bce31c9b5 100644
--- a/Modules/Segmentation/files.cmake
+++ b/Modules/Segmentation/files.cmake
@@ -1,117 +1,118 @@
 set(CPP_FILES
   Algorithms/mitkCalculateSegmentationVolume.cpp
   Algorithms/mitkContourModelSetToImageFilter.cpp
   Algorithms/mitkContourSetToPointSetFilter.cpp
   Algorithms/mitkContourUtils.cpp
   Algorithms/mitkCorrectorAlgorithm.cpp
   Algorithms/mitkDiffImageApplier.cpp
   Algorithms/mitkDiffSliceOperation.cpp
   Algorithms/mitkDiffSliceOperationApplier.cpp
   Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp
   Algorithms/mitkImageLiveWireContourModelFilter.cpp
   Algorithms/mitkImageToContourFilter.cpp
   #Algorithms/mitkImageToContourModelFilter.cpp
   Algorithms/mitkImageToLiveWireContourFilter.cpp
   Algorithms/mitkManualSegmentationToSurfaceFilter.cpp
   Algorithms/mitkOtsuSegmentationFilter.cpp
   Algorithms/mitkOverwriteDirectedPlaneImageFilter.cpp
   Algorithms/mitkOverwriteSliceImageFilter.cpp
   Algorithms/mitkSegmentationObjectFactory.cpp
   Algorithms/mitkShapeBasedInterpolationAlgorithm.cpp
   Algorithms/mitkShowSegmentationAsSmoothedSurface.cpp
   Algorithms/mitkShowSegmentationAsSurface.cpp
   Algorithms/mitkVtkImageOverwrite.cpp
   Controllers/mitkSegmentationInterpolationController.cpp
   Controllers/mitkToolManager.cpp
   Controllers/mitkSegmentationModuleActivator.cpp
   Controllers/mitkToolManagerProvider.cpp
   DataManagement/mitkContour.cpp
   DataManagement/mitkContourSet.cpp
   DataManagement/mitkExtrudedContour.cpp
   Interactions/mitkAdaptiveRegionGrowingTool.cpp
   Interactions/mitkAddContourTool.cpp
   Interactions/mitkAutoCropTool.cpp
   Interactions/mitkAutoSegmentationTool.cpp
   Interactions/mitkAutoSegmentationWithPreviewTool.cpp
+  Interactions/mitkAutoMLSegmentationWithPreviewTool.cpp
   Interactions/mitkBinaryThresholdBaseTool.cpp
   Interactions/mitkBinaryThresholdTool.cpp
   Interactions/mitkBinaryThresholdULTool.cpp
   Interactions/mitkCalculateGrayValueStatisticsTool.cpp
   Interactions/mitkCalculateVolumetryTool.cpp
   Interactions/mitkContourModelInteractor.cpp
   Interactions/mitkContourModelLiveWireInteractor.cpp
   Interactions/mitkLiveWireTool2D.cpp
   Interactions/mitkContourTool.cpp
   Interactions/mitkCorrectorTool2D.cpp
   Interactions/mitkCreateSurfaceTool.cpp
   Interactions/mitkDrawPaintbrushTool.cpp
   Interactions/mitkErasePaintbrushTool.cpp
   Interactions/mitkEraseRegionTool.cpp
   Interactions/mitkFastMarchingTool.cpp
   Interactions/mitkFastMarchingTool3D.cpp
   Interactions/mitkFeedbackContourTool.cpp
   Interactions/mitkFillRegionTool.cpp
   Interactions/mitkOtsuTool3D.cpp
   Interactions/mitkPaintbrushTool.cpp
   Interactions/mitkPixelManipulationTool.cpp
   Interactions/mitkRegionGrowingTool.cpp
   Interactions/mitkSegmentationsProcessingTool.cpp
   Interactions/mitkSetRegionTool.cpp
   Interactions/mitkSegTool2D.cpp
   Interactions/mitkSubtractContourTool.cpp
   Interactions/mitkTool.cpp
   Interactions/mitkToolCommand.cpp
   Interactions/mitkWatershedTool.cpp
   Interactions/mitkPickingTool.cpp
   Interactions/mitkSegmentationInteractor.cpp #SO
   Rendering/mitkContourMapper2D.cpp
   Rendering/mitkContourSetMapper2D.cpp
   Rendering/mitkContourSetVtkMapper3D.cpp
   Rendering/mitkContourVtkMapper3D.cpp
   SegmentationUtilities/BooleanOperations/mitkBooleanOperation.cpp
   SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp
 #Added from ML
   Controllers/mitkSliceBasedInterpolationController.cpp
   Algorithms/mitkSurfaceStampImageFilter.cpp
 )
 
 set(RESOURCE_FILES
   Add_48x48.png
   Add_Cursor_32x32.png
   Correction_48x48.png
   Correction_Cursor_32x32.png
   Erase_48x48.png
   Erase_Cursor_32x32.png
   FastMarching_48x48.png
   FastMarching_Cursor_32x32.png
   Fill_48x48.png
   Fill_Cursor_32x32.png
   LiveWire_48x48.png
   LiveWire_Cursor_32x32.png
   Otsu_48x48.png
   Paint_48x48.png
   Paint_Cursor_32x32.png
   Pick_48x48.png
   RegionGrowing_48x48.png
   RegionGrowing_Cursor_32x32.png
   Subtract_48x48.png
   Subtract_Cursor_32x32.png
   Threshold_48x48.png
   TwoThresholds_48x48.png
   Watershed_48x48.png
   Watershed_Cursor_32x32.png
   Wipe_48x48.png
   Wipe_Cursor_32x32.png
 
   Interactions/dummy.xml
   Interactions/LiveWireTool.xml
   Interactions/FastMarchingTool.xml
   Interactions/PressMoveRelease.xml
   Interactions/PressMoveReleaseAndPointSetting.xml
   Interactions/PressMoveReleaseWithCTRLInversion.xml
   Interactions/PressMoveReleaseWithCTRLInversionAllMouseMoves.xml
   Interactions/SegmentationToolsConfig.xml
 
   Interactions/ContourModelModificationConfig.xml
   Interactions/ContourModelModificationInteractor.xml
 )
diff --git a/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.cpp
index 031b353dab..9e925b66ba 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.cpp
@@ -1,214 +1,194 @@
 /*============================================================================
 
 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 "QmitkOtsuTool3DGUI.h"
-#include "QmitkConfirmSegmentationDialog.h"
 
 #include <QMessageBox>
-#include <qlabel.h>
-#include <qlayout.h>
-#include <qlistwidget.h>
-#include <qpushbutton.h>
-#include <qspinbox.h>
 
 MITK_TOOL_GUI_MACRO(MITKSEGMENTATIONUI_EXPORT, QmitkOtsuTool3DGUI, "")
 
 QmitkOtsuTool3DGUI::QmitkOtsuTool3DGUI() : QmitkToolGUI(), m_NumberOfRegions(0)
 {
   m_Controls.setupUi(this);
 
   connect(m_Controls.previewButton, SIGNAL(clicked()), this, SLOT(OnSpinboxValueAccept()));
-  connect(m_Controls.m_selectionListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(OnRegionSelectionChanged()));
+  connect(m_Controls.m_selectionListWidget, &QmitkSimpleLabelSetListWidget::SelectedLabelsChanged, this, &QmitkOtsuTool3DGUI::OnRegionSelectionChanged);
   connect(m_Controls.m_Spinbox, SIGNAL(valueChanged(int)), this, SLOT(OnRegionSpinboxChanged(int)));
   connect(m_Controls.m_ConfSegButton, SIGNAL(clicked()), this, SLOT(OnSegmentationRegionAccept()));
   connect(this, SIGNAL(NewToolAssociated(mitk::Tool *)), this, SLOT(OnNewToolAssociated(mitk::Tool *)));
   connect(m_Controls.advancedSettingsButton, SIGNAL(toggled(bool)), this, SLOT(OnAdvancedSettingsButtonToggled(bool)));
 
   this->OnAdvancedSettingsButtonToggled(false);
 }
 
 QmitkOtsuTool3DGUI::~QmitkOtsuTool3DGUI()
 {
   if (m_OtsuTool3DTool.IsNotNull())
   {
     m_OtsuTool3DTool->CurrentlyBusy -=
       mitk::MessageDelegate1<QmitkOtsuTool3DGUI, bool>(this, &QmitkOtsuTool3DGUI::BusyStateChanged);
   }
 }
 
 void QmitkOtsuTool3DGUI::OnRegionSpinboxChanged(int numberOfRegions)
 {
   // we have to change to minimum number of histogram bins accordingly
   int curBinValue = m_Controls.m_BinsSpinBox->value();
   if (curBinValue < numberOfRegions)
     m_Controls.m_BinsSpinBox->setValue(numberOfRegions);
 }
 
-void QmitkOtsuTool3DGUI::OnRegionSelectionChanged()
+void QmitkOtsuTool3DGUI::OnRegionSelectionChanged(const QmitkSimpleLabelSetListWidget::LabelVectorType& selectedLabels)
 {
-  m_SelectedItems = m_Controls.m_selectionListWidget->selectedItems();
-
   if (m_OtsuTool3DTool.IsNotNull())
   {
-    // update preview of region
-    QList<QListWidgetItem *>::Iterator it;
-    std::vector<int> regionIDs;
-    for (it = m_SelectedItems.begin(); it != m_SelectedItems.end(); ++it)
-      regionIDs.push_back((*it)->text().toInt());
+    mitk::AutoMLSegmentationWithPreviewTool::SelectedLabelVectorType labelIDs;
+    for (const auto& label : selectedLabels)
+    {
+      labelIDs.push_back(label->GetValue());
+    }
 
-    m_OtsuTool3DTool->SetSelectedRegions(regionIDs);
+    m_OtsuTool3DTool->SetSelectedLabels(labelIDs);
     m_OtsuTool3DTool->UpdatePreview();
 
-    m_Controls.m_ConfSegButton->setEnabled(!regionIDs.empty());
+    m_Controls.m_ConfSegButton->setEnabled(!labelIDs.empty());
   }
 }
 
 void QmitkOtsuTool3DGUI::OnAdvancedSettingsButtonToggled(bool toggled)
 {
   m_Controls.m_ValleyCheckbox->setVisible(toggled);
   m_Controls.binLabel->setVisible(toggled);
   m_Controls.m_BinsSpinBox->setVisible(toggled);
 
   if (toggled)
   {
     int max = m_OtsuTool3DTool->GetMaxNumberOfBins();
     if (max >= m_Controls.m_BinsSpinBox->minimum())
     {
       m_Controls.m_BinsSpinBox->setMaximum(max);
     }
   }
 }
 
 void QmitkOtsuTool3DGUI::OnNewToolAssociated(mitk::Tool *tool)
 {
   if (m_OtsuTool3DTool.IsNotNull())
   {
     m_OtsuTool3DTool->CurrentlyBusy -=
       mitk::MessageDelegate1<QmitkOtsuTool3DGUI, bool>(this, &QmitkOtsuTool3DGUI::BusyStateChanged);
   }
 
   m_OtsuTool3DTool = dynamic_cast<mitk::OtsuTool3D *>(tool);
 
   if (m_OtsuTool3DTool.IsNotNull())
   {
     m_OtsuTool3DTool->CurrentlyBusy +=
       mitk::MessageDelegate1<QmitkOtsuTool3DGUI, bool>(this, &QmitkOtsuTool3DGUI::BusyStateChanged);
 
     m_OtsuTool3DTool->SetOverwriteExistingSegmentation(true);
     m_OtsuTool3DTool->IsTimePointChangeAwareOff();
     m_Controls.m_CheckProcessAll->setVisible(m_OtsuTool3DTool->GetTargetSegmentationNode()->GetData()->GetTimeSteps() > 1);
   }
 }
 
 void QmitkOtsuTool3DGUI::OnSegmentationRegionAccept()
 {
-  QmitkConfirmSegmentationDialog dialog;
   QString segName = QString::fromStdString(m_OtsuTool3DTool->GetCurrentSegmentationName());
 
   if (m_OtsuTool3DTool.IsNotNull())
   {
     if (this->m_Controls.m_CheckCreateNew->isChecked())
     {
       m_OtsuTool3DTool->SetOverwriteExistingSegmentation(false);
     }
     else
     {
       m_OtsuTool3DTool->SetOverwriteExistingSegmentation(true);
     }
 
     m_OtsuTool3DTool->SetCreateAllTimeSteps(this->m_Controls.m_CheckProcessAll->isChecked());
 
     this->m_Controls.m_ConfSegButton->setEnabled(false);
     m_OtsuTool3DTool->ConfirmSegmentation();
   }
 }
 
 void QmitkOtsuTool3DGUI::OnSpinboxValueAccept()
 {
   if (m_NumberOfRegions == m_Controls.m_Spinbox->value() &&
       m_UseValleyEmphasis == m_Controls.m_ValleyCheckbox->isChecked() &&
       m_NumberOfBins == m_Controls.m_BinsSpinBox->value())
     return;
 
   if (m_OtsuTool3DTool.IsNotNull())
   {
     try
     {
       int proceed;
       QMessageBox *messageBox = new QMessageBox(QMessageBox::Question,
                                                 nullptr,
                                                 "The otsu segmentation computation may take several minutes depending "
                                                 "on the number of Regions you selected. Proceed anyway?",
                                                 QMessageBox::Ok | QMessageBox::Cancel);
       if (m_Controls.m_Spinbox->value() >= 5)
       {
         proceed = messageBox->exec();
         if (proceed != QMessageBox::Ok)
           return;
       }
 
       m_NumberOfRegions = m_Controls.m_Spinbox->value();
       m_UseValleyEmphasis = m_Controls.m_ValleyCheckbox->isChecked();
       m_NumberOfBins = m_Controls.m_BinsSpinBox->value();
       m_OtsuTool3DTool->SetNumberOfRegions(m_NumberOfRegions);
       m_OtsuTool3DTool->SetUseValley(m_UseValleyEmphasis);
       m_OtsuTool3DTool->SetNumberOfBins(m_NumberOfBins);
 
       m_OtsuTool3DTool->UpdatePreview();
     }
     catch (...)
     {
       this->setCursor(Qt::ArrowCursor);
       QMessageBox *messageBox =
         new QMessageBox(QMessageBox::Critical,
                         nullptr,
                         "itkOtsuFilter error: image dimension must be in {2, 3} and no RGB images can be handled.");
       messageBox->exec();
       delete messageBox;
       return;
     }
 
-    // insert regions into widget
-    QString itemName;
-    QListWidgetItem *item;
-    m_Controls.m_selectionListWidget->clear();
-    for (int i = 0; i < m_Controls.m_Spinbox->value(); ++i)
-    {
-      itemName = QString::number(i);
-      item = new QListWidgetItem(itemName);
-      m_Controls.m_selectionListWidget->addItem(item);
-    }
-    // deactivate 'confirm segmentation'-button
-    m_Controls.m_ConfSegButton->setEnabled(false);
+    m_Controls.m_selectionListWidget->SetLabelSetImage(m_OtsuTool3DTool->GetMLPreview());
     m_OtsuTool3DTool->IsTimePointChangeAwareOn();
   }
 }
 
 void QmitkOtsuTool3DGUI::BusyStateChanged(bool value)
 {
   if (value)
   {
     QApplication::setOverrideCursor(QCursor(Qt::BusyCursor));
   }
   else
   {
     QApplication::restoreOverrideCursor();
   }
 
   m_Controls.m_ValleyCheckbox->setEnabled(!value);
   m_Controls.binLabel->setEnabled(!value);
   m_Controls.m_BinsSpinBox->setEnabled(!value);
-  m_Controls.m_ConfSegButton->setEnabled(!m_OtsuTool3DTool->GetSelectedRegions().empty() && !value);
+  m_Controls.m_ConfSegButton->setEnabled(!m_OtsuTool3DTool->GetSelectedLabels().empty() && !value);
   m_Controls.m_CheckProcessAll->setEnabled(!value);
   m_Controls.m_CheckCreateNew->setEnabled(!value);
   m_Controls.previewButton->setEnabled(!value);
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.h b/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.h
index ce2ad862fe..e7a3762c43 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkOtsuTool3DGUI.h
@@ -1,83 +1,75 @@
 /*============================================================================
 
 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 QmitkOtsuTool3DGUI_h_Included
 #define QmitkOtsuTool3DGUI_h_Included
 
 #include "QmitkToolGUI.h"
 #include "mitkOtsuTool3D.h"
+
 #include "ui_QmitkOtsuToolWidgetControls.h"
+
 #include <MitkSegmentationUIExports.h>
-#include <QListWidget>
 #include <QPushButton>
 
-class QSpinBox;
-class QLabel;
-
 /**
   \ingroup org_mitk_gui_qt_interactivesegmentation_internal
   \brief GUI for mitk::.
   \sa mitk::
 
   This GUI shows ...
 
   Last contributor: $Author$
 */
 class MITKSEGMENTATIONUI_EXPORT QmitkOtsuTool3DGUI : public QmitkToolGUI
 {
   Q_OBJECT
 
 public:
   mitkClassMacro(QmitkOtsuTool3DGUI, QmitkToolGUI);
   itkFactorylessNewMacro(Self);
   itkCloneMacro(Self);
 
-    signals :
+protected slots :
 
-    public slots :
-
-    protected slots :
-
-    void OnNewToolAssociated(mitk::Tool *);
+  void OnNewToolAssociated(mitk::Tool *);
 
   void OnSpinboxValueAccept();
 
   void OnSegmentationRegionAccept();
 
-  void OnRegionSelectionChanged();
+  void OnRegionSelectionChanged(const QmitkSimpleLabelSetListWidget::LabelVectorType& selectedLabels);
 
   void OnRegionSpinboxChanged(int);
 
 private slots:
 
   void OnAdvancedSettingsButtonToggled(bool toggled);
 
 protected:
   QmitkOtsuTool3DGUI();
   ~QmitkOtsuTool3DGUI() override;
 
   void BusyStateChanged(bool value) override;
 
   mitk::OtsuTool3D::Pointer m_OtsuTool3DTool;
 
   Ui_QmitkOtsuToolWidgetControls m_Controls;
 
   int m_NumberOfRegions;
 
   bool m_UseValleyEmphasis;
 
   int m_NumberOfBins;
-
-  QList<QListWidgetItem *> m_SelectedItems;
 };
 
 #endif
diff --git a/Modules/SegmentationUI/Qmitk/QmitkOtsuToolWidgetControls.ui b/Modules/SegmentationUI/Qmitk/QmitkOtsuToolWidgetControls.ui
index 27e1d87ff8..d01d26178d 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkOtsuToolWidgetControls.ui
+++ b/Modules/SegmentationUI/Qmitk/QmitkOtsuToolWidgetControls.ui
@@ -1,234 +1,253 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>QmitkOtsuToolWidgetControls</class>
  <widget class="QWidget" name="QmitkOtsuToolWidgetControls">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>192</width>
-    <height>300</height>
+    <width>699</width>
+    <height>352</height>
    </rect>
   </property>
   <property name="sizePolicy">
    <sizepolicy hsizetype="Ignored" vsizetype="Minimum">
     <horstretch>0</horstretch>
     <verstretch>0</verstretch>
    </sizepolicy>
   </property>
   <property name="minimumSize">
    <size>
     <width>100</width>
     <height>0</height>
    </size>
   </property>
   <property name="maximumSize">
    <size>
     <width>100000</width>
     <height>100000</height>
    </size>
   </property>
   <property name="windowTitle">
    <string>QmitkOtsuToolWidget</string>
   </property>
-  <property name="toolTip">
-   <string>Move to adjust the segmentation</string>
-  </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <property name="sizeConstraint">
       <enum>QLayout::SetNoConstraint</enum>
      </property>
      <item>
       <widget class="QLabel" name="numberOfRegionsLabel">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Ignored" vsizetype="Minimum">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="text">
         <string>Number of Regions:</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QSpinBox" name="m_Spinbox">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="maximumSize">
         <size>
          <width>40</width>
          <height>16777215</height>
         </size>
        </property>
        <property name="minimum">
         <number>2</number>
        </property>
        <property name="maximum">
         <number>32</number>
        </property>
       </widget>
      </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
     </layout>
    </item>
    <item>
     <widget class="ctkExpandButton" name="advancedSettingsButton">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="minimumSize">
       <size>
        <width>0</width>
        <height>32</height>
       </size>
      </property>
      <property name="text">
       <string>Advanced settings</string>
      </property>
      <property name="toolButtonStyle">
       <enum>Qt::ToolButtonTextBesideIcon</enum>
      </property>
      <property name="mirrorOnExpand" stdset="0">
       <bool>true</bool>
      </property>
     </widget>
    </item>
    <item>
-    <layout class="QGridLayout" name="advancedSettingsLayout">
+    <layout class="QGridLayout" name="advancedSettingsLayout" rowstretch="0,0" columnstretch="0,0,0">
+     <item row="1" column="1">
+      <widget class="QSpinBox" name="m_BinsSpinBox">
+       <property name="minimum">
+        <number>2</number>
+       </property>
+       <property name="maximum">
+        <number>4096</number>
+       </property>
+       <property name="value">
+        <number>128</number>
+       </property>
+      </widget>
+     </item>
      <item row="0" column="0">
       <widget class="QCheckBox" name="m_ValleyCheckbox">
        <property name="text">
         <string>Use Valley Emphasis</string>
        </property>
       </widget>
      </item>
      <item row="1" column="0">
       <widget class="QLabel" name="binLabel">
        <property name="text">
         <string>Number of Histogram Bins:</string>
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
-      <widget class="QSpinBox" name="m_BinsSpinBox">
-       <property name="minimum">
-        <number>2</number>
-       </property>
-       <property name="maximum">
-        <number>4096</number>
+     <item row="1" column="2">
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
        </property>
-       <property name="value">
-        <number>128</number>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
        </property>
-      </widget>
+      </spacer>
      </item>
     </layout>
    </item>
    <item>
-    <widget class="QListWidget" name="m_selectionListWidget">
+    <widget class="QmitkSimpleLabelSetListWidget" name="m_selectionListWidget" native="true">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="maximumSize">
       <size>
        <width>10000000</width>
-       <height>100</height>
+       <height>10000000</height>
       </size>
      </property>
-     <property name="autoScrollMargin">
-      <number>0</number>
-     </property>
-     <property name="selectionMode">
-      <enum>QAbstractItemView::MultiSelection</enum>
-     </property>
-     <property name="resizeMode">
-      <enum>QListView::Adjust</enum>
-     </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="previewButton">
      <property name="sizePolicy">
-      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+      <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="maximumSize">
       <size>
        <width>100000</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="text">
       <string>Preview</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="m_ConfSegButton">
      <property name="enabled">
       <bool>false</bool>
      </property>
      <property name="sizePolicy">
-      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+      <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="maximumSize">
       <size>
        <width>100000</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="text">
       <string>Confirm Segmentation</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QCheckBox" name="m_CheckProcessAll">
      <property name="toolTip">
       <string>Process/overwrite all time steps of the dynamic segmentation and not just the currently visible time step.</string>
      </property>
      <property name="text">
       <string>Process all time steps</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QCheckBox" name="m_CheckCreateNew">
      <property name="toolTip">
       <string>Add the confirmed segmentation as a new segmentation instead of overwriting the currently selected.</string>
      </property>
      <property name="text">
       <string>Create as new segmentation</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>
   <customwidget>
    <class>ctkExpandButton</class>
    <extends>QToolButton</extends>
    <header>ctkExpandButton.h</header>
   </customwidget>
+  <customwidget>
+   <class>QmitkSimpleLabelSetListWidget</class>
+   <extends>QWidget</extends>
+   <header>QmitkSimpleLabelSetListWidget.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSimpleLabelSetListWidget.cpp b/Modules/SegmentationUI/Qmitk/QmitkSimpleLabelSetListWidget.cpp
new file mode 100644
index 0000000000..8d6f3215f9
--- /dev/null
+++ b/Modules/SegmentationUI/Qmitk/QmitkSimpleLabelSetListWidget.cpp
@@ -0,0 +1,182 @@
+/*============================================================================
+
+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 "QmitkSimpleLabelSetListWidget.h"
+
+#include "mitkMessage.h"
+
+#include <qlayout.h>
+
+QmitkSimpleLabelSetListWidget::QmitkSimpleLabelSetListWidget(QWidget* parent) : QWidget(parent), m_LabelList(nullptr)
+{
+  QGridLayout* layout = new QGridLayout(this);
+  this->setContentsMargins(0, 0, 0, 0);
+
+  m_LabelList = new QListWidget(this);
+  m_LabelList->setSelectionMode(QAbstractItemView::MultiSelection);
+  m_LabelList->setResizeMode(QListView::Adjust);
+  m_LabelList->setAutoScrollMargin(0);
+  layout->addWidget(m_LabelList);
+
+  connect(m_LabelList, SIGNAL(itemSelectionChanged()), this, SLOT(OnLabelSelectionChanged()));
+}
+
+QmitkSimpleLabelSetListWidget::~QmitkSimpleLabelSetListWidget()
+{
+  if (m_LabelSetImage.IsNotNull())
+  {
+    m_LabelSetImage->BeforeChangeLayerEvent -= mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+      this, &QmitkSimpleLabelSetListWidget::OnLooseLabelSetConnection);
+    m_LabelSetImage->AfterChangeLayerEvent -= mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+      this, &QmitkSimpleLabelSetListWidget::OnEstablishLabelSetConnection);
+    OnLooseLabelSetConnection();
+  }
+}
+
+QmitkSimpleLabelSetListWidget::LabelVectorType QmitkSimpleLabelSetListWidget::SelectedLabels() const
+{
+  auto selectedItems = m_LabelList->selectedItems();
+  LabelVectorType result;
+
+  QList<QListWidgetItem*>::Iterator it;
+  for (it = selectedItems.begin(); it != selectedItems.end(); ++it)
+  {
+    auto labelValue = (*it)->data(Qt::UserRole).toUInt();
+
+
+    auto activeLayerID = m_LabelSetImage->GetActiveLayer();
+    auto labelSet = m_LabelSetImage->GetLabelSet(activeLayerID);
+    
+    result.push_back(labelSet->GetLabel(labelValue));
+  }
+
+  return result;
+}
+
+const mitk::LabelSetImage* QmitkSimpleLabelSetListWidget::GetLabelSetImage() const
+{
+  return m_LabelSetImage;
+}
+
+void QmitkSimpleLabelSetListWidget::SetLabelSetImage(const mitk::LabelSetImage* image)
+{
+  if (image != m_LabelSetImage)
+  {
+    if (m_LabelSetImage.IsNotNull())
+    {
+      m_LabelSetImage->BeforeChangeLayerEvent -= mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+        this, &QmitkSimpleLabelSetListWidget::OnLooseLabelSetConnection);
+      m_LabelSetImage->AfterChangeLayerEvent -= mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+        this, &QmitkSimpleLabelSetListWidget::OnLayerChanged);
+      this->OnLooseLabelSetConnection();
+    }
+
+    m_LabelSetImage = image;
+
+    if (m_LabelSetImage.IsNotNull())
+    {
+      m_LabelSetImage->BeforeChangeLayerEvent += mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+        this, &QmitkSimpleLabelSetListWidget::OnLooseLabelSetConnection);
+      m_LabelSetImage->AfterChangeLayerEvent += mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+        this, &QmitkSimpleLabelSetListWidget::OnLayerChanged);
+      this->OnLayerChanged();
+    }
+  }
+}
+
+void QmitkSimpleLabelSetListWidget::OnLooseLabelSetConnection()
+{
+  if (m_LabelSetImage.IsNull())
+    return;
+
+  auto activeLayerID = m_LabelSetImage->GetActiveLayer();
+  auto labelSet = m_LabelSetImage->GetLabelSet(activeLayerID);
+
+  // Reset LabelSetWidget Events
+  labelSet->AddLabelEvent -= mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+    this, &QmitkSimpleLabelSetListWidget::OnLabelChanged);
+  labelSet->RemoveLabelEvent -= mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+    this, &QmitkSimpleLabelSetListWidget::OnLabelChanged);
+  labelSet->ModifyLabelEvent -= mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+    this, &QmitkSimpleLabelSetListWidget::OnLabelChanged);
+}
+
+void QmitkSimpleLabelSetListWidget::OnEstablishLabelSetConnection()
+{
+  if (m_LabelSetImage.IsNull())
+    return;
+
+  auto activeLayerID = m_LabelSetImage->GetActiveLayer();
+  auto labelSet = m_LabelSetImage->GetLabelSet(activeLayerID);
+
+  // Reset LabelSetWidget Events
+  labelSet->AddLabelEvent += mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+    this, &QmitkSimpleLabelSetListWidget::OnLabelChanged);
+  labelSet->RemoveLabelEvent += mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+    this, &QmitkSimpleLabelSetListWidget::OnLabelChanged);
+  labelSet->ModifyLabelEvent += mitk::MessageDelegate<QmitkSimpleLabelSetListWidget>(
+    this, &QmitkSimpleLabelSetListWidget::OnLabelChanged);
+}
+
+void QmitkSimpleLabelSetListWidget::OnLayerChanged()
+{
+  this->OnEstablishLabelSetConnection();
+  this->ResetList();
+  emit ActiveLayerChanged();
+  emit SelectedLabelsChanged(this->SelectedLabels());
+}
+
+void QmitkSimpleLabelSetListWidget::OnLabelChanged()
+{
+  this->ResetList();
+  emit ActiveLayerChanged();
+  emit SelectedLabelsChanged(this->SelectedLabels());
+}
+
+void QmitkSimpleLabelSetListWidget::OnLabelSelectionChanged()
+{
+  emit SelectedLabelsChanged(this->SelectedLabels());
+}
+
+void QmitkSimpleLabelSetListWidget::ResetList()
+{
+  m_LabelList->clear();
+  
+  auto activeLayerID = m_LabelSetImage->GetActiveLayer();
+  auto labelSet = m_LabelSetImage->GetLabelSet(activeLayerID);
+
+  auto iter = labelSet->IteratorConstBegin();
+  for (; iter != labelSet->IteratorConstEnd(); ++iter)
+  {
+    auto color = iter->second->GetColor();
+    QPixmap pixmap(10, 10);
+    pixmap.fill(QColor(color[0] * 255, color[1] * 255, color[2] * 255));
+    QIcon icon(pixmap);
+
+    QListWidgetItem* item = new QListWidgetItem(icon, QString::fromStdString(iter->second->GetName()));
+    item->setData(Qt::UserRole, QVariant(iter->second->GetValue()));
+    m_LabelList->addItem(item);
+  }
+}
+
+void QmitkSimpleLabelSetListWidget::SetSelectedLabels(const LabelVectorType& selectedLabels)
+{
+  for (int i = 0; i < m_LabelList->count(); ++i)
+  {
+    QListWidgetItem* item = m_LabelList->item(i);
+    auto labelValue = item->data(Qt::UserRole).toUInt();
+
+    auto finding = std::find_if(selectedLabels.begin(), selectedLabels.end(), [labelValue](const mitk::Label* label) {return label->GetValue() == labelValue; });
+    item->setSelected(finding != selectedLabels.end());
+  }
+}
+
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSimpleLabelSetListWidget.h b/Modules/SegmentationUI/Qmitk/QmitkSimpleLabelSetListWidget.h
new file mode 100644
index 0000000000..88c716ff0c
--- /dev/null
+++ b/Modules/SegmentationUI/Qmitk/QmitkSimpleLabelSetListWidget.h
@@ -0,0 +1,63 @@
+/*============================================================================
+
+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 QmitkSimpleLabelSetListWidget_h_Included
+#define QmitkSimpleLabelSetListWidget_h_Included
+
+#include "mitkLabel.h"
+#include "mitkLabelSetImage.h"
+#include <MitkSegmentationUIExports.h>
+#include <QListWidget>
+
+/**
+  \brief Widget that offers a simple list that displays all labels (color and name) in the active
+  layer of a LabelSetImage.
+*/
+class MITKSEGMENTATIONUI_EXPORT QmitkSimpleLabelSetListWidget : public QWidget
+{
+  Q_OBJECT
+
+public:
+  QmitkSimpleLabelSetListWidget(QWidget* parent = nullptr);
+  ~QmitkSimpleLabelSetListWidget() override;
+
+  using LabelVectorType = std::vector<mitk::Label::ConstPointer>;
+
+  LabelVectorType SelectedLabels() const;
+  const mitk::LabelSetImage* GetLabelSetImage() const;
+
+signals:
+  void SelectedLabelsChanged(const LabelVectorType& selectedLabels);
+  void ActiveLayerChanged();
+
+public slots :
+  void SetLabelSetImage(const mitk::LabelSetImage* image);
+  void SetSelectedLabels(const LabelVectorType& selectedLabels);
+
+protected slots:
+
+  void OnLabelSelectionChanged();
+
+protected:
+  void OnLayerChanged();
+  void OnLabelChanged();
+
+  void OnLooseLabelSetConnection();
+  void OnEstablishLabelSetConnection();
+
+  void ResetList();
+
+  mitk::LabelSetImage::ConstPointer m_LabelSetImage;
+  QListWidget* m_LabelList;
+};
+
+#endif
diff --git a/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUI.cpp
index a6f7763f5c..41c3151292 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUI.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUI.cpp
@@ -1,150 +1,199 @@
 /*============================================================================
 
 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 "QmitkWatershedToolGUI.h"
 
-#include "QmitkNewSegmentationDialog.h"
-#include "mitkProgressBar.h"
-
-#include <qapplication.h>
-#include <qlabel.h>
-#include <qlayout.h>
-#include <qpainter.h>
-#include <qpushbutton.h>
-#include <qslider.h>
+#include <QMessageBox>
 
 MITK_TOOL_GUI_MACRO(MITKSEGMENTATIONUI_EXPORT, QmitkWatershedToolGUI, "")
 
-QmitkWatershedToolGUI::QmitkWatershedToolGUI() : QmitkToolGUI(), m_SliderThreshold(nullptr), m_SliderLevel(nullptr)
+QmitkWatershedToolGUI::QmitkWatershedToolGUI() : QmitkToolGUI()
 {
-  // create the visible widgets
-  QGridLayout *layout = new QGridLayout(this);
-  this->setContentsMargins(0, 0, 0, 0);
-
-  QLabel *label = new QLabel("Threshold ", this);
-  QFont f = label->font();
-  f.setBold(false);
-  label->setFont(f);
-  layout->addWidget(label, 0, 0);
-
-  QLabel *label2 = new QLabel("Level ", this);
-  f = label2->font();
-  f.setBold(false);
-  label2->setFont(f);
-  layout->addWidget(label2, 2, 0);
-
-  m_ThresholdLabel = new QLabel(" 0.04", this);
-  f = m_ThresholdLabel->font();
-  f.setBold(false);
-  m_ThresholdLabel->setFont(f);
-  layout->addWidget(m_ThresholdLabel, 0, 1);
-
-  m_SliderThreshold = new QSlider(Qt::Horizontal, this);
-  m_SliderThreshold->setMinimum(0);
-  m_SliderThreshold->setMaximum(100);
-  m_SliderThreshold->setPageStep(1);
-  m_SliderThreshold->setValue(4);
-  connect(m_SliderThreshold, SIGNAL(valueChanged(int)), this, SLOT(OnSliderValueThresholdChanged(int)));
-  layout->addWidget(m_SliderThreshold, 1, 0, 1, 2);
-
-  m_LevelLabel = new QLabel(" 0.35", this);
-  f = m_LevelLabel->font();
-  f.setBold(false);
-  m_LevelLabel->setFont(f);
-  layout->addWidget(m_LevelLabel, 2, 1);
-
-  m_SliderLevel = new QSlider(Qt::Horizontal, this);
-  m_SliderLevel->setMinimum(0);
-  m_SliderLevel->setMaximum(100);
-  m_SliderLevel->setPageStep(1);
-  m_SliderLevel->setValue(35);
-  connect(m_SliderLevel, SIGNAL(valueChanged(int)), this, SLOT(OnSliderValueLevelChanged(int)));
-  layout->addWidget(m_SliderLevel, 3, 0, 1, 2);
-
-  QPushButton *okButton = new QPushButton("Run Segmentation", this);
-  connect(okButton, SIGNAL(clicked()), this, SLOT(OnCreateSegmentation()));
-  okButton->setFont(f);
-  layout->addWidget(okButton, 4, 0, 1, 2);
-
-  m_InformationLabel = new QLabel("", this);
-  f = m_InformationLabel->font();
-  f.setBold(false);
-  m_InformationLabel->setFont(f);
-  layout->addWidget(m_InformationLabel, 5, 0, 1, 2);
-
+  m_Controls.setupUi(this);
+
+  m_Controls.thresholdSlider->setMinimum(0);
+  //We set the threshold maximum to 0.5 to avoid crashes in the watershed filter
+  //see T27703 for more details.
+  m_Controls.thresholdSlider->setMaximum(0.5);
+  m_Controls.thresholdSlider->setValue(m_Threshold);
+  m_Controls.thresholdSlider->setPageStep(0.01);
+  m_Controls.thresholdSlider->setSingleStep(0.001);
+  m_Controls.thresholdSlider->setDecimals(4);
+
+  m_Controls.levelSlider->setMinimum(0);
+  m_Controls.levelSlider->setMaximum(1);
+  m_Controls.levelSlider->setValue(m_Level);
+  m_Controls.levelSlider->setPageStep(0.1);
+  m_Controls.levelSlider->setSingleStep(0.01);
+
+  connect(m_Controls.previewButton, SIGNAL(clicked()), this, SLOT(OnSettingsAccept()));
+  connect(m_Controls.m_selectionListWidget, &QmitkSimpleLabelSetListWidget::SelectedLabelsChanged, this, &QmitkWatershedToolGUI::OnRegionSelectionChanged);
+  connect(m_Controls.levelSlider, SIGNAL(valueChanged(double)), this, SLOT(OnLevelChanged(double)));
+  connect(m_Controls.thresholdSlider, SIGNAL(valueChanged(double)), this, SLOT(OnThresholdChanged(double)));
+  connect(m_Controls.m_ConfSegButton, SIGNAL(clicked()), this, SLOT(OnSegmentationRegionAccept()));
   connect(this, SIGNAL(NewToolAssociated(mitk::Tool *)), this, SLOT(OnNewToolAssociated(mitk::Tool *)));
 }
 
 QmitkWatershedToolGUI::~QmitkWatershedToolGUI()
 {
   if (m_WatershedTool.IsNotNull())
   {
-    // m_WatershedTool->SizeChanged -= mitk::MessageDelegate1<QmitkWatershedToolGUI, int>( this,
-    // &QmitkWatershedToolGUI::OnSizeChanged );
+    m_WatershedTool->CurrentlyBusy -=
+      mitk::MessageDelegate1<QmitkWatershedToolGUI, bool>(this, &QmitkWatershedToolGUI::BusyStateChanged);
+  }
+}
+
+void QmitkWatershedToolGUI::OnRegionSelectionChanged(const QmitkSimpleLabelSetListWidget::LabelVectorType& selectedLabels)
+{
+  if (m_WatershedTool.IsNotNull())
+  {
+    mitk::AutoMLSegmentationWithPreviewTool::SelectedLabelVectorType labelIDs;
+    for (const auto& label : selectedLabels)
+    {
+      labelIDs.push_back(label->GetValue());
+    }
+
+    m_WatershedTool->SetSelectedLabels(labelIDs);
+    m_WatershedTool->UpdatePreview();
+
+    m_Controls.m_ConfSegButton->setEnabled(!labelIDs.empty());
   }
 }
 
 void QmitkWatershedToolGUI::OnNewToolAssociated(mitk::Tool *tool)
 {
   if (m_WatershedTool.IsNotNull())
   {
-    // m_WatershedTool->SizeChanged -= mitk::MessageDelegate1<QmitkWatershedToolGUI, int>( this,
-    // &QmitkWatershedToolGUI::OnSizeChanged );
+    m_WatershedTool->CurrentlyBusy -=
+      mitk::MessageDelegate1<QmitkWatershedToolGUI, bool>(this, &QmitkWatershedToolGUI::BusyStateChanged);
   }
 
   m_WatershedTool = dynamic_cast<mitk::WatershedTool *>(tool);
-  OnSliderValueLevelChanged(35);
-  OnSliderValueThresholdChanged(4);
 
   if (m_WatershedTool.IsNotNull())
   {
-    //    m_WatershedTool->SizeChanged += mitk::MessageDelegate1<QmitkWatershedToolGUI, int>( this,
-    //    &QmitkWatershedToolGUI::OnSizeChanged );
+    m_WatershedTool->CurrentlyBusy +=
+      mitk::MessageDelegate1<QmitkWatershedToolGUI, bool>(this, &QmitkWatershedToolGUI::BusyStateChanged);
+
+    m_WatershedTool->SetLevel(m_Level);
+    m_WatershedTool->SetThreshold(m_Threshold);
+
+    m_WatershedTool->SetOverwriteExistingSegmentation(true);
+    m_WatershedTool->IsTimePointChangeAwareOff();
+    m_Controls.m_CheckProcessAll->setVisible(m_WatershedTool->GetTargetSegmentationNode()->GetData()->GetTimeSteps() > 1);
   }
 }
 
-void QmitkWatershedToolGUI::OnSliderValueThresholdChanged(int value)
+void QmitkWatershedToolGUI::OnSegmentationRegionAccept()
 {
+  QString segName = QString::fromStdString(m_WatershedTool->GetCurrentSegmentationName());
+
   if (m_WatershedTool.IsNotNull())
   {
-    double realValue = value / 100.;
-    m_WatershedTool->SetThreshold(realValue);
-    m_ThresholdLabel->setText(QString::number(realValue));
+    if (this->m_Controls.m_CheckCreateNew->isChecked())
+    {
+      m_WatershedTool->SetOverwriteExistingSegmentation(false);
+    }
+    else
+    {
+      m_WatershedTool->SetOverwriteExistingSegmentation(true);
+    }
+
+    m_WatershedTool->SetCreateAllTimeSteps(this->m_Controls.m_CheckProcessAll->isChecked());
+
+    this->m_Controls.m_ConfSegButton->setEnabled(false);
+    m_WatershedTool->ConfirmSegmentation();
   }
 }
 
-void QmitkWatershedToolGUI::OnSliderValueLevelChanged(int value)
+void QmitkWatershedToolGUI::OnSettingsAccept()
 {
   if (m_WatershedTool.IsNotNull())
   {
-    double realValue = value / 100.;
-    m_WatershedTool->SetLevel(realValue);
-    m_LevelLabel->setText(QString::number(realValue));
+    try
+    {
+      m_Threshold = m_Controls.thresholdSlider->value();
+      m_Level = m_Controls.levelSlider->value();
+      m_WatershedTool->SetThreshold(m_Threshold);
+      m_WatershedTool->SetLevel(m_Level);
+
+      m_WatershedTool->UpdatePreview();
+    }
+    catch (const std::exception& e)
+    {
+      this->setCursor(Qt::ArrowCursor);
+      std::stringstream stream;
+      stream << "Error while generation watershed segmentation. Reason: " << e.what();
+
+      QMessageBox* messageBox =
+        new QMessageBox(QMessageBox::Critical,
+          nullptr, stream.str().c_str());
+      messageBox->exec();
+      delete messageBox;
+      MITK_ERROR << stream.str();
+      return;
+    }
+    catch (...)
+    {
+      this->setCursor(Qt::ArrowCursor);
+      std::stringstream stream;
+      stream << "Unkown error occured while generation watershed segmentation.";
+
+      QMessageBox* messageBox =
+        new QMessageBox(QMessageBox::Critical,
+          nullptr, stream.str().c_str());
+      messageBox->exec();
+      delete messageBox;
+      MITK_ERROR << stream.str();
+      return;
+    }
+
+    m_Controls.m_selectionListWidget->SetLabelSetImage(m_WatershedTool->GetMLPreview());
+    m_WatershedTool->IsTimePointChangeAwareOn();
   }
 }
 
-void QmitkWatershedToolGUI::OnCreateSegmentation()
+void QmitkWatershedToolGUI::BusyStateChanged(bool value)
 {
-  QApplication::setOverrideCursor(Qt::BusyCursor);
-  m_InformationLabel->setText(QString("Please wait some time for computation..."));
-  m_InformationLabel->repaint();
-  QApplication::processEvents();
+  if (value)
+  {
+    QApplication::setOverrideCursor(QCursor(Qt::BusyCursor));
+  }
+  else
+  {
+    QApplication::restoreOverrideCursor();
+  }
 
-  m_WatershedTool->DoIt();
-  m_InformationLabel->setText(QString(""));
-  QApplication::setOverrideCursor(Qt::ArrowCursor);
+  m_Controls.levelSlider->setEnabled(!value);
+  m_Controls.thresholdSlider->setEnabled(!value);
+  m_Controls.m_ConfSegButton->setEnabled(!m_WatershedTool->GetSelectedLabels().empty() && !value);
+  m_Controls.m_CheckProcessAll->setEnabled(!value);
+  m_Controls.m_CheckCreateNew->setEnabled(!value);
+  m_Controls.previewButton->setEnabled(!value);
+}
 
-  for (int i = 0; i < 60; ++i)
+
+void QmitkWatershedToolGUI::OnLevelChanged(double value)
+{
+  if (m_WatershedTool.IsNotNull())
+  {
+    m_WatershedTool->SetLevel(value);
+  }
+}
+
+void QmitkWatershedToolGUI::OnThresholdChanged(double value)
+{
+  if (m_WatershedTool.IsNotNull())
   {
-    mitk::ProgressBar::GetInstance()->Progress();
+    m_WatershedTool->SetThreshold(value);
   }
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUI.h b/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUI.h
index 23c40cab24..c5b8bbe5f1 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUI.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUI.h
@@ -1,72 +1,71 @@
 /*============================================================================
 
 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 QmitkWatershedToolGUI_h_Included
 #define QmitkWatershedToolGUI_h_Included
 
 #include "QmitkToolGUI.h"
 #include "mitkWatershedTool.h"
-#include <MitkSegmentationUIExports.h>
 
-class QSlider;
-class QLabel;
-class QFrame;
+#include "ui_QmitkWatershedToolGUIControls.h"
+
+#include <MitkSegmentationUIExports.h>
 
 /**
   \ingroup org_mitk_gui_qt_interactivesegmentation_internal
   \brief GUI for mitk::WatershedTool.
   \sa mitk::WatershedTool
 
   This GUI shows two sliders to change the watershed parameters. It executes the watershed algorithm by clicking on the
   button.
 
 */
 class MITKSEGMENTATIONUI_EXPORT QmitkWatershedToolGUI : public QmitkToolGUI
 {
   Q_OBJECT
 
 public:
   mitkClassMacro(QmitkWatershedToolGUI, QmitkToolGUI);
   itkFactorylessNewMacro(Self);
   itkCloneMacro(Self);
 
-    protected slots :
+protected slots :
+
+  void OnNewToolAssociated(mitk::Tool *);
 
-    void OnNewToolAssociated(mitk::Tool *);
+  void OnSettingsAccept();
 
-  /** \brief Passes the chosen threshold value directly to the watershed tool */
-  void OnSliderValueThresholdChanged(int value);
-  /** \brief Passes the chosen level value directly to the watershed tool */
-  void OnSliderValueLevelChanged(int value);
-  /** \brief Starts segmentation algorithm in the watershed tool */
-  void OnCreateSegmentation();
+  void OnSegmentationRegionAccept();
+
+  void OnRegionSelectionChanged(const QmitkSimpleLabelSetListWidget::LabelVectorType& selectedLabels);
+
+  void OnLevelChanged(double value);
+  void OnThresholdChanged(double value);
 
 protected:
   QmitkWatershedToolGUI();
   ~QmitkWatershedToolGUI() override;
 
-  QSlider *m_SliderThreshold;
-  QSlider *m_SliderLevel;
-
-  /** \brief Label showing the current threshold value. */
-  QLabel *m_ThresholdLabel;
-  /** \brief Label showing the current level value. */
-  QLabel *m_LevelLabel;
-  /** \brief Label showing additional informations. */
-  QLabel *m_InformationLabel;
+  void BusyStateChanged(bool value) override;
 
-  QFrame *m_Frame;
+  //Recommendation from ITK is to have a threshold:level ration around 1:100
+  //we set Level a bit higher. This provokes more oversegmentation,
+  //but produces less objects in the first run and profits form the fact that
+  //decreasing level is quite fast in the filter.
+  double m_Level = 0.6;
+  double m_Threshold = 0.004;
 
+  Ui_QmitkWatershedToolGUIControls m_Controls;
   mitk::WatershedTool::Pointer m_WatershedTool;
 };
 
 #endif
diff --git a/Modules/SegmentationUI/Qmitk/QmitkOtsuToolWidgetControls.ui b/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUIControls.ui
similarity index 52%
copy from Modules/SegmentationUI/Qmitk/QmitkOtsuToolWidgetControls.ui
copy to Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUIControls.ui
index 27e1d87ff8..4c4931c08a 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkOtsuToolWidgetControls.ui
+++ b/Modules/SegmentationUI/Qmitk/QmitkWatershedToolGUIControls.ui
@@ -1,234 +1,160 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>QmitkOtsuToolWidgetControls</class>
- <widget class="QWidget" name="QmitkOtsuToolWidgetControls">
+ <class>QmitkWatershedToolGUIControls</class>
+ <widget class="QWidget" name="QmitkWatershedToolGUIControls">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>192</width>
-    <height>300</height>
+    <height>352</height>
    </rect>
   </property>
   <property name="sizePolicy">
    <sizepolicy hsizetype="Ignored" vsizetype="Minimum">
     <horstretch>0</horstretch>
     <verstretch>0</verstretch>
    </sizepolicy>
   </property>
   <property name="minimumSize">
    <size>
     <width>100</width>
     <height>0</height>
    </size>
   </property>
   <property name="maximumSize">
    <size>
     <width>100000</width>
     <height>100000</height>
    </size>
   </property>
   <property name="windowTitle">
    <string>QmitkOtsuToolWidget</string>
   </property>
-  <property name="toolTip">
-   <string>Move to adjust the segmentation</string>
-  </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <property name="sizeConstraint">
-      <enum>QLayout::SetNoConstraint</enum>
-     </property>
-     <item>
-      <widget class="QLabel" name="numberOfRegionsLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Ignored" vsizetype="Minimum">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
+    <layout class="QGridLayout" name="advancedSettingsLayout">
+     <item row="1" column="0">
+      <widget class="QLabel" name="levelLabel">
        <property name="text">
-        <string>Number of Regions:</string>
+        <string>Level:</string>
        </property>
       </widget>
      </item>
-     <item>
-      <widget class="QSpinBox" name="m_Spinbox">
+     <item row="0" column="0">
+      <widget class="QLabel" name="thresholdLabel">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
-       <property name="maximumSize">
-        <size>
-         <width>40</width>
-         <height>16777215</height>
-        </size>
-       </property>
-       <property name="minimum">
-        <number>2</number>
-       </property>
-       <property name="maximum">
-        <number>32</number>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <widget class="ctkExpandButton" name="advancedSettingsButton">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="minimumSize">
-      <size>
-       <width>0</width>
-       <height>32</height>
-      </size>
-     </property>
-     <property name="text">
-      <string>Advanced settings</string>
-     </property>
-     <property name="toolButtonStyle">
-      <enum>Qt::ToolButtonTextBesideIcon</enum>
-     </property>
-     <property name="mirrorOnExpand" stdset="0">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QGridLayout" name="advancedSettingsLayout">
-     <item row="0" column="0">
-      <widget class="QCheckBox" name="m_ValleyCheckbox">
        <property name="text">
-        <string>Use Valley Emphasis</string>
+        <string>Threshold:</string>
        </property>
       </widget>
      </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="binLabel">
-       <property name="text">
-        <string>Number of Histogram Bins:</string>
-       </property>
-      </widget>
+     <item row="0" column="1">
+      <widget class="ctkSliderWidget" name="thresholdSlider" native="true"/>
      </item>
      <item row="1" column="1">
-      <widget class="QSpinBox" name="m_BinsSpinBox">
-       <property name="minimum">
-        <number>2</number>
-       </property>
-       <property name="maximum">
-        <number>4096</number>
-       </property>
-       <property name="value">
-        <number>128</number>
-       </property>
-      </widget>
+      <widget class="ctkSliderWidget" name="levelSlider" native="true"/>
      </item>
     </layout>
    </item>
    <item>
-    <widget class="QListWidget" name="m_selectionListWidget">
+    <widget class="QmitkSimpleLabelSetListWidget" name="m_selectionListWidget" native="true">
      <property name="sizePolicy">
-      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+      <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="maximumSize">
       <size>
        <width>10000000</width>
-       <height>100</height>
+       <height>10000000</height>
       </size>
      </property>
-     <property name="autoScrollMargin">
-      <number>0</number>
-     </property>
-     <property name="selectionMode">
-      <enum>QAbstractItemView::MultiSelection</enum>
-     </property>
-     <property name="resizeMode">
-      <enum>QListView::Adjust</enum>
-     </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="previewButton">
      <property name="sizePolicy">
-      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+      <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="maximumSize">
       <size>
        <width>100000</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="text">
       <string>Preview</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="m_ConfSegButton">
      <property name="enabled">
       <bool>false</bool>
      </property>
      <property name="sizePolicy">
-      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+      <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="maximumSize">
       <size>
        <width>100000</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="text">
       <string>Confirm Segmentation</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QCheckBox" name="m_CheckProcessAll">
      <property name="toolTip">
       <string>Process/overwrite all time steps of the dynamic segmentation and not just the currently visible time step.</string>
      </property>
      <property name="text">
       <string>Process all time steps</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QCheckBox" name="m_CheckCreateNew">
      <property name="toolTip">
       <string>Add the confirmed segmentation as a new segmentation instead of overwriting the currently selected.</string>
      </property>
      <property name="text">
       <string>Create as new segmentation</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>
   <customwidget>
-   <class>ctkExpandButton</class>
-   <extends>QToolButton</extends>
-   <header>ctkExpandButton.h</header>
+   <class>QmitkSimpleLabelSetListWidget</class>
+   <extends>QWidget</extends>
+   <header>QmitkSimpleLabelSetListWidget.h</header>
+  </customwidget>
+  <customwidget>
+   <class>ctkSliderWidget</class>
+   <extends>QWidget</extends>
+   <header location="global">ctkSliderWidget.h</header>
+   <container>1</container>
   </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff --git a/Modules/SegmentationUI/files.cmake b/Modules/SegmentationUI/files.cmake
index a7ba3f718d..d84231e8a4 100644
--- a/Modules/SegmentationUI/files.cmake
+++ b/Modules/SegmentationUI/files.cmake
@@ -1,81 +1,84 @@
 set( CPP_FILES
 Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp
 Qmitk/QmitkBinaryThresholdToolGUI.cpp
 Qmitk/QmitkBinaryThresholdULToolGUI.cpp
 Qmitk/QmitkCalculateGrayValueStatisticsToolGUI.cpp
 Qmitk/QmitkConfirmSegmentationDialog.cpp
 Qmitk/QmitkCopyToClipBoardDialog.cpp
 Qmitk/QmitkDrawPaintbrushToolGUI.cpp
 Qmitk/QmitkErasePaintbrushToolGUI.cpp
 Qmitk/QmitkFastMarchingTool3DGUI.cpp
 Qmitk/QmitkFastMarchingToolGUI.cpp
 
 Qmitk/QmitkLiveWireTool2DGUI.cpp
 Qmitk/QmitkNewSegmentationDialog.cpp
 Qmitk/QmitkOtsuTool3DGUI.cpp
 Qmitk/QmitkPaintbrushToolGUI.cpp
 Qmitk/QmitkPickingToolGUI.cpp
 Qmitk/QmitkPixelManipulationToolGUI.cpp
 Qmitk/QmitkSlicesInterpolator.cpp
 Qmitk/QmitkToolGUI.cpp
 Qmitk/QmitkToolGUIArea.cpp
 Qmitk/QmitkToolSelectionBox.cpp
 Qmitk/QmitkWatershedToolGUI.cpp
 #Added from ML
 Qmitk/QmitkLabelSetWidget.cpp
 Qmitk/QmitkSurfaceStampWidget.cpp
 Qmitk/QmitkMaskStampWidget.cpp
 Qmitk/QmitkSliceBasedInterpolatorWidget.cpp
 Qmitk/QmitkSurfaceBasedInterpolatorWidget.cpp
 Qmitk/QmitkSearchLabelDialog.cpp
+Qmitk/QmitkSimpleLabelSetListWidget.cpp
 )
 
 set(MOC_H_FILES
 Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h
 Qmitk/QmitkBinaryThresholdToolGUI.h
 Qmitk/QmitkBinaryThresholdULToolGUI.h
 Qmitk/QmitkCalculateGrayValueStatisticsToolGUI.h
 Qmitk/QmitkConfirmSegmentationDialog.h
 Qmitk/QmitkCopyToClipBoardDialog.h
 Qmitk/QmitkDrawPaintbrushToolGUI.h
 Qmitk/QmitkErasePaintbrushToolGUI.h
 Qmitk/QmitkFastMarchingTool3DGUI.h
 Qmitk/QmitkFastMarchingToolGUI.h
 Qmitk/QmitkLiveWireTool2DGUI.h
 Qmitk/QmitkNewSegmentationDialog.h
 Qmitk/QmitkOtsuTool3DGUI.h
 Qmitk/QmitkPaintbrushToolGUI.h
 Qmitk/QmitkPickingToolGUI.h
 Qmitk/QmitkPixelManipulationToolGUI.h
 Qmitk/QmitkSlicesInterpolator.h
 Qmitk/QmitkToolGUI.h
 Qmitk/QmitkToolGUIArea.h
 Qmitk/QmitkToolSelectionBox.h
 Qmitk/QmitkWatershedToolGUI.h
 #Added from ML
 Qmitk/QmitkLabelSetWidget.h
 Qmitk/QmitkSurfaceStampWidget.h
 Qmitk/QmitkMaskStampWidget.h
 Qmitk/QmitkSliceBasedInterpolatorWidget.h
 Qmitk/QmitkSurfaceBasedInterpolatorWidget.h
 Qmitk/QmitkSearchLabelDialog.h
+Qmitk/QmitkSimpleLabelSetListWidget.h
 )
 
 set(UI_FILES
 Qmitk/QmitkAdaptiveRegionGrowingToolGUIControls.ui
 Qmitk/QmitkConfirmSegmentationDialog.ui
 Qmitk/QmitkOtsuToolWidgetControls.ui
 Qmitk/QmitkPickingToolGUIControls.ui
 Qmitk/QmitkLiveWireTool2DGUIControls.ui
+Qmitk/QmitkWatershedToolGUIControls.ui
 #Added from ML
 Qmitk/QmitkLabelSetWidgetControls.ui
 Qmitk/QmitkSurfaceStampWidgetGUIControls.ui
 Qmitk/QmitkMaskStampWidgetGUIControls.ui
 Qmitk/QmitkSliceBasedInterpolatorWidgetGUIControls.ui
 Qmitk/QmitkSurfaceBasedInterpolatorWidgetGUIControls.ui
 Qmitk/QmitkSearchLabelDialogGUI.ui
 )
 
 set(QRC_FILES
   resources/SegmentationUI.qrc
 )
diff --git a/Plugins/org.blueberry.ui.qt.log/documentation/UserManual/blueberrylogview.dox b/Plugins/org.blueberry.ui.qt.log/documentation/UserManual/blueberrylogview.dox
index 34290412a6..4f4fa8fde2 100644
--- a/Plugins/org.blueberry.ui.qt.log/documentation/UserManual/blueberrylogview.dox
+++ b/Plugins/org.blueberry.ui.qt.log/documentation/UserManual/blueberrylogview.dox
@@ -1,16 +1,16 @@
 /**
-\page org_blueberry_ui_qt_log The Logging Plugin
+\page org_blueberry_views_logview The Logging Plugin
 
 \imageMacro{logging.svg,"Icon of the Logging Plugin",2.00}
 
-This plug-in records all logging output of events and progress as specified in the source code with time of occurence, level of importance (Info, Warning, Error, Fatal, Debug), the message given and where it happens. The logging starts once the plug-is started. A screenshot of the provided Logging view is shown next.
+This plug-in records all logging output of events and progress as specified in the source code with time of occurrence, level of importance (Info, Warning, Error, Fatal, Debug), the message given and the origin of the message (source code section).
 
-\imageMacro{LogView.png,"Screenshot of the Logging Module",16.00}
+\imageMacro{LogView.png,"Screenshot of the Logging Plugin",16.00}
 
-There are different features available in the view. The "Filter" text field allows for searching all log events containing a certain substring. Using the button "Copy to clipboard" on the bottom right you can copy the current content of the logging view to your clipboard. This enables you to insert the logging information to any text processing application.
+There are different features available in the view. The 'Filter' text field provides the possibility to search for all log events containing a certain substring. The 'Copy to clipboard' button allows you to copy the current content of the logging view to your clipboard. This enables you to insert the logging information to any text processing application.
 
-You can also show more information on every logging message by activating the two checkboxes. In the simple view, leaving both checkboxes unchecked, you'll see logging messages and logging levels. A brief description of the logging levels can be found in the \ref LoggingPage "logging concept documentation". The checkbox "Categories" adds a column for the category. The checkbox "Advanced Fields" shows method, filename and linenumber where the logging message was emitted as well as the running time of the application. The next figure shows all information which can be shown in the Logging Module.
+In the simple logging view, you'll see logging messages and logging levels. A brief description of the logging levels can be found in the \ref LoggingPage "logging concept documentation". With two checkboxes more information on every logging message can be activated. The checkbox 'categories' adds a column for the category. The checkbox 'advanced fields' additionally displays the time from application start to the log message entry and the function, filename and line number of the logging message origin.
 
 \imageMacro{LogViewExplain.png,"Details on the Vizualized Logging Information",16.00}
 
 */
diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h
index 3c4571eb93..ed0edc443b 100644
--- a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h
+++ b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h
@@ -1,79 +1,94 @@
 /*============================================================================
 
 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 QMITK_SINGLE_NODE_SELECTION_WIDGET_H
 #define QMITK_SINGLE_NODE_SELECTION_WIDGET_H
 
 #include <mitkDataStorage.h>
 #include <mitkWeakPointer.h>
 #include <mitkNodePredicateBase.h>
 
 #include "org_mitk_gui_qt_common_Export.h"
 
 #include "ui_QmitkSingleNodeSelectionWidget.h"
 
 #include <QmitkAbstractNodeSelectionWidget.h>
 #include <QmitkNodeSelectionButton.h>
 
 class QmitkAbstractDataStorageModel;
 
 /**
 * @class QmitkSingleNodeSelectionWidget
 * @brief Widget that represents a node selection of (max) one node. It acts like a button. Clicking on it
 *        allows to change the selection.
+*
+* @remark This class provides a public function 'SetAutoSelectNewNodes' that can be used to enable
+*         the auto selection mode (default is false).
+*         The user of this class calling this function has to make sure that the base-class Q_SIGNAL
+*         'CurrentSelectionChanged', which will be emitted by this function, is already
+*         connected to a receiving slot, if the initial valid auto selection should not get lost.
 */
 class MITK_QT_COMMON QmitkSingleNodeSelectionWidget : public QmitkAbstractNodeSelectionWidget
 {
   Q_OBJECT
 
 public:
   explicit QmitkSingleNodeSelectionWidget(QWidget* parent = nullptr);
 
   mitk::DataNode::Pointer GetSelectedNode() const;
   bool GetAutoSelectNewNodes() const;
 
   using NodeList = QmitkAbstractNodeSelectionWidget::NodeList;
 
 public Q_SLOTS:
   void SetCurrentSelectedNode(mitk::DataNode* selectedNode);
 
-  /** Sets the auto selection mode (Default is false).
-  If auto select is true and the following conditions are fullfilled, the widget will
-  select a node automatically from the data storage:
-  - a data storage is set
-  - data storage contains at least one node that matches the given predicate
-  - no selection is set.*/
+  /**
+  * Sets the auto selection mode (default is false).
+  * If auto select is true and the following conditions are fullfilled, the widget will
+  * select a node automatically from the data storage:
+  *  - a data storage is set
+  *  - data storage contains at least one node that matches the given predicate
+  *  - no selection is set
+  *
+  * @remark Enabling the auto selection mode by calling 'SetAutoSelectNewNodes(true)'
+  *         will directly emit a 'QmitkSingleNodeSelectionWidget::CurrentSelectionChanged' Q_SIGNAL
+  *         if a valid auto selection was made.
+  *         If this initial emission should not get lost, auto selection mode needs to be enabled after this
+  *         selection widget has been connected via the 'QmitkSingleNodeSelectionWidget::CurrentSelectionChanged'
+  *         Q_SIGNAL to a receiving function.
+  */
   void SetAutoSelectNewNodes(bool autoSelect);
 
 protected Q_SLOTS:
   virtual void OnClearSelection();
 
 protected:
   void ReviseSelectionChanged(const NodeList& oldInternalSelection, NodeList& newInternalSelection) override;
 
   bool eventFilter(QObject *obj, QEvent *ev) override;
   void EditSelection();
   void UpdateInfo() override;
 
   void OnNodeAddedToStorage(const mitk::DataNode* node) override;
 
   /** Helper function that gets a suitable auto selected node from the datastorage that fits to the predicate settings.
    @param ignoreNodes You may pass a list of nodes that must not be choosen as auto selected node. */
   mitk::DataNode::Pointer DetermineAutoSelectNode(const NodeList& ignoreNodes = {});
 
   /** See documentation of SetAutoSelectNewNodes for details*/
   bool m_AutoSelectNewNodes;
 
   Ui_QmitkSingleNodeSelectionWidget m_Controls;
 };
 
 #endif // QMITK_SINGLE_NODE_SELECTION_WIDGET_H
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
index 299883d318..d608a7078f 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp
@@ -1,903 +1,907 @@
 /*============================================================================
 
 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 <QObject>
 
 #include "mitkProperties.h"
 #include "mitkSegTool2D.h"
 #include "mitkStatusBar.h"
 
 #include "QmitkNewSegmentationDialog.h"
 #include <QmitkSegmentationOrganNamesHandling.cpp>
 
 #include <QMessageBox>
 
 #include <berryIWorkbenchPage.h>
 
 #include "QmitkSegmentationView.h"
 
 #include <mitkSurfaceToImageFilter.h>
 
 #include "mitkVtkResliceInterpolationProperty.h"
 
 #include "mitkApplicationCursor.h"
 #include "mitkSegmentationObjectFactory.h"
 #include "mitkPluginActivator.h"
 #include "mitkCameraController.h"
 #include "mitkLabelSetImage.h"
 #include "mitkImageTimeSelector.h"
 #include "mitkNodePredicateSubGeometry.h"
 
 #include <QmitkRenderWindow.h>
 
 #include "usModuleResource.h"
 #include "usModuleResourceStream.h"
 
 //micro service to get the ToolManager instance
 #include "mitkToolManagerProvider.h"
 
 #include <mitkWorkbenchUtil.h>
 #include <regex>
 
 const std::string QmitkSegmentationView::VIEW_ID = "org.mitk.views.segmentation";
 
 QmitkSegmentationView::QmitkSegmentationView()
   : m_Parent(nullptr)
   , m_Controls(nullptr)
   , m_RenderWindowPart(nullptr)
   , m_MouseCursorSet(false)
   , m_DataSelectionChanged(false)
 {
   mitk::TNodePredicateDataType<mitk::Image>::Pointer isImage = mitk::TNodePredicateDataType<mitk::Image>::New();
   mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
   mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
   mitk::NodePredicateDataType::Pointer isOdf = mitk::NodePredicateDataType::New("OdfImage");
   auto isSegment = mitk::NodePredicateDataType::New("Segment");
 
   mitk::NodePredicateOr::Pointer validImages = mitk::NodePredicateOr::New();
   validImages->AddPredicate(mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isSegment)));
   validImages->AddPredicate(isDwi);
   validImages->AddPredicate(isDti);
   validImages->AddPredicate(isOdf);
 
   m_IsNotAHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)));
 
   m_IsOfTypeImagePredicate = mitk::NodePredicateAnd::New(validImages, m_IsNotAHelperObject);
 
   mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true));
   mitk::NodePredicateNot::Pointer isNotBinaryPredicate = mitk::NodePredicateNot::New(isBinaryPredicate);
 
   mitk::NodePredicateAnd::Pointer isABinaryImagePredicate = mitk::NodePredicateAnd::New(m_IsOfTypeImagePredicate, isBinaryPredicate);
   mitk::NodePredicateAnd::Pointer isNotABinaryImagePredicate = mitk::NodePredicateAnd::New(m_IsOfTypeImagePredicate, isNotBinaryPredicate);
 
-  m_IsASegmentationImagePredicate = mitk::NodePredicateOr::New(isABinaryImagePredicate, mitk::TNodePredicateDataType<mitk::LabelSetImage>::New());
-  m_IsAPatientImagePredicate = mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, mitk::NodePredicateNot::New(mitk::TNodePredicateDataType<mitk::LabelSetImage>::New()));
+  auto isMLImageType = mitk::TNodePredicateDataType<mitk::LabelSetImage>::New();
+  mitk::NodePredicateAnd::Pointer isAMLImagePredicate = mitk::NodePredicateAnd::New(isMLImageType, m_IsNotAHelperObject);
+  mitk::NodePredicateAnd::Pointer isNotAMLImagePredicate = mitk::NodePredicateAnd::New(mitk::NodePredicateNot::New(isMLImageType), m_IsNotAHelperObject);
+
+  m_IsASegmentationImagePredicate = mitk::NodePredicateOr::New(isABinaryImagePredicate, isAMLImagePredicate);
+  m_IsAPatientImagePredicate = mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, isNotAMLImagePredicate);
 }
 
 QmitkSegmentationView::~QmitkSegmentationView()
 {
   if (m_Controls)
   {
     SetToolSelectionBoxesEnabled(false);
     // deactivate all tools
     mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1);
 
     // removing all observers
     for (NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter)
     {
       (*dataIter).first->GetProperty("visible")->RemoveObserver((*dataIter).second);
     }
     m_WorkingDataObserverTags.clear();
 
     mitk::RenderingManager::GetInstance()->RemoveObserver(m_RenderingManagerObserverTag);
 
     ctkPluginContext* context = mitk::PluginActivator::getContext();
     ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>();
     mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef);
     service->RemoveAllPlanePositions();
     context->ungetService(ppmRef);
     SetToolManagerSelection(nullptr, nullptr);
   }
 
   delete m_Controls;
 }
 
 void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes)
 {
    if (!nodes) return;
 
    mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
    if (!toolManager) return;
    for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter)
    {
       this->FireNodeSelected( *iter );
       // only last iteration meaningful, multiple generated objects are not taken into account here
    }
 }
 
 void QmitkSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
 {
   if (m_RenderWindowPart != renderWindowPart)
   {
     m_RenderWindowPart = renderWindowPart;
   }
 
   if (m_Parent)
   {
     m_Parent->setEnabled(true);
   }
 
   // tell the interpolation about tool manager, data storage and render window part
   if (m_Controls)
   {
     mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
     m_Controls->m_SlicesInterpolator->SetDataStorage(this->GetDataStorage());
     QList<mitk::SliceNavigationController*> controllers;
     controllers.push_back(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController());
     controllers.push_back(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController());
     controllers.push_back(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController());
     m_Controls->m_SlicesInterpolator->Initialize(toolManager, controllers);
   }
 }
 
 void QmitkSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/)
 {
   m_RenderWindowPart = nullptr;
   if (m_Parent)
   {
     m_Parent->setEnabled(false);
   }
 }
 
 void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs)
 {
    if (m_Controls != nullptr)
    {
       bool slimView = prefs->GetBool("slim view", false);
       m_Controls->m_ManualToolSelectionBox2D->SetShowNames(!slimView);
       m_Controls->m_ManualToolSelectionBox3D->SetShowNames(!slimView);
       m_Controls->btnNewSegmentation->setToolButtonStyle(slimView
         ? Qt::ToolButtonIconOnly
         : Qt::ToolButtonTextOnly);
    }
 
    auto autoSelectionEnabled = prefs->GetBool("auto selection", true);
    m_Controls->patImageSelector->SetAutoSelectNewNodes(autoSelectionEnabled);
    m_Controls->segImageSelector->SetAutoSelectNewNodes(autoSelectionEnabled);
    this->ForceDisplayPreferencesUponAllImages();
 }
 
 void QmitkSegmentationView::CreateNewSegmentation()
 {
    mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0);
    if (node.IsNotNull())
    {
      mitk::Image::ConstPointer referenceImage = dynamic_cast<mitk::Image*>(node->GetData());
      if (referenceImage.IsNotNull())
      {
        if (referenceImage->GetDimension() > 1)
        {
          // ask about the name and organ type of the new segmentation
          QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog(m_Parent); // needs a QWidget as parent, "this" is not QWidget
          QStringList organColors = mitk::OrganNamesHandling::GetDefaultOrganColorString();;
 
          dialog->SetSuggestionList(organColors);
 
          int dialogReturnValue = dialog->exec();
          if (dialogReturnValue == QDialog::Rejected)
          {
            // user clicked cancel or pressed Esc or something similar
            return;
          }
 
          const auto currentTimePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
          unsigned int imageTimeStep = 0;
          if (referenceImage->GetTimeGeometry()->IsValidTimePoint(currentTimePoint))
          {
            imageTimeStep = referenceImage->GetTimeGeometry()->TimePointToTimeStep(currentTimePoint);
          }
 
          auto segTemplateImage = referenceImage;
          if (referenceImage->GetDimension() > 3)
          {
            auto result = QMessageBox::question(m_Parent, tr("Generate a static mask?"),tr("The selected image has multiple time steps. You can either generate a simple/static masks resembling the geometry of the first timestep of the image. Or you can generate a dynamic mask that equals the selected image in geometry and number of timesteps; thus a dynamic mask can change over time (e.g. according to the image)."), tr("Yes, generate a static mask"), tr("No, generate a dynamic mask"), QString(), 0,0);
            if (result == 0)
            {
              auto selector = mitk::ImageTimeSelector::New();
              selector->SetInput(referenceImage);
              selector->SetTimeNr(0);
              selector->Update();
 
              const auto refTimeGeometry = referenceImage->GetTimeGeometry();
              auto newTimeGeometry = mitk::ProportionalTimeGeometry::New();
              newTimeGeometry->SetFirstTimePoint(refTimeGeometry->GetMinimumTimePoint());
              newTimeGeometry->SetStepDuration(refTimeGeometry->GetMaximumTimePoint() - refTimeGeometry->GetMinimumTimePoint());
 
              mitk::Image::Pointer newImage = selector->GetOutput();
              newTimeGeometry->SetTimeStepGeometry(referenceImage->GetGeometry(imageTimeStep), 0);
              newImage->SetTimeGeometry(newTimeGeometry);
              segTemplateImage = newImage;
            }
          }
 
          // ask the user about an organ type and name, add this information to the image's (!) propertylist
          // create a new image of the same dimensions and smallest possible pixel type
          mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
          mitk::Tool* firstTool = toolManager->GetToolById(0);
          if (firstTool)
          {
            try
            {
              std::string newNodeName = dialog->GetSegmentationName().toStdString();
              if (newNodeName.empty())
              {
                newNodeName = "no_name";
              }
 
              mitk::DataNode::Pointer emptySegmentation = firstTool->CreateEmptySegmentationNode(segTemplateImage, newNodeName, dialog->GetColor());
              // initialize showVolume to false to prevent recalculating the volume while working on the segmentation
              emptySegmentation->SetProperty("showVolume", mitk::BoolProperty::New(false));
              if (!emptySegmentation)
              {
                return; // could be aborted by user
              }
 
              mitk::OrganNamesHandling::UpdateOrganList(organColors, dialog->GetSegmentationName(), dialog->GetColor());
 
              // escape ';' here (replace by '\;'), see longer comment above
              QString stringForStorage = organColors.replaceInStrings(";", "\\;").join(";");
              MITK_DEBUG << "Will store: " << stringForStorage;
              this->GetPreferences()->Put("Organ-Color-List", stringForStorage);
              this->GetPreferences()->Flush();
 
              if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0))
              {
                mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)->SetSelected(false);
              }
              emptySegmentation->SetSelected(true);
              this->GetDataStorage()->Add(emptySegmentation, node); // add as a child, because the segmentation "derives" from the original
 
              m_Controls->segImageSelector->SetCurrentSelectedNode(emptySegmentation);
              mitk::RenderingManager::GetInstance()->InitializeViews(referenceImage->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
              mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime()->SetPos(imageTimeStep);
            }
            catch (const std::bad_alloc&)
            {
              QMessageBox::warning(nullptr, tr("Create new segmentation"), tr("Could not allocate memory for new segmentation"));
            }
          }
        }
        else
        {
          QMessageBox::information(nullptr, tr("Segmentation"), tr("Segmentation is currently not supported for 2D images"));
        }
      }
    }
    else
    {
      MITK_ERROR << "'Create new segmentation' button should never be clickable unless a patient image is selected...";
    }
 }
 
 void QmitkSegmentationView::OnVisiblePropertyChanged()
 {
    this->CheckRenderingState();
 }
 
 void QmitkSegmentationView::NodeAdded(const mitk::DataNode *node)
 {
   if (!m_IsASegmentationImagePredicate->CheckNode(node))
   {
     return;
   }
 
   itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command = itk::SimpleMemberCommand<QmitkSegmentationView>::New();
   command->SetCallbackFunction(this, &QmitkSegmentationView::OnVisiblePropertyChanged);
   m_WorkingDataObserverTags.insert(std::pair<mitk::DataNode*, unsigned long>(const_cast<mitk::DataNode*>(node), node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command)));
 
   ApplyDisplayOptions(const_cast<mitk::DataNode*>(node));
 }
 
 void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node)
 {
   if (m_IsASegmentationImagePredicate->CheckNode(node))
   {
     //First of all remove all possible contour markers of the segmentation
     mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations(node, mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true)));
 
     ctkPluginContext* context = mitk::PluginActivator::getContext();
     ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>();
     mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef);
 
     for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it)
     {
       std::string nodeName = node->GetName();
       unsigned int t = nodeName.find_last_of(" ");
       unsigned int id = atof(nodeName.substr(t + 1).c_str()) - 1;
 
       service->RemovePlanePosition(id);
 
       this->GetDataStorage()->Remove(it->Value());
     }
 
     context->ungetService(ppmRef);
     service = nullptr;
 
     if ((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) && m_Controls->patImageSelector->GetSelectedNode().IsNotNull())
     {
       this->SetToolManagerSelection(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0), nullptr);
       this->UpdateWarningLabel(tr("Select or create a segmentation"));
     }
 
     mitk::Image* image = dynamic_cast<mitk::Image*>(node->GetData());
     mitk::SurfaceInterpolationController::GetInstance()->RemoveInterpolationSession(image);
   }
 
   mitk::DataNode* tempNode = const_cast<mitk::DataNode*>(node);
   //Remove observer if one was registered
   auto finding = m_WorkingDataObserverTags.find(tempNode);
   if (finding != m_WorkingDataObserverTags.end())
   {
     node->GetProperty("visible")->RemoveObserver(m_WorkingDataObserverTags[tempNode]);
     m_WorkingDataObserverTags.erase(tempNode);
   }
 }
 
 void QmitkSegmentationView::OnPatientSelectionChanged(QList<mitk::DataNode::Pointer> nodes)
 {
    if(! nodes.empty())
    {
       this->UpdateWarningLabel("");
       auto node = nodes.first();
 
       auto segPredicate = mitk::NodePredicateAnd::New(m_IsASegmentationImagePredicate.GetPointer(), mitk::NodePredicateSubGeometry::New(node->GetData()->GetGeometry()));
 
       m_Controls->segImageSelector->SetNodePredicate(segPredicate);
 
       mitk::DataNode* segNode = m_Controls->segImageSelector->GetSelectedNode();
       this->SetToolManagerSelection(node, segNode);
       if (segNode)
       {
         //Doing this we can assure that the segmentation is always visible if the segmentation and the patient image are
         //loaded separately
         int layer(10);
         node->GetIntProperty("layer", layer);
         layer++;
         segNode->SetProperty("layer", mitk::IntProperty::New(layer));
         this->CheckRenderingState();
       }
       else
       {
          this->SetToolSelectionBoxesEnabled( false );
          this->UpdateWarningLabel(tr("Select or create a segmentation"));
       }
    }
    else
    {
      m_Controls->segImageSelector->SetNodePredicate(m_IsASegmentationImagePredicate);
      this->UpdateWarningLabel(tr("Please select an image!"));
      this->SetToolSelectionBoxesEnabled( false );
    }
 }
 
 void QmitkSegmentationView::OnSegmentationSelectionChanged(QList<mitk::DataNode::Pointer> nodes)
 {
    if (nodes.empty())
    {
       this->UpdateWarningLabel(tr("Select or create a segmentation"));
       this->SetToolSelectionBoxesEnabled( false );
       return;
    }
 
    auto refNode = m_Controls->patImageSelector->GetSelectedNode();
    auto segNode = nodes.front();
 
    if (!refNode)
    {
      this->UpdateWarningLabel(tr("Please select the matching patient image!"));
      this->SetToolSelectionBoxesEnabled(false);
      this->SetToolManagerSelection(nullptr, segNode);
      return;
    }
 
    this->CheckRenderingState();
    if ( m_Controls->lblSegmentationWarnings->isVisible()) // "this->CheckRenderingState()" caused a warning. we do not need to go any further
       return;
 
    this->SetToolManagerSelection(refNode, segNode);
 
    if (segNode)
    {
      //Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are
      //loaded separately
      int layer(10);
      refNode->GetIntProperty("layer", layer);
      layer++;
      segNode->SetProperty("layer", mitk::IntProperty::New(layer));
    }
    else
    {
      this->SetToolSelectionBoxesEnabled(false);
      this->UpdateWarningLabel(tr("Select or create a segmentation"));
    }
 
    mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
    if (!renderWindowPart || !segNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()))
    {
      this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!"));
      this->SetToolSelectionBoxesEnabled( false );
    }
 }
 
 void QmitkSegmentationView::OnShowMarkerNodes (bool state)
 {
    mitk::SegTool2D::Pointer manualSegmentationTool;
 
    unsigned int numberOfExistingTools = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetTools().size();
 
    for(unsigned int i = 0; i < numberOfExistingTools; i++)
    {
       manualSegmentationTool = dynamic_cast<mitk::SegTool2D*>(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetToolById(i));
 
       if (manualSegmentationTool)
       {
          if(state == true)
          {
             manualSegmentationTool->SetShowMarkerNodes( true );
          }
          else
          {
             manualSegmentationTool->SetShowMarkerNodes( false );
          }
       }
    }
 }
 
 void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node)
 {
    QmitkRenderWindow* selectedRenderWindow = nullptr;
    QmitkRenderWindow* axialRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("axial");
    QmitkRenderWindow* sagittalRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("sagittal");
    QmitkRenderWindow* coronalRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("coronal");
    QmitkRenderWindow* _3DRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("3d");
    bool PlanarFigureInitializedWindow = false;
 
    // find initialized renderwindow
    if (node->GetBoolProperty("PlanarFigureInitializedWindow",
       PlanarFigureInitializedWindow, axialRenderWindow->GetRenderer()))
    {
       selectedRenderWindow = axialRenderWindow;
    }
    if (!selectedRenderWindow && node->GetBoolProperty(
       "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
       sagittalRenderWindow->GetRenderer()))
    {
       selectedRenderWindow = sagittalRenderWindow;
    }
    if (!selectedRenderWindow && node->GetBoolProperty(
       "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
       coronalRenderWindow->GetRenderer()))
    {
       selectedRenderWindow = coronalRenderWindow;
    }
    if (!selectedRenderWindow && node->GetBoolProperty(
       "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
       _3DRenderWindow->GetRenderer()))
    {
       selectedRenderWindow = _3DRenderWindow;
    }
 
    // make node visible
    if (selectedRenderWindow)
    {
       std::string nodeName = node->GetName();
       unsigned int t = nodeName.find_last_of(" ");
       unsigned int id = atof(nodeName.substr(t+1).c_str())-1;
 
       {
          ctkPluginContext* context = mitk::PluginActivator::getContext();
          ctkServiceReference ppmRef = context->getServiceReference<mitk::PlanePositionManagerService>();
          mitk::PlanePositionManagerService* service = context->getService<mitk::PlanePositionManagerService>(ppmRef);
          selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id));
          context->ungetService(ppmRef);
       }
 
       selectedRenderWindow->GetRenderer()->GetCameraController()->Fit();
       mitk::RenderingManager::GetInstance()->RequestUpdateAll();
    }
 }
 
 void QmitkSegmentationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer> &nodes)
 {
   if (nodes.size() != 0)
   {
     std::string markerName = "Position";
     unsigned int numberOfNodes = nodes.size();
     std::string nodeName = nodes.at(0)->GetName();
     if ((numberOfNodes == 1) && (nodeName.find(markerName) == 0))
     {
       this->OnContourMarkerSelected(nodes.at(0));
       return;
     }
   }
 }
 
 void QmitkSegmentationView::OnTabWidgetChanged(int id)
 {
    //always disable tools on tab changed
    mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1);
 
    //2D Tab ID = 0
    //3D Tab ID = 1
    if (id == 0)
    {
       //Hide 3D selection box, show 2D selection box
       m_Controls->m_ManualToolSelectionBox3D->hide();
       m_Controls->m_ManualToolSelectionBox2D->show();
       //Deactivate possible active tool
 
       //TODO Remove possible visible interpolations -> Maybe changes in SlicesInterpolator
    }
    else
    {
       //Hide 3D selection box, show 2D selection box
       m_Controls->m_ManualToolSelectionBox2D->hide();
       m_Controls->m_ManualToolSelectionBox3D->show();
       //Deactivate possible active tool
    }
 }
 
 void QmitkSegmentationView::SetToolManagerSelection(mitk::DataNode* referenceData, mitk::DataNode* workingData)
 {
   // called as a result of new BlueBerry selections
   //   tells the ToolManager for manual segmentation about new selections
   //   updates GUI information about what the user should select
   mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
   toolManager->SetReferenceData(const_cast<mitk::DataNode*>(referenceData));
   toolManager->SetWorkingData(const_cast<mitk::DataNode*>(workingData));
 
   m_Controls->btnNewSegmentation->setEnabled(referenceData != nullptr);
 }
 
 void QmitkSegmentationView::ForceDisplayPreferencesUponAllImages()
 {
    if (!m_Parent)
    {
      return;
    }
 
    // check all images and segmentations in DataStorage:
    // (items in brackets are implicitly done by previous steps)
    // 1.
    //   if  a reference image is selected,
    //     show the reference image
    //     and hide all other images (orignal and segmentation),
    //     (and hide all segmentations of the other original images)
    //     and show all the reference's segmentations
    //   if no reference image is selected, do do nothing
    //
    // 2.
    //   if  a segmentation is selected,
    //     show it
    //     (and hide all all its siblings (childs of the same parent, incl, nullptr parent))
    //   if no segmentation is selected, do nothing
 
    if (!m_Controls)
    {
      return; // might happen on initialization (preferences loaded)
    }
 
    mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
    mitk::DataNode::Pointer referenceData = toolManager->GetReferenceData(0);
    mitk::DataNode::Pointer workingData =   toolManager->GetWorkingData(0);
 
    // 1.
    if (referenceData.IsNotNull())
    {
       // iterate all images
      mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDataStorage()->GetSubset(m_IsASegmentationImagePredicate);
 
       for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter)
 
       {
          mitk::DataNode* node = *iter;
          // apply display preferences
          ApplyDisplayOptions(node);
 
          // set visibility
          node->SetVisibility(node == referenceData);
       }
    }
 
    // 2.
    if (workingData.IsNotNull())
       workingData->SetVisibility(true);
 
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node)
 {
   if (!node)
   {
     return;
   }
 
   mitk::BoolProperty::Pointer drawOutline = mitk::BoolProperty::New(GetPreferences()->GetBool("draw outline", true));
   mitk::BoolProperty::Pointer volumeRendering = mitk::BoolProperty::New(GetPreferences()->GetBool("volume rendering", false));
   mitk::LabelSetImage* labelSetImage = dynamic_cast<mitk::LabelSetImage*>(node->GetData());
   if (nullptr != labelSetImage)
   {
     // node is actually a multi label segmentation,
     // but its outline property can be set in the 'single label' segmentation preference page as well
     node->SetProperty("labelset.contour.active", drawOutline);
     //node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f));
     node->SetProperty("volumerendering", volumeRendering);
     // force render window update to show outline
     node->GetData()->Modified();
   }
   else
   {
     // node is a 'single label' segmentation
     bool isBinary = false;
     node->GetBoolProperty("binary", isBinary);
     if (isBinary)
     {
       node->SetProperty("outline binary", drawOutline);
       node->SetProperty("outline width", mitk::FloatProperty::New(2.0));
       //node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f));
       node->SetProperty("volumerendering", volumeRendering);
       // force render window update to show outline
       node->GetData()->Modified();
     }
   }
 }
 
 void QmitkSegmentationView::CheckRenderingState()
 {
   mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart();
   mitk::DataNode* workingNode = m_Controls->segImageSelector->GetSelectedNode();
 
   if (!workingNode)
   {
     this->SetToolSelectionBoxesEnabled(false);
     this->UpdateWarningLabel(tr("Select or create a segmentation"));
     return;
   }
 
   bool selectedNodeIsVisible = renderWindowPart && workingNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer());
 
   if (!selectedNodeIsVisible)
   {
     this->SetToolSelectionBoxesEnabled(false);
     this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!"));
     return;
   }
 
    /*
    * Here we check whether the geometry of the selected segmentation image if aligned with the worldgeometry
    * At the moment it is not supported to use a geometry different from the selected image for reslicing.
    * For further information see Bug 16063
    */
 
    const mitk::BaseGeometry* worldGeo = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D();
 
    if (workingNode && worldGeo)
    {
 
       const mitk::BaseGeometry* workingNodeGeo = workingNode->GetData()->GetGeometry();
       const mitk::BaseGeometry* worldGeo = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D();
 
       if (mitk::Equal(*workingNodeGeo->GetBoundingBox(), *worldGeo->GetBoundingBox(), mitk::eps, true))
       {
          this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), workingNode);
          this->SetToolSelectionBoxesEnabled(true);
          this->UpdateWarningLabel("");
          return;
       }
    }
 
    this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), nullptr);
    this->SetToolSelectionBoxesEnabled(false);
    this->UpdateWarningLabel(tr("Please perform a reinit on the segmentation image!"));
 }
 
 void QmitkSegmentationView::UpdateWarningLabel(QString text)
 {
    if (text.size() == 0)
       m_Controls->lblSegmentationWarnings->hide();
    else
       m_Controls->lblSegmentationWarnings->show();
    m_Controls->lblSegmentationWarnings->setText("<font color=\"red\">" + text + "</font>");
 }
 
 void QmitkSegmentationView::CreateQtPartControl(QWidget* parent)
 {
    // setup the basic GUI of this view
    m_Parent = parent;
 
    m_Controls = new Ui::QmitkSegmentationControls;
    m_Controls->setupUi(parent);
 
    m_Controls->patImageSelector->SetDataStorage(GetDataStorage());
    m_Controls->patImageSelector->SetNodePredicate(m_IsAPatientImagePredicate);
    m_Controls->patImageSelector->SetSelectionIsOptional(false);
    m_Controls->patImageSelector->SetInvalidInfo("Select an image.");
    m_Controls->patImageSelector->SetPopUpTitel("Select an image.");
    m_Controls->patImageSelector->SetPopUpHint("Select an image that should be used to define the geometry and bounds of the segmentation.");
 
    UpdateWarningLabel(tr("Please select an image"));
 
    if (m_Controls->patImageSelector->GetSelectedNode().IsNotNull())
    {
      UpdateWarningLabel(tr("Select or create a new segmentation"));
    }
 
    m_Controls->segImageSelector->SetDataStorage(GetDataStorage());
    m_Controls->segImageSelector->SetNodePredicate(m_IsASegmentationImagePredicate);
    m_Controls->segImageSelector->SetSelectionIsOptional(false);
    m_Controls->segImageSelector->SetInvalidInfo("Select a segmentation.");
    m_Controls->segImageSelector->SetPopUpTitel("Select a segmentation.");
    m_Controls->segImageSelector->SetPopUpHint("Select a segmentation that should be modified. Only segmentation with the same geometry and within the bounds of the reference image are selected.");
 
    if (m_Controls->segImageSelector->GetSelectedNode().IsNotNull())
    {
      UpdateWarningLabel("");
    }
 
    mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
    assert(toolManager);
 
    toolManager->SetDataStorage(*(GetDataStorage()));
    toolManager->InitializeTools();
 
    QString segTools2D = tr("Add Subtract Correction Paint Wipe 'Region Growing' Fill Erase 'Live Wire' '2D Fast Marching'");
    QString segTools3D = tr("Threshold 'UL Threshold' Otsu 'Fast Marching 3D' 'Region Growing 3D' Watershed Picking");
 
    std::regex extSegTool2DRegEx("SegTool2D$");
    std::regex extSegTool3DRegEx("SegTool3D$");
 
    auto tools = toolManager->GetTools();
 
    for (const auto &tool : tools)
    {
      if (std::regex_search(tool->GetNameOfClass(), extSegTool2DRegEx))
      {
        segTools2D.append(QString(" '%1'").arg(tool->GetName()));
      }
      else if (std::regex_search(tool->GetNameOfClass(), extSegTool3DRegEx))
      {
        segTools3D.append(QString(" '%1'").arg(tool->GetName()));
      }
    }
 
    // all part of open source MITK
    m_Controls->m_ManualToolSelectionBox2D->setEnabled(true);
    m_Controls->m_ManualToolSelectionBox2D->SetGenerateAccelerators(true);
    m_Controls->m_ManualToolSelectionBox2D->SetToolGUIArea(m_Controls->m_ManualToolGUIContainer2D);
 
    m_Controls->m_ManualToolSelectionBox2D->SetDisplayedToolGroups(segTools2D.toStdString());
    m_Controls->m_ManualToolSelectionBox2D->SetLayoutColumns(3);
    m_Controls->m_ManualToolSelectionBox2D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible);
    connect(m_Controls->m_ManualToolSelectionBox2D, &QmitkToolSelectionBox::ToolSelected, this, &QmitkSegmentationView::OnManualTool2DSelected);
 
    //setup 3D Tools
    m_Controls->m_ManualToolSelectionBox3D->setEnabled(true);
    m_Controls->m_ManualToolSelectionBox3D->SetGenerateAccelerators(true);
    m_Controls->m_ManualToolSelectionBox3D->SetToolGUIArea(m_Controls->m_ManualToolGUIContainer3D);
    //specify tools to be added to 3D Tool area
    m_Controls->m_ManualToolSelectionBox3D->SetDisplayedToolGroups(segTools3D.toStdString());
    m_Controls->m_ManualToolSelectionBox3D->SetLayoutColumns(3);
    m_Controls->m_ManualToolSelectionBox3D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible);
 
    //Hide 3D selection box, show 2D selection box
    m_Controls->m_ManualToolSelectionBox3D->hide();
    m_Controls->m_ManualToolSelectionBox2D->show();
 
    // update the list of segmentations
    toolManager->NewNodeObjectsGenerated += mitk::MessageDelegate1<QmitkSegmentationView, mitk::ToolManager::DataVectorType*>(this, &QmitkSegmentationView::NewNodeObjectsGenerated);
 
    // create signal/slot connections
    connect(m_Controls->patImageSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkSegmentationView::OnPatientSelectionChanged);
    connect(m_Controls->segImageSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkSegmentationView::OnSegmentationSelectionChanged);
 
    connect(m_Controls->btnNewSegmentation, &QToolButton::clicked, this, &QmitkSegmentationView::CreateNewSegmentation);
    connect(m_Controls->tabWidgetSegmentationTools, &QTabWidget::currentChanged, this, &QmitkSegmentationView::OnTabWidgetChanged);
    connect(m_Controls->m_SlicesInterpolator, &QmitkSlicesInterpolator::SignalShowMarkerNodes, this, &QmitkSegmentationView::OnShowMarkerNodes);
 
    // set callback function for already existing nodes (images & segmentations)
    mitk::DataStorage::SetOfObjects::ConstPointer allImages = GetDataStorage()->GetSubset(m_IsOfTypeImagePredicate);
    for (mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter)
    {
      mitk::DataNode* node = *iter;
      itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command = itk::SimpleMemberCommand<QmitkSegmentationView>::New();
      command->SetCallbackFunction(this, &QmitkSegmentationView::OnVisiblePropertyChanged);
      m_WorkingDataObserverTags.insert(std::pair<mitk::DataNode*, unsigned long>(node, node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command)));
    }
 
    itk::SimpleMemberCommand<QmitkSegmentationView>::Pointer command = itk::SimpleMemberCommand<QmitkSegmentationView>::New();
    command->SetCallbackFunction(this, &QmitkSegmentationView::CheckRenderingState);
    m_RenderingManagerObserverTag = mitk::RenderingManager::GetInstance()->AddObserver(mitk::RenderingManagerViewsInitializedEvent(), command);
 
    SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), m_Controls->segImageSelector->GetSelectedNode());
 
    m_RenderWindowPart = GetRenderWindowPart();
    if (m_RenderWindowPart)
    {
      RenderWindowPartActivated(m_RenderWindowPart);
    }
 
    //Should be done last, if everything else is configured because it triggers the autoselection of data.
    m_Controls->patImageSelector->SetAutoSelectNewNodes(true);
    m_Controls->segImageSelector->SetAutoSelectNewNodes(true);
 }
 
 void QmitkSegmentationView::SetFocus()
 {
   m_Controls->btnNewSegmentation->setFocus();
 }
 
 void QmitkSegmentationView::OnManualTool2DSelected(int id)
 {
    if (id >= 0)
    {
       std::string text = "Active Tool: \"";
       mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
       text += toolManager->GetToolById(id)->GetName();
       text += "\"";
       mitk::StatusBar::GetInstance()->DisplayText(text.c_str());
 
       us::ModuleResource resource = toolManager->GetToolById(id)->GetCursorIconResource();
       this->SetMouseCursor(resource, 0, 0);
    }
    else
    {
       this->ResetMouseCursor();
       mitk::StatusBar::GetInstance()->DisplayText("");
    }
 }
 
 void QmitkSegmentationView::ResetMouseCursor()
 {
    if ( m_MouseCursorSet )
    {
       mitk::ApplicationCursor::GetInstance()->PopCursor();
       m_MouseCursorSet = false;
    }
 }
 
 void QmitkSegmentationView::SetMouseCursor( const us::ModuleResource& resource, int hotspotX, int hotspotY )
 {
    // Remove previously set mouse cursor
    if (m_MouseCursorSet)
       this->ResetMouseCursor();
 
    if (resource)
    {
      us::ModuleResourceStream cursor(resource, std::ios::binary);
      mitk::ApplicationCursor::GetInstance()->PushCursor(cursor, hotspotX, hotspotY);
      m_MouseCursorSet = true;
    }
 }
 
 void QmitkSegmentationView::SetToolSelectionBoxesEnabled(bool status)
 {
   if (status)
   {
     m_Controls->m_ManualToolSelectionBox2D->RecreateButtons();
     m_Controls->m_ManualToolSelectionBox3D->RecreateButtons();
   }
 
   m_Controls->m_ManualToolSelectionBox2D->setEnabled(status);
   m_Controls->m_ManualToolSelectionBox3D->setEnabled(status);
   m_Controls->m_SlicesInterpolator->setEnabled(status);
 }