diff --git a/Modules/Core/test/mitkITKEventObserverGuardTest.cpp b/Modules/Core/test/mitkITKEventObserverGuardTest.cpp
index 22a77c1c7b..7634bfaccf 100644
--- a/Modules/Core/test/mitkITKEventObserverGuardTest.cpp
+++ b/Modules/Core/test/mitkITKEventObserverGuardTest.cpp
@@ -1,258 +1,258 @@
 /*============================================================================
 
 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 "mitkITKEventObserverGuard.h"
 
 #include <itkEventObject.h>
 #include <itkCommand.h>
 
 #include <mitkTestFixture.h>
 #include <mitkTestingMacros.h>
 
 // Create a command to observe events
 class DummyCommand : public itk::Command
 {
 public:
   using Self = DummyCommand;
   using Superclass = itk::Command;
   using Pointer = itk::SmartPointer<Self>;
   using ConstPointer = itk::SmartPointer<const Self>;
 
   itkNewMacro(DummyCommand);
 
   void Execute(itk::Object*, const itk::EventObject&) override
   {
     ++ExecutionCount;
   }
 
   void Execute(const itk::Object*, const itk::EventObject&) override
   {
     ++ExecutionCount;
   }
 
   int ExecutionCount;
 
 protected:
   DummyCommand() : ExecutionCount(0) {}
 };
 
 class mitkITKEventObserverGuardTestSuite : public mitk::TestFixture
 {
   CPPUNIT_TEST_SUITE(mitkITKEventObserverGuardTestSuite);
   MITK_TEST(TestConstructor);
   MITK_TEST(TestConstructor2);
   MITK_TEST(TestConstructor3);
   MITK_TEST(TestConstructor4);
   MITK_TEST(TestReset);
   MITK_TEST(TestReset2);
   MITK_TEST(TestOperateAssign);
   CPPUNIT_TEST_SUITE_END();
 
   itk::Object::Pointer m_TestObject;
   DummyCommand::Pointer m_DummyCommand;
   DummyCommand::Pointer m_DummyCommand2;
 
 public:
   void setUp() override
   {
     m_TestObject = itk::Object::New();
     m_DummyCommand = DummyCommand::New();
     m_DummyCommand2 = DummyCommand::New();
   }
 
   void tearDown() override
   {
     m_TestObject = nullptr;
     m_DummyCommand = nullptr;
     m_DummyCommand2 = nullptr;
   }
   // This test is supposed to verify inheritance behaviour, this test will fail if the behaviour changes in the future
 
   void TestConstructor()
   {
     mitk::ITKEventObserverGuard guard;
 
     CPPUNIT_ASSERT(!guard.IsInitialized());
   }
 
   void TestConstructor2()
   {
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(0, m_DummyCommand->ExecutionCount);
 
     {
       auto tag = m_TestObject->AddObserver(itk::ModifiedEvent(), m_DummyCommand);
       mitk::ITKEventObserverGuard guard(m_TestObject, tag);
 
       CPPUNIT_ASSERT(guard.IsInitialized());
       m_TestObject->InvokeEvent(itk::ModifiedEvent());
       CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
       m_TestObject->InvokeEvent(itk::ProgressEvent());
       CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
     }
 
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
   }
 
   void TestConstructor3()
   {
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(0, m_DummyCommand->ExecutionCount);
 
     {
       mitk::ITKEventObserverGuard guard(m_TestObject, itk::ModifiedEvent(), m_DummyCommand);
 
       CPPUNIT_ASSERT(guard.IsInitialized());
       m_TestObject->InvokeEvent(itk::ModifiedEvent());
       CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
       m_TestObject->InvokeEvent(itk::ProgressEvent());
       CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
     }
 
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
   }
 
   void TestConstructor4()
   {
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(0, m_DummyCommand->ExecutionCount);
 
     {
-      mitk::ITKEventObserverGuard guard(m_TestObject, itk::ModifiedEvent(), [this](const itk::EventObject& e) {++(this->m_DummyCommand->ExecutionCount); });
+      mitk::ITKEventObserverGuard guard(m_TestObject, itk::ModifiedEvent(), [this](const itk::EventObject&) {++(this->m_DummyCommand->ExecutionCount); });
 
       CPPUNIT_ASSERT(guard.IsInitialized());
       m_TestObject->InvokeEvent(itk::ModifiedEvent());
       CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
       m_TestObject->InvokeEvent(itk::ProgressEvent());
       CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
     }
 
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
   }
 
   void TestReset()
   {
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(0, m_DummyCommand->ExecutionCount);
 
     mitk::ITKEventObserverGuard guard(m_TestObject, itk::ModifiedEvent(), m_DummyCommand);
 
     CPPUNIT_ASSERT(guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
     guard.Reset();
     CPPUNIT_ASSERT(!guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
     guard.Reset();
     CPPUNIT_ASSERT(!guard.IsInitialized());
   }
 
   void TestReset2()
   {
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(0, m_DummyCommand->ExecutionCount);
 
     mitk::ITKEventObserverGuard guard(m_TestObject, itk::ModifiedEvent(), m_DummyCommand);
 
     CPPUNIT_ASSERT(guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
     auto tag = m_TestObject->AddObserver(itk::ProgressEvent(), m_DummyCommand2);
     guard.Reset(m_TestObject, tag);
     CPPUNIT_ASSERT(guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
     m_TestObject->InvokeEvent(itk::ProgressEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand2->ExecutionCount);
   }
 
   void TestReset3()
   {
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(0, m_DummyCommand->ExecutionCount);
 
     mitk::ITKEventObserverGuard guard(m_TestObject, itk::ModifiedEvent(), m_DummyCommand);
 
     CPPUNIT_ASSERT(guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
     guard.Reset(m_TestObject, itk::ProgressEvent(), m_DummyCommand2);
     CPPUNIT_ASSERT(guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
     m_TestObject->InvokeEvent(itk::ProgressEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand2->ExecutionCount);
   }
 
   void TestReset4()
   {
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(0, m_DummyCommand->ExecutionCount);
 
     mitk::ITKEventObserverGuard guard(m_TestObject, itk::ModifiedEvent(), m_DummyCommand);
 
     CPPUNIT_ASSERT(guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
-    guard.Reset(m_TestObject, itk::ProgressEvent(), [this](const itk::EventObject& e) {++(this->m_DummyCommand2->ExecutionCount); });
+    guard.Reset(m_TestObject, itk::ProgressEvent(), [this](const itk::EventObject&) {++(this->m_DummyCommand2->ExecutionCount); });
     CPPUNIT_ASSERT(guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
     m_TestObject->InvokeEvent(itk::ProgressEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand2->ExecutionCount);
   }
 
   void TestOperateAssign()
   {
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(0, m_DummyCommand->ExecutionCount);
 
     mitk::ITKEventObserverGuard guard(m_TestObject, itk::ModifiedEvent(), m_DummyCommand);
 
     CPPUNIT_ASSERT(guard.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
-    auto guard2 = mitk::ITKEventObserverGuard(m_TestObject, itk::ProgressEvent(), [this](const itk::EventObject& e) {++(this->m_DummyCommand2->ExecutionCount); });
+    auto guard2 = mitk::ITKEventObserverGuard(m_TestObject, itk::ProgressEvent(), [this](const itk::EventObject&) {++(this->m_DummyCommand2->ExecutionCount); });
     CPPUNIT_ASSERT(guard.IsInitialized());
     CPPUNIT_ASSERT(guard2.IsInitialized());
     m_TestObject->InvokeEvent(itk::ProgressEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand2->ExecutionCount);
 
     guard = guard2;
 
     CPPUNIT_ASSERT(guard.IsInitialized());
     CPPUNIT_ASSERT(!guard2.IsInitialized());
     m_TestObject->InvokeEvent(itk::ModifiedEvent());
     CPPUNIT_ASSERT_EQUAL(1, m_DummyCommand->ExecutionCount);
 
     m_TestObject->InvokeEvent(itk::ProgressEvent());
     CPPUNIT_ASSERT_EQUAL(2, m_DummyCommand2->ExecutionCount);
   }
 };
 
 MITK_TEST_SUITE_REGISTRATION(mitkITKEventObserverGuard)
diff --git a/Modules/Multilabel/autoload/DICOMSegIO/mitkDICOMSegmentationIO.cpp b/Modules/Multilabel/autoload/DICOMSegIO/mitkDICOMSegmentationIO.cpp
index 37c94a28e8..ad1fcb89d7 100644
--- a/Modules/Multilabel/autoload/DICOMSegIO/mitkDICOMSegmentationIO.cpp
+++ b/Modules/Multilabel/autoload/DICOMSegIO/mitkDICOMSegmentationIO.cpp
@@ -1,694 +1,694 @@
 /*============================================================================
 
 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 __mitkDICOMSegmentationIO__cpp
 #define __mitkDICOMSegmentationIO__cpp
 
 #include "mitkDICOMSegmentationIO.h"
 
 #include "mitkDICOMSegIOMimeTypes.h"
 #include "mitkDICOMSegmentationConstants.h"
 #include <mitkDICOMDCMTKTagScanner.h>
 #include <mitkDICOMIOHelper.h>
 #include <mitkDICOMProperty.h>
 #include <mitkIDICOMTagsOfInterest.h>
 #include <mitkImageAccessByItk.h>
 #include <mitkImageCast.h>
 #include <mitkLocaleSwitch.h>
 #include <mitkPropertyNameHelper.h>
 
 
 // itk
 #include <itkThresholdImageFilter.h>
 
 // dcmqi
 #include <dcmqi/ImageSEGConverter.h>
 
 // us
 #include <usGetModuleContext.h>
 #include <usModuleContext.h>
 
 namespace mitk
 {
   DICOMSegmentationIO::DICOMSegmentationIO()
     : AbstractFileIO(LabelSetImage::GetStaticNameOfClass(),
       mitk::MitkDICOMSEGIOMimeTypes::DICOMSEG_MIMETYPE_NAME(),
       "DICOM Segmentation")
   {
     AbstractFileWriter::SetRanking(10);
     AbstractFileReader::SetRanking(10);
     this->RegisterService();
   }
 
   std::vector<mitk::DICOMTagPath> DICOMSegmentationIO::GetDICOMTagsOfInterest()
   {
     std::vector<mitk::DICOMTagPath> result;
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_SEQUENCE_PATH());
 
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_NUMBER_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_LABEL_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_ALGORITHM_TYPE_PATH());
 
     result.emplace_back(DICOMSegmentationConstants::ANATOMIC_REGION_SEQUENCE_PATH());
     result.emplace_back(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_VALUE_PATH());
     result.emplace_back(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_SCHEME_PATH());
     result.emplace_back(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_MEANING_PATH());
 
     result.emplace_back(DICOMSegmentationConstants::SEGMENTED_PROPERTY_CATEGORY_SEQUENCE_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH());
 
     result.emplace_back(DICOMSegmentationConstants::SEGMENTED_PROPERTY_TYPE_SEQUENCE_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_VALUE_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_SCHEME_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_MEANING_PATH());
 
     result.emplace_back(DICOMSegmentationConstants::SEGMENTED_PROPERTY_MODIFIER_SEQUENCE_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_VALUE_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_SCHEME_PATH());
     result.emplace_back(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_MEANING_PATH());
 
     return result;
   }
 
   IFileIO::ConfidenceLevel DICOMSegmentationIO::GetWriterConfidenceLevel() const
   {
     if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported)
       return Unsupported;
 
     // Check if the input file is a segmentation
     const LabelSetImage *input = dynamic_cast<const LabelSetImage *>(this->GetInput());
 
     if (input)
     {
       if ((input->GetDimension() != 3))
       {
         MITK_INFO << "DICOM segmentation writer is tested only with 3D images, sorry.";
         return Unsupported;
       }
 
       // Check if input file has dicom information for the referenced image (original DICOM image, e.g. CT) Still necessary, see write()
       mitk::StringLookupTableProperty::Pointer dicomFilesProp =
       dynamic_cast<mitk::StringLookupTableProperty *>(input->GetProperty("referenceFiles").GetPointer());
 
       if (dicomFilesProp.IsNotNull())
         return Supported;
     }
 
     return Unsupported;
   }
 
   void DICOMSegmentationIO::Write()
   {
     ValidateOutputLocation();
 
     mitk::LocaleSwitch localeSwitch("C");
     LocalFile localFile(this);
     const std::string path = localFile.GetFileName();
 
     auto input = dynamic_cast<const LabelSetImage *>(this->GetInput());
     if (input == nullptr)
       mitkThrow() << "Cannot write non-image data";
 
     // Get DICOM information from referenced image
     vector<std::unique_ptr<DcmDataset>> dcmDatasetsSourceImage;
     std::unique_ptr<DcmFileFormat> readFileFormat(new DcmFileFormat());
     try
     {
       // TODO: Generate dcmdataset witk DICOM tags from property list; ATM the source are the filepaths from the
       // property list
       mitk::StringLookupTableProperty::Pointer filesProp =
         dynamic_cast<mitk::StringLookupTableProperty *>(input->GetProperty("referenceFiles").GetPointer());
 
       if (filesProp.IsNull())
       {
         mitkThrow() << "No property with dicom file path.";
         return;
       }
 
       StringLookupTable filesLut = filesProp->GetValue();
       const StringLookupTable::LookupTableType &lookUpTableMap = filesLut.GetLookupTable();
 
       for (const auto &it : lookUpTableMap)
       {
         const char *fileName = (it.second).c_str();
         if (readFileFormat->loadFile(fileName, EXS_Unknown).good())
         {
           std::unique_ptr<DcmDataset> readDCMDataset(readFileFormat->getAndRemoveDataset());
           dcmDatasetsSourceImage.push_back(std::move(readDCMDataset));
         }
       }
     }
     catch (const std::exception &e)
     {
       MITK_ERROR << "An error occurred while getting the dicom informations: " << e.what() << endl;
       return;
     }
 
     // Iterate over all layers. For each a dcm file will be generated
     for (unsigned int layer = 0; layer < input->GetNumberOfLayers(); ++layer)
     {
       vector<itkInternalImageType::Pointer> segmentations;
 
       try
       {
         auto mitkLayerImage = input->GetGroupImage(layer);
 
         // Cast mitk layer image to itk
         ImageToItk<itkInputImageType>::Pointer imageToItkFilter = ImageToItk<itkInputImageType>::New();
         imageToItkFilter->SetInput(mitkLayerImage);
         // Cast from original itk type to dcmqi input itk image type
         typedef itk::CastImageFilter<itkInputImageType, itkInternalImageType> castItkImageFilterType;
         castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New();
         castFilter->SetInput(imageToItkFilter->GetOutput());
         castFilter->Update();
 
         itkInternalImageType::Pointer itkLabelImage = castFilter->GetOutput();
         itkLabelImage->DisconnectPipeline();
 
         // Iterate over all labels. For each label a segmentation image will be created
         auto labelSet = input->GetConstLabelsByValue(input->GetLabelValuesByGroup(layer));
 
-        for (const auto label : labelSet)
+        for (const auto& label : labelSet)
         {
           // Thresold over the image with the given label value
           itk::ThresholdImageFilter<itkInternalImageType>::Pointer thresholdFilter =
             itk::ThresholdImageFilter<itkInternalImageType>::New();
           thresholdFilter->SetInput(itkLabelImage);
           thresholdFilter->ThresholdOutside(label->GetValue(), label->GetValue());
           thresholdFilter->SetOutsideValue(0);
           thresholdFilter->Update();
           itkInternalImageType::Pointer segmentImage = thresholdFilter->GetOutput();
           segmentImage->DisconnectPipeline();
 
           segmentations.push_back(segmentImage);
         }
       }
       catch (const itk::ExceptionObject &e)
       {
         MITK_ERROR << e.GetDescription() << endl;
         return;
       }
 
       // Create segmentation meta information
       const std::string tmpMetaInfoFile = this->CreateMetaDataJsonFile(layer);
 
       MITK_INFO << "Writing image: " << path << std::endl;
       try
       {
         //TODO is there a better way? Interface expects a vector of raw pointer.
         vector<DcmDataset*> rawVecDataset;
         for (const auto& dcmDataSet : dcmDatasetsSourceImage)
           rawVecDataset.push_back(dcmDataSet.get());
 
         // Convert itk segmentation images to dicom image
         std::unique_ptr<dcmqi::ImageSEGConverter> converter = std::make_unique<dcmqi::ImageSEGConverter>();
         std::unique_ptr<DcmDataset> result(converter->itkimage2dcmSegmentation(rawVecDataset, segmentations, tmpMetaInfoFile, false));
 
         // Write dicom file
         DcmFileFormat dcmFileFormat(result.get());
 
         std::string filePath = path.substr(0, path.find_last_of("."));
         // If there is more than one layer, we have to write more than 1 dicom file
         if (input->GetNumberOfLayers() != 1)
           filePath = filePath + std::to_string(layer) + ".dcm";
         else
           filePath = filePath + ".dcm";
 
         dcmFileFormat.saveFile(filePath.c_str(), EXS_LittleEndianExplicit);
       }
       catch (const std::exception &e)
       {
         MITK_ERROR << "An error occurred during writing the DICOM Seg: " << e.what() << endl;
         return;
       }
     } // Write a dcm file for the next layer
   }
 
   IFileIO::ConfidenceLevel DICOMSegmentationIO::GetReaderConfidenceLevel() const
   {
     if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported)
       return Unsupported;
 
     const std::string fileName = this->GetLocalFileName();
 
     DcmFileFormat dcmFileFormat;
     OFCondition status = dcmFileFormat.loadFile(fileName.c_str());
 
     if (status.bad())
       return Unsupported;
 
     OFString modality;
     if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good())
     {
       if (modality.compare("SEG") == 0)
         return Supported;
       else
         return Unsupported;
     }
     return Unsupported;
   }
 
   std::vector<BaseData::Pointer> DICOMSegmentationIO::DoRead()
   {
     mitk::LocaleSwitch localeSwitch("C");
 
     LabelSetImage::Pointer labelSetImage;
     std::vector<BaseData::Pointer> result;
 
     const std::string path = this->GetLocalFileName();
 
     MITK_INFO << "loading " << path << std::endl;
 
     if (path.empty())
       mitkThrow() << "Empty filename in mitk::ItkImageIO ";
 
     try
     {
       // Get the dcm data set from file path
       DcmFileFormat dcmFileFormat;
       OFCondition status = dcmFileFormat.loadFile(path.c_str());
       if (status.bad())
         mitkThrow() << "Can't read the input file!";
 
       DcmDataset *dataSet = dcmFileFormat.getDataset();
       if (dataSet == nullptr)
         mitkThrow() << "Can't read data from input file!";
 
       //=============================== dcmqi part ====================================
       // Read the DICOM SEG images (segItkImages) and DICOM tags (metaInfo)
       std::unique_ptr<dcmqi::ImageSEGConverter> converter = std::make_unique<dcmqi::ImageSEGConverter>();
       pair<map<unsigned, itkInternalImageType::Pointer>, string> dcmqiOutput =
         converter->dcmSegmentation2itkimage(dataSet);
 
       map<unsigned, itkInternalImageType::Pointer> segItkImages = dcmqiOutput.first;
 
       dcmqi::JSONSegmentationMetaInformationHandler metaInfo(dcmqiOutput.second.c_str());
       metaInfo.read();
 
       MITK_INFO << "Input " << metaInfo.getJSONOutputAsString();
       //===============================================================================
 
       // Get the label information from segment attributes for each itk image
       vector<map<unsigned, dcmqi::SegmentAttributes *>>::const_iterator segmentIter =
         metaInfo.segmentsAttributesMappingList.begin();
 
       // For each itk image add a layer to the LabelSetImage output
       for (auto &element : segItkImages)
       {
         // Get the labeled image and cast it to mitkImage
         typedef itk::CastImageFilter<itkInternalImageType, itkInputImageType> castItkImageFilterType;
         castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New();
         castFilter->SetInput(element.second);
         castFilter->Update();
 
         Image::Pointer layerImage;
         CastToMitkImage(castFilter->GetOutput(), layerImage);
 
         // Get pixel value of the label
         itkInternalImageType::ValueType segValue = 1;
         typedef itk::ImageRegionIterator<const itkInternalImageType> IteratorType;
         // Iterate over the image to find the pixel value of the label
         IteratorType iter(element.second, element.second->GetLargestPossibleRegion());
         iter.GoToBegin();
         while (!iter.IsAtEnd())
         {
           itkInputImageType::PixelType value = iter.Get();
           if (value != LabelSetImage::UNLABELED_VALUE)
           {
             segValue = value;
             break;
           }
           ++iter;
         }
         // Get Segment information map
         map<unsigned, dcmqi::SegmentAttributes *> segmentMap = (*segmentIter);
         map<unsigned, dcmqi::SegmentAttributes *>::const_iterator segmentMapIter = (*segmentIter).begin();
         dcmqi::SegmentAttributes *segmentAttribute = (*segmentMapIter).second;
 
         OFString labelName;
 
         if (segmentAttribute->getSegmentedPropertyTypeCodeSequence() != nullptr)
         {
           segmentAttribute->getSegmentedPropertyTypeCodeSequence()->getCodeMeaning(labelName);
           if (segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence() != nullptr)
           {
             OFString modifier;
             segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence()->getCodeMeaning(modifier);
             labelName.append(" (").append(modifier).append(")");
           }
         }
         else
         {
           labelName = std::to_string(segmentAttribute->getLabelID()).c_str();
           if (labelName.empty())
             labelName = "Unnamed";
         }
 
         float tmp[3] = { 0.0, 0.0, 0.0 };
         if (segmentAttribute->getRecommendedDisplayRGBValue() != nullptr)
         {
           tmp[0] = segmentAttribute->getRecommendedDisplayRGBValue()[0] / 255.0;
           tmp[1] = segmentAttribute->getRecommendedDisplayRGBValue()[1] / 255.0;
           tmp[2] = segmentAttribute->getRecommendedDisplayRGBValue()[2] / 255.0;
         }
 
         Label *newLabel = nullptr;
         // If labelSetImage do not exists (first image)
         if (labelSetImage.IsNull())
         {
           // Initialize the labelSetImage with the read image
           labelSetImage = LabelSetImage::New();
           labelSetImage->InitializeByLabeledImage(layerImage);
           // Already a label was generated, so set the information to this
           newLabel = labelSetImage->GetActiveLabel();
           newLabel->SetName(labelName.c_str());
           newLabel->SetColor(Color(tmp));
           newLabel->SetValue(segValue);
         }
         else
         {
           // Add a new layer to the labelSetImage. Background label is set automatically
           labelSetImage->AddLayer(layerImage);
 
           // Add new label
           newLabel = new Label;
           newLabel->SetName(labelName.c_str());
           newLabel->SetColor(Color(tmp));
           newLabel->SetValue(segValue);
           labelSetImage->AddLabel(newLabel, labelSetImage->GetActiveLayer());
         }
 
         // Add some more label properties
         this->SetLabelProperties(newLabel, segmentAttribute);
         ++segmentIter;
       }
 
       labelSetImage->SetAllLabelsVisible(true);
 
       // Add some general DICOM Segmentation properties
       mitk::IDICOMTagsOfInterest *toiSrv = DICOMIOHelper::GetTagsOfInterestService();
       auto tagsOfInterest = toiSrv->GetTagsOfInterest();
       DICOMTagPathList tagsOfInterestList;
       for (const auto &tag : tagsOfInterest)
       {
         tagsOfInterestList.push_back(tag.first);
       }
 
       mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New();
       scanner->SetInputFiles({ GetInputLocation() });
       scanner->AddTagPaths(tagsOfInterestList);
       scanner->Scan();
 
       mitk::DICOMDatasetAccessingImageFrameList frames = scanner->GetFrameInfoList();
       if (frames.empty())
       {
         MITK_ERROR << "Error reading the DICOM Seg file" << std::endl;
         return result;
       }
 
       auto findings = DICOMIOHelper::ExtractPathsOfInterest(tagsOfInterestList, frames);
       DICOMIOHelper::SetProperties(labelSetImage, findings);
 
       // Set active layer to the first layer of the labelset image
       if (labelSetImage->GetNumberOfLayers() > 1 && labelSetImage->GetActiveLayer() != 0)
         labelSetImage->SetActiveLayer(0);
     }
     catch (const std::exception &e)
     {
       MITK_ERROR << "An error occurred while reading the DICOM Seg file: " << e.what();
       return result;
     }
     catch (...)
     {
       MITK_ERROR << "An error occurred in dcmqi while reading the DICOM Seg file";
       return result;
     }
 
     result.push_back(labelSetImage.GetPointer());
     return result;
   }
 
   const std::string mitk::DICOMSegmentationIO::CreateMetaDataJsonFile(int layer)
   {
     const mitk::LabelSetImage *image = dynamic_cast<const mitk::LabelSetImage *>(this->GetInput());
 
     const std::string output;
     dcmqi::JSONSegmentationMetaInformationHandler handler;
 
 
     // 1. Metadata attributes that will be listed in the resulting DICOM SEG object
     std::string contentCreatorName;
     if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0070, 0x0084).c_str(),
       contentCreatorName))
       contentCreatorName = "MITK";
     handler.setContentCreatorName(contentCreatorName);
 
     std::string clinicalTrailSeriesId;
     if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0071).c_str(),
       clinicalTrailSeriesId))
       clinicalTrailSeriesId = "Session 1";
     handler.setClinicalTrialSeriesID(clinicalTrailSeriesId);
 
     std::string clinicalTrialTimePointID;
     if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0050).c_str(),
       clinicalTrialTimePointID))
       clinicalTrialTimePointID = "0";
     handler.setClinicalTrialTimePointID(clinicalTrialTimePointID);
 
     std::string clinicalTrialCoordinatingCenterName = "";
     if (!image->GetPropertyList()->GetStringProperty(GeneratePropertyNameForDICOMTag(0x0012, 0x0060).c_str(),
       clinicalTrialCoordinatingCenterName))
       clinicalTrialCoordinatingCenterName = "Unknown";
     handler.setClinicalTrialCoordinatingCenterName(clinicalTrialCoordinatingCenterName);
 
     std::string seriesDescription;
     if (!image->GetPropertyList()->GetStringProperty("name", seriesDescription))
       seriesDescription = "MITK Segmentation";
     handler.setSeriesDescription(seriesDescription);
 
     handler.setSeriesNumber("0" + std::to_string(layer));
     handler.setInstanceNumber("1");
     handler.setBodyPartExamined("");
 
     auto labelSet = image->GetConstLabelsByValue(image->GetLabelValuesByGroup(layer));
 
-    for (const auto label : labelSet)
+    for (const auto& label : labelSet)
     {
       if (label != nullptr)
       {
         TemporoSpatialStringProperty *segmentNumberProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_NUMBER_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentLabelProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_LABEL_PATH()).c_str()));
 
         TemporoSpatialStringProperty *algorithmTypeProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_ALGORITHM_TYPE_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentCategoryCodeValueProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentCategoryCodeSchemeProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentCategoryCodeMeaningProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentTypeCodeValueProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_VALUE_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentTypeCodeSchemeProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_SCHEME_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentTypeCodeMeaningProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_MEANING_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentModifierCodeValueProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_VALUE_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentModifierCodeSchemeProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_SCHEME_PATH()).c_str()));
 
         TemporoSpatialStringProperty *segmentModifierCodeMeaningProp = dynamic_cast<mitk::TemporoSpatialStringProperty *>(label->GetProperty(
           mitk::DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_MEANING_PATH()).c_str()));
 
         dcmqi::SegmentAttributes *segmentAttribute = nullptr;
 
         if (segmentNumberProp->GetValue() == "")
         {
           MITK_ERROR << "Something went wrong with the label ID.";
         }
         else
         {
           int labelId = std::stoi(segmentNumberProp->GetValue());
           segmentAttribute = handler.createAndGetNewSegment(labelId);
         }
         if (segmentAttribute != nullptr)
         {
           segmentAttribute->setSegmentLabel(segmentLabelProp->GetValueAsString());
           segmentAttribute->setSegmentDescription(segmentLabelProp->GetValueAsString());
           segmentAttribute->setSegmentAlgorithmType(algorithmTypeProp->GetValueAsString());
           segmentAttribute->setSegmentAlgorithmName("MITK Segmentation");
           if (segmentCategoryCodeValueProp != nullptr && segmentCategoryCodeSchemeProp != nullptr &&
             segmentCategoryCodeMeaningProp != nullptr)
             segmentAttribute->setSegmentedPropertyCategoryCodeSequence(
               segmentCategoryCodeValueProp->GetValueAsString(),
               segmentCategoryCodeSchemeProp->GetValueAsString(),
               segmentCategoryCodeMeaningProp->GetValueAsString());
           else
             // some default values
             segmentAttribute->setSegmentedPropertyCategoryCodeSequence(
               "M-01000", "SRT", "Morphologically Altered Structure");
 
           if (segmentTypeCodeValueProp != nullptr && segmentTypeCodeSchemeProp != nullptr &&
             segmentTypeCodeMeaningProp != nullptr)
           {
             segmentAttribute->setSegmentedPropertyTypeCodeSequence(segmentTypeCodeValueProp->GetValueAsString(),
               segmentTypeCodeSchemeProp->GetValueAsString(),
               segmentTypeCodeMeaningProp->GetValueAsString());
             handler.setBodyPartExamined(segmentTypeCodeMeaningProp->GetValueAsString());
           }
           else
           {
             // some default values
             segmentAttribute->setSegmentedPropertyTypeCodeSequence("M-03000", "SRT", "Mass");
             handler.setBodyPartExamined("Mass");
           }
           if (segmentModifierCodeValueProp != nullptr && segmentModifierCodeSchemeProp != nullptr &&
             segmentModifierCodeMeaningProp != nullptr)
             segmentAttribute->setSegmentedPropertyTypeModifierCodeSequence(
               segmentModifierCodeValueProp->GetValueAsString(),
               segmentModifierCodeSchemeProp->GetValueAsString(),
               segmentModifierCodeMeaningProp->GetValueAsString());
 
           Color color = label->GetColor();
           segmentAttribute->setRecommendedDisplayRGBValue(color[0] * 255, color[1] * 255, color[2] * 255);
         }
       }
     }
     return handler.getJSONOutputAsString();
   }
 
   void mitk::DICOMSegmentationIO::SetLabelProperties(mitk::Label *label, dcmqi::SegmentAttributes *segmentAttribute)
   {
     // Segment Number:Identification number of the segment.The value of Segment Number(0062, 0004) shall be unique
     // within the Segmentation instance in which it is created
     label->SetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_NUMBER_PATH()).c_str(),
       TemporoSpatialStringProperty::New(std::to_string(label->GetValue())));
 
     // Segment Label: User-defined label identifying this segment.
     label->SetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_LABEL_PATH()).c_str(),
       TemporoSpatialStringProperty::New(label->GetName()));
 
     // Segment Algorithm Type: Type of algorithm used to generate the segment.
     if (!segmentAttribute->getSegmentAlgorithmType().empty())
       label->SetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_ALGORITHM_TYPE_PATH()).c_str(),
         TemporoSpatialStringProperty::New(segmentAttribute->getSegmentAlgorithmType()));
 
     // Add Segmented Property Category Code Sequence tags
     auto categoryCodeSequence = segmentAttribute->getSegmentedPropertyCategoryCodeSequence();
     if (categoryCodeSequence != nullptr)
     {
       OFString codeValue; // (0008,0100) Code Value
       categoryCodeSequence->getCodeValue(codeValue);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeValue.c_str()));
 
       OFString codeScheme; // (0008,0102) Coding Scheme Designator
       categoryCodeSequence->getCodingSchemeDesignator(codeScheme);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeScheme.c_str()));
 
       OFString codeMeaning; // (0008,0104) Code Meaning
       categoryCodeSequence->getCodeMeaning(codeMeaning);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeMeaning.c_str()));
     }
 
     // Add Segmented Property Type Code Sequence tags
     auto typeCodeSequence = segmentAttribute->getSegmentedPropertyTypeCodeSequence();
     if (typeCodeSequence != nullptr)
     {
       OFString codeValue; // (0008,0100) Code Value
       typeCodeSequence->getCodeValue(codeValue);
       label->SetProperty(DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_VALUE_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeValue.c_str()));
 
       OFString codeScheme; // (0008,0102) Coding Scheme Designator
       typeCodeSequence->getCodingSchemeDesignator(codeScheme);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_SCHEME_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeScheme.c_str()));
 
       OFString codeMeaning; // (0008,0104) Code Meaning
       typeCodeSequence->getCodeMeaning(codeMeaning);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_MEANING_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeMeaning.c_str()));
     }
 
     // Add Segmented Property Type Modifier Code Sequence tags
     auto modifierCodeSequence = segmentAttribute->getSegmentedPropertyTypeModifierCodeSequence();
     if (modifierCodeSequence != nullptr)
     {
       OFString codeValue; // (0008,0100) Code Value
       modifierCodeSequence->getCodeValue(codeValue);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_VALUE_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeValue.c_str()));
 
       OFString codeScheme; // (0008,0102) Coding Scheme Designator
       modifierCodeSequence->getCodingSchemeDesignator(codeScheme);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_SCHEME_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeScheme.c_str()));
 
       OFString codeMeaning; // (0008,0104) Code Meaning
       modifierCodeSequence->getCodeMeaning(codeMeaning);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_MODIFIER_CODE_MEANING_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeMeaning.c_str()));
     }
 
     // Add Atomic RegionSequence tags
     auto atomicRegionSequence = segmentAttribute->getAnatomicRegionSequence();
     if (atomicRegionSequence != nullptr)
     {
       OFString codeValue; // (0008,0100) Code Value
       atomicRegionSequence->getCodeValue(codeValue);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_VALUE_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeValue.c_str()));
 
       OFString codeScheme; // (0008,0102) Coding Scheme Designator
       atomicRegionSequence->getCodingSchemeDesignator(codeScheme);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_SCHEME_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeScheme.c_str()));
 
       OFString codeMeaning; // (0008,0104) Code Meaning
       atomicRegionSequence->getCodeMeaning(codeMeaning);
       label->SetProperty(
         DICOMTagPathToPropertyName(DICOMSegmentationConstants::ANATOMIC_REGION_CODE_MEANING_PATH()).c_str(),
         TemporoSpatialStringProperty::New(codeMeaning.c_str()));
     }
   }
 
   DICOMSegmentationIO *DICOMSegmentationIO::IOClone() const { return new DICOMSegmentationIO(*this); }
 } // namespace
 
 #endif //__mitkDICOMSegmentationIO__cpp
diff --git a/Modules/Multilabel/mitkLabelSetImage.cpp b/Modules/Multilabel/mitkLabelSetImage.cpp
index 383ccda818..df4124dfdb 100644
--- a/Modules/Multilabel/mitkLabelSetImage.cpp
+++ b/Modules/Multilabel/mitkLabelSetImage.cpp
@@ -1,1630 +1,1630 @@
 /*============================================================================
 
 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 "mitkLabelSetImage.h"
 
 #include <mitkImageAccessByItk.h>
 #include <mitkImageCast.h>
 #include <mitkImagePixelWriteAccessor.h>
 #include <mitkPadImageFilter.h>
 #include <mitkDICOMSegmentationPropertyHelper.h>
 #include <mitkDICOMQIPropertyHelper.h>
 
 #include <itkLabelGeometryImageFilter.h>
 #include <itkCommand.h>
 #include <itkBinaryFunctorImageFilter.h>
 
 
 namespace mitk
 {
   template <typename ImageType>
   void ClearBufferProcessing(ImageType* itkImage)
   {
     itkImage->FillBuffer(0);
   }
 
   void ClearImageBuffer(mitk::Image* image)
   {
     if (image->GetDimension() == 4)
     { //remark: this extra branch was added, because LabelSetImage instances can be
       //dynamic (4D), but AccessByItk by support only supports 2D and 3D.
       //The option to change the CMake default dimensions for AccessByItk was
       //dropped (for details see discussion in T28756)
       AccessFixedDimensionByItk(image, ClearBufferProcessing, 4);
     }
     else
     {
       AccessByItk(image, ClearBufferProcessing);
     }
   }
 }
 
 const mitk::LabelSetImage::LabelValueType mitk::LabelSetImage::UNLABELED_VALUE = 0;
 
 mitk::LabelSetImage::LabelSetImage()
-  : mitk::Image(), m_UnlabeledLabelLock(false), m_ActiveLayer(0), m_activeLayerInvalid(false), m_ActiveLabelValue(0)
+  : mitk::Image(), m_ActiveLabelValue(0), m_UnlabeledLabelLock(false), m_ActiveLayer(0), m_activeLayerInvalid(false)
 {
   m_LookupTable = mitk::LookupTable::New();
   m_LookupTable->SetType(mitk::LookupTable::MULTILABEL);
 
   // Add some DICOM Tags as properties to segmentation image
   DICOMSegmentationPropertyHelper::DeriveDICOMSegmentationProperties(this);
 }
 
 mitk::LabelSetImage::LabelSetImage(const mitk::LabelSetImage &other)
   : Image(other),
+    m_ActiveLabelValue(other.m_ActiveLabelValue),
+    m_LookupTable(other.m_LookupTable->Clone()),
     m_UnlabeledLabelLock(other.m_UnlabeledLabelLock),
     m_ActiveLayer(other.GetActiveLayer()),
-    m_activeLayerInvalid(false),
-    m_LookupTable(other.m_LookupTable->Clone()),
-    m_ActiveLabelValue(other.m_ActiveLabelValue)
+    m_activeLayerInvalid(false)
 {
   GroupIndexType i = 0;
   for (auto groupImage : other.m_LayerContainer)
   {
     this->AddLayer(groupImage->Clone(), other.GetConstLabelsByValue(other.GetLabelValuesByGroup(i)));
     i++;
   }
   m_Groups = other.m_Groups;
 
   // Add some DICOM Tags as properties to segmentation image
   DICOMSegmentationPropertyHelper::DeriveDICOMSegmentationProperties(this);
 }
 
 void mitk::LabelSetImage::Initialize(const mitk::Image *other)
 {
   mitk::PixelType pixelType(mitk::MakeScalarPixelType<LabelSetImage::PixelType>());
   if (other->GetDimension() == 2)
   {
     const unsigned int dimensions[] = {other->GetDimension(0), other->GetDimension(1), 1};
     Superclass::Initialize(pixelType, 3, dimensions);
   }
   else
   {
     Superclass::Initialize(pixelType, other->GetDimension(), other->GetDimensions());
   }
 
   auto originalGeometry = other->GetTimeGeometry()->Clone();
   this->SetTimeGeometry(originalGeometry);
 
   // initialize image memory to zero
   ClearImageBuffer(this);
 
   // Transfer some general DICOM properties from the source image to derived image (e.g. Patient information,...)
   DICOMQIPropertyHelper::DeriveDICOMSourceProperties(other, this);
 
   // Add a inital LabelSet ans corresponding image data to the stack
   if (this->GetNumberOfLayers() == 0)
   {
     AddLayer();
   }
 }
 
 mitk::LabelSetImage::~LabelSetImage()
 {
   for (auto [value, label] : m_LabelMap)
   {
     this->ReleaseLabel(label);
   }
   m_LabelMap.clear();
 }
 
 unsigned int mitk::LabelSetImage::GetActiveLayer() const
 {
   if (m_LayerContainer.size() == 0) mitkThrow() << "Cannot return active layer index. No layer is available.";
 
   return m_ActiveLayer;
 }
 
 unsigned int mitk::LabelSetImage::GetNumberOfLayers() const
 {
   return m_LayerContainer.size();
 }
 
 void mitk::LabelSetImage::RemoveGroup(GroupIndexType indexToDelete)
 {
   if (!this->ExistGroup(indexToDelete)) mitkThrow() << "Cannot remove group. Group does not exist. Invalid group index: "<<indexToDelete;
 
   const auto activeIndex = GetActiveLayer();
 
   auto newActiveIndex = activeIndex;
   auto newActiveIndexBeforeDeletion = activeIndex;
   //determin new active group index (afte the group will be removed);
   if (indexToDelete < activeIndex)
   { //lower the index because position in m_LayerContainer etc has changed
     newActiveIndex = activeIndex-1;
   }
   else if (indexToDelete == activeIndex)
   {
     if (this->GetNumberOfLayers() == 1)
     { //last layer is about to be deleted
       newActiveIndex = 0;
     }
     else
     {
       //we have to add/substract one more because we have not removed the layer yet, thus the group count is to 1 high.
       newActiveIndex = indexToDelete+1 < GetNumberOfLayers() ? indexToDelete : GetNumberOfLayers() - 2;
       newActiveIndexBeforeDeletion = indexToDelete + 1 < GetNumberOfLayers() ? indexToDelete+1 : indexToDelete -1;
     }
   }
 
   if (activeIndex == indexToDelete)
   {
     // we are deleting the active layer, it should not be copied back into the vector
     m_activeLayerInvalid = true;
     //copy the image content of the upcoming new active layer; 
     SetActiveLayer(newActiveIndexBeforeDeletion);
   }
 
   auto relevantLabels = m_GroupToLabelMap[indexToDelete];
 
   // remove labels of group
   for (auto labelValue : relevantLabels)
   {
     auto label = m_LabelMap[labelValue];
     this->ReleaseLabel(label);
     m_LabelToGroupMap.erase(labelValue);
     m_LabelMap.erase(labelValue);
     this->InvokeEvent(LabelRemovedEvent(labelValue));
   }
   // remove the group entries in the maps and the image.
   m_Groups.erase(m_Groups.begin() + indexToDelete);
   m_GroupToLabelMap.erase(m_GroupToLabelMap.begin() + indexToDelete);
   m_LayerContainer.erase(m_LayerContainer.begin() + indexToDelete);
 
   //update old indeces in m_GroupToLabelMap to new layer indices
   for (auto& element : m_LabelToGroupMap)
   {
     if (element.second > indexToDelete) element.second = element.second -1;
   }
 
   //correct active layer index
   m_ActiveLayer = newActiveIndex;
 
   this->InvokeEvent(LabelsChangedEvent(relevantLabels));
   this->InvokeEvent(GroupRemovedEvent(indexToDelete));
   this->Modified();
 }
 
 mitk::LabelSetImage::LabelValueVectorType mitk::LabelSetImage::ExtractLabelValuesFromLabelVector(const LabelVectorType& labels)
 {
   LabelValueVectorType result;
 
   for (auto label : labels)
   {
     result.emplace_back(label->GetValue());
   }
   return result;
 }
 
 mitk::LabelSetImage::LabelValueVectorType mitk::LabelSetImage::ExtractLabelValuesFromLabelVector(const ConstLabelVectorType& labels)
 {
   LabelValueVectorType result;
 
   for (auto label : labels)
   {
     result.emplace_back(label->GetValue());
   }
   return result;
 }
 
 mitk::LabelSetImage::ConstLabelVectorType mitk::LabelSetImage::ConvertLabelVectorConst(const LabelVectorType& labels)
 {
   ConstLabelVectorType result(labels.begin(), labels.end());
   return result;
 };
 
 const mitk::LabelSetImage::LabelValueVectorType mitk::LabelSetImage::GetAllLabelValues() const
 {
   LabelValueVectorType result;
 
   for (auto [value, label] : m_LabelMap)
   {
     result.emplace_back(value);
   }
   return result;
 }
 
 mitk::LabelSetImage::LabelValueVectorType mitk::LabelSetImage::GetUsedLabelValues() const
 {
   LabelValueVectorType result = { UNLABELED_VALUE };
 
   for (auto [value, label] : m_LabelMap)
   {
     result.emplace_back(value);
   }
 
   return result;
 }
 
 mitk::LabelSetImage::GroupIndexType mitk::LabelSetImage::AddLayer(ConstLabelVector labels)
 {
   mitk::Image::Pointer newImage = mitk::Image::New();
   newImage->Initialize(this->GetPixelType(),
                        this->GetDimension(),
                        this->GetDimensions(),
                        this->GetImageDescriptor()->GetNumberOfChannels());
   newImage->SetTimeGeometry(this->GetTimeGeometry()->Clone());
 
   ClearImageBuffer(newImage);
 
   return this->AddLayer(newImage, labels);
 }
 
 mitk::LabelSetImage::GroupIndexType mitk::LabelSetImage::AddLayer(mitk::Image::Pointer layerImage, ConstLabelVector labels)
 {
   GroupIndexType newGroupID = m_Groups.size();
 
   // push a new working image for the new layer
   m_LayerContainer.push_back(layerImage);
 
   m_Groups.push_back("");
   m_GroupToLabelMap.push_back({});
 
   for (auto label : labels)
   {
     if (m_LabelMap.end() != m_LabelMap.find(label->GetValue()))
     {
       mitkThrow() << "Cannot add layer. Labels that should be added with layer use at least one label value that is already in use. Conflicted label value: " << label->GetValue();
     }
 
     auto labelClone = label->Clone();
 
     DICOMSegmentationPropertyHelper::SetDICOMSegmentProperties(labelClone);
     this->AddLabelToMap(labelClone->GetValue(), labelClone, newGroupID);
     this->RegisterLabel(labelClone);
   }
 
   this->Modified();
   this->InvokeEvent(GroupAddedEvent(newGroupID));
 
   return newGroupID;
 }
 
 void mitk::LabelSetImage::ReplaceGroupLabels(const GroupIndexType groupID, const ConstLabelVectorType& labelSet)
 {
   if (m_LayerContainer.size() <= groupID)
   {
     mitkThrow() << "Trying to replace labels of non-exising group. Invalid group id: "<<groupID;
   }
 
   //remove old group labels
   auto oldLabels = this->m_GroupToLabelMap[groupID];
   for (auto labelID : oldLabels)
   {
     this->RemoveLabelFromMap(labelID);
     this->InvokeEvent(LabelRemovedEvent(labelID));
 
   }
   this->InvokeEvent(LabelsChangedEvent(oldLabels));
   this->InvokeEvent(GroupModifiedEvent(groupID));
 
   //add new labels to group
   for (auto label : labelSet)
   {
     this->AddLabel(label->Clone(), groupID, true, false);
   }
 }
 
 void mitk::LabelSetImage::ReplaceGroupLabels(const GroupIndexType groupID, const LabelVectorType& labelSet)
 {
   return ReplaceGroupLabels(groupID, ConvertLabelVectorConst(labelSet));
 }
 
 mitk::Image* mitk::LabelSetImage::GetGroupImage(GroupIndexType groupID)
 {
   if (!this->ExistGroup(groupID)) mitkThrow() << "Error, cannot return group image. Group ID is invalid. Invalid ID: " << groupID;
 
   return groupID == this->GetActiveLayer() ? this : m_LayerContainer[groupID];
 }
 
 const mitk::Image* mitk::LabelSetImage::GetGroupImage(GroupIndexType groupID) const
 {
   if (!this->ExistGroup(groupID)) mitkThrow() << "Error, cannot return group image. Group ID is invalid. Invalid ID: " << groupID;
 
   return groupID == this->GetActiveLayer() ? this : m_LayerContainer[groupID].GetPointer();
 }
 
 void mitk::LabelSetImage::SetActiveLayer(unsigned int layer)
 {
   try
   {
     if (4 == this->GetDimension())
     {
       if ((layer != GetActiveLayer() || m_activeLayerInvalid) && (layer < this->GetNumberOfLayers()))
       {
         BeforeChangeLayerEvent.Send();
 
         if (m_activeLayerInvalid)
         {
           // We should not write the invalid layer back to the vector
           m_activeLayerInvalid = false;
         }
         else
         {
           AccessFixedDimensionByItk_n(this, ImageToLayerContainerProcessing, 4, (GetActiveLayer()));
         }
         m_ActiveLayer = layer;
         AccessFixedDimensionByItk_n(this, LayerContainerToImageProcessing, 4, (GetActiveLayer()));
 
         AfterChangeLayerEvent.Send();
       }
     }
     else
     {
       if ((layer != GetActiveLayer() || m_activeLayerInvalid) && (layer < this->GetNumberOfLayers()))
       {
         BeforeChangeLayerEvent.Send();
 
         if (m_activeLayerInvalid)
         {
           // We should not write the invalid layer back to the vector
           m_activeLayerInvalid = false;
         }
         else
         {
           AccessByItk_1(this, ImageToLayerContainerProcessing, GetActiveLayer());
         }
         m_ActiveLayer = layer;
         AccessByItk_1(this, LayerContainerToImageProcessing, GetActiveLayer());
 
         AfterChangeLayerEvent.Send();
       }
     }
   }
   catch (itk::ExceptionObject &e)
   {
     mitkThrow() << e.GetDescription();
   }
   this->Modified();
 }
 
 void mitk::LabelSetImage::SetActiveLabel(LabelValueType label)
 {
   m_ActiveLabelValue = label;
 
   if (label != UNLABELED_VALUE)
   {
     auto groupID = this->GetGroupIndexOfLabel(label);
     if (groupID!=this->GetActiveLayer()) this->SetActiveLayer(groupID);
   }
   Modified();
 }
 
 void mitk::LabelSetImage::ClearBuffer()
 {
   try
   {
     ClearImageBuffer(this);
     this->Modified();
   }
   catch (itk::ExceptionObject &e)
   {
     mitkThrow() << e.GetDescription();
   }
 }
 
-void mitk::LabelSetImage::MergeLabel(PixelType pixelValue, PixelType sourcePixelValue, unsigned int layer)
+void mitk::LabelSetImage::MergeLabel(PixelType pixelValue, PixelType sourcePixelValue)
 {
   try
   {
     AccessByItk_2(this, MergeLabelProcessing, pixelValue, sourcePixelValue);
   }
   catch (itk::ExceptionObject &e)
   {
     mitkThrow() << e.GetDescription();
   }
   this->SetActiveLabel(pixelValue);
   this->InvokeEvent(LabelModifiedEvent(sourcePixelValue));
   this->InvokeEvent(LabelModifiedEvent(pixelValue));
   this->InvokeEvent(LabelsChangedEvent({ sourcePixelValue, pixelValue }));
   Modified();
 }
 
-void mitk::LabelSetImage::MergeLabels(PixelType pixelValue, const std::vector<PixelType>& vectorOfSourcePixelValues, unsigned int layer)
+void mitk::LabelSetImage::MergeLabels(PixelType pixelValue, const std::vector<PixelType>& vectorOfSourcePixelValues)
 {
   try
   {
     for (unsigned int idx = 0; idx < vectorOfSourcePixelValues.size(); idx++)
     {
       AccessByItk_2(this, MergeLabelProcessing, pixelValue, vectorOfSourcePixelValues[idx]);
       this->InvokeEvent(LabelModifiedEvent(vectorOfSourcePixelValues[idx]));
     }
   }
   catch (itk::ExceptionObject &e)
   {
     mitkThrow() << e.GetDescription();
   }
   this->SetActiveLabel(pixelValue);
   this->InvokeEvent(LabelModifiedEvent(pixelValue));
   auto modifiedValues = vectorOfSourcePixelValues;
   modifiedValues.push_back(pixelValue);
   this->InvokeEvent(LabelsChangedEvent(modifiedValues));
 
   Modified();
 }
 
 void mitk::LabelSetImage::RemoveLabel(LabelValueType pixelValue)
 {
   if (m_LabelMap.find(pixelValue) == m_LabelMap.end()) return;
 
   auto groupID = this->GetGroupIndexOfLabel(pixelValue);
 
   //first erase the pixel content (also triggers a LabelModified event)
   this->EraseLabel(pixelValue);
   this->RemoveLabelFromMap(pixelValue);
 
 
   if (m_ActiveLabelValue == pixelValue)
   {
     this->SetActiveLabel(0);
   }
 
   this->InvokeEvent(LabelRemovedEvent(pixelValue));
   this->InvokeEvent(LabelsChangedEvent({ pixelValue }));
   this->InvokeEvent(GroupModifiedEvent(groupID));
 }
 
 void mitk::LabelSetImage::RemoveLabelFromMap(LabelValueType pixelValue)
 {
   if (m_LabelMap.find(pixelValue) == m_LabelMap.end()) mitkThrow()<<"Invalid state of of instance. RemoveLabelFromMap was called for unkown label id. invalid label id: "<<pixelValue;
 
   auto groupID = this->GetGroupIndexOfLabel(pixelValue);
 
   this->ReleaseLabel(m_LabelMap[pixelValue]);
   //now remove the label entry itself
   m_LabelMap.erase(pixelValue);
   m_LabelToGroupMap.erase(pixelValue);
   auto labelsInGroup = m_GroupToLabelMap[groupID];
   labelsInGroup.erase(std::remove(labelsInGroup.begin(), labelsInGroup.end(), pixelValue), labelsInGroup.end());
   m_GroupToLabelMap[groupID] = labelsInGroup;
 }
 
 void mitk::LabelSetImage::RemoveLabels(const LabelValueVectorType& vectorOfLabelPixelValues)
 {
   for (const auto labelValue : vectorOfLabelPixelValues)
   {
     this->RemoveLabel(labelValue);
   }
   this->InvokeEvent(LabelsChangedEvent(vectorOfLabelPixelValues));
 }
 
 void mitk::LabelSetImage::EraseLabel(LabelValueType pixelValue)
 {
   try
   {
     auto groupID = this->GetGroupIndexOfLabel(pixelValue);
 
     mitk::Image* groupImage = this->GetGroupImage(groupID);
 
     if (4 == this->GetDimension())
     {
       AccessFixedDimensionByItk_1(groupImage, EraseLabelProcessing, 4, pixelValue);
     }
     else
     {
       AccessByItk_1(groupImage, EraseLabelProcessing, pixelValue);
     }
   }
   catch (const itk::ExceptionObject& e)
   {
     mitkThrow() << e.GetDescription();
   }
 
   this->InvokeEvent(LabelModifiedEvent(pixelValue));
   this->InvokeEvent(LabelsChangedEvent({ pixelValue }));
   Modified();
 }
 
 void mitk::LabelSetImage::EraseLabels(const LabelValueVectorType& labelValues)
 {
   for (auto labelValue : labelValues)
   {
     this->EraseLabel(labelValue);
   }
 }
 
 mitk::LabelSetImage::LabelValueType mitk::LabelSetImage::GetUnusedLabelValue() const
 {
   auto usedValues = this->GetUsedLabelValues();
   return usedValues.back() + 1;
 }
 
 mitk::Label* mitk::LabelSetImage::AddLabel(mitk::Label* label, GroupIndexType groupID, bool addAsClone, bool correctLabelValue)
 {
   unsigned int max_size = mitk::Label::MAX_LABEL_VALUE + 1;
   if (m_LayerContainer.size() >= max_size)
     return nullptr;
 
   mitk::Label::Pointer newLabel = addAsClone ? label->Clone() : Label::Pointer(label);
 
   auto pixelValue = newLabel->GetValue();
   auto usedValues = this->GetUsedLabelValues();
   auto finding = std::find(usedValues.begin(), usedValues.end(), pixelValue);
 
   if (!usedValues.empty() && usedValues.end() != finding)
   {
     if (correctLabelValue)
     {
       pixelValue = this->GetUnusedLabelValue();
       newLabel->SetValue(pixelValue);
     }
     else
     {
       mitkThrow() << "Cannot add label due to conflicting label value that already exists in the MultiLabelSegmentation. Conflicting label value: " << pixelValue;
     }
   }
 
   // add DICOM information of the label
   DICOMSegmentationPropertyHelper::SetDICOMSegmentProperties(newLabel);
 
   this->AddLabelToMap(pixelValue, newLabel, groupID);
   this->RegisterLabel(newLabel);
 
   this->InvokeEvent(LabelAddedEvent(newLabel->GetValue()));
   m_ActiveLabelValue = newLabel->GetValue();
   this->Modified();
 
   return newLabel;
 }
 
 mitk::Label* mitk::LabelSetImage::AddLabel(const std::string& name, const mitk::Color& color, GroupIndexType groupID)
 {
   mitk::Label::Pointer newLabel = mitk::Label::New();
   newLabel->SetName(name);
   newLabel->SetColor(color);
   return AddLabel(newLabel,groupID,false);
 }
 
 void mitk::LabelSetImage::RenameLabel(LabelValueType pixelValue, const std::string& name, const mitk::Color& color)
 {
   mitk::Label* label = GetLabel(pixelValue);
   if (nullptr == label) mitkThrow() << "Cannot rename label.Unknown label value provided. Unkoen label value:" << pixelValue;
 
   label->SetName(name);
   label->SetColor(color);
 
   this->UpdateLookupTable(pixelValue);
   // change DICOM information of the label
   DICOMSegmentationPropertyHelper::SetDICOMSegmentProperties(label);
 }
 
 mitk::Label *mitk::LabelSetImage::GetActiveLabel()
 {
   if (m_ActiveLabelValue == UNLABELED_VALUE) return nullptr;
 
   auto finding = m_LabelMap.find(m_ActiveLabelValue);
   return finding == m_LabelMap.end() ? nullptr : finding->second;
 }
 
 const mitk::Label* mitk::LabelSetImage::GetActiveLabel() const
 {
   if (m_ActiveLabelValue == UNLABELED_VALUE) return nullptr;
 
   auto finding = m_LabelMap.find(m_ActiveLabelValue);
   return finding == m_LabelMap.end() ? nullptr : finding->second;
 }
 
 void mitk::LabelSetImage::UpdateCenterOfMass(PixelType pixelValue)
 {
   if (4 == this->GetDimension())
   {
     AccessFixedDimensionByItk_1(this->GetGroupImage(this->GetGroupIndexOfLabel(pixelValue)), CalculateCenterOfMassProcessing, 4, pixelValue);
   }
   else
   {
     AccessByItk_1(this->GetGroupImage(this->GetGroupIndexOfLabel(pixelValue)), CalculateCenterOfMassProcessing, pixelValue);
   }
 }
 
 void mitk::LabelSetImage::SetLookupTable(mitk::LookupTable* lut)
 {
   m_LookupTable = lut;
   this->Modified();
 }
 
 void mitk::LabelSetImage::UpdateLookupTable(PixelType pixelValue)
 {
   const mitk::Color& color = this->GetLabel(pixelValue)->GetColor();
 
   double rgba[4];
   m_LookupTable->GetTableValue(static_cast<int>(pixelValue), rgba);
   rgba[0] = color.GetRed();
   rgba[1] = color.GetGreen();
   rgba[2] = color.GetBlue();
   if (GetLabel(pixelValue)->GetVisible())
     rgba[3] = GetLabel(pixelValue)->GetOpacity();
   else
     rgba[3] = 0.0;
   m_LookupTable->SetTableValue(static_cast<int>(pixelValue), rgba);
 }
 
 unsigned int mitk::LabelSetImage::GetNumberOfLabels(unsigned int layer) const
 {
   if (layer >= m_Groups.size()) mitkThrow() << "Cannot get number of labels in group. Group is unkown. Invalid index:" << layer;
   return m_GroupToLabelMap[layer].size();
 }
 
 unsigned int mitk::LabelSetImage::GetTotalNumberOfLabels() const
 {
   return m_LabelMap.size();
 }
 
 void mitk::LabelSetImage::MaskStamp(mitk::Image *mask, bool forceOverwrite)
 {
   try
   {
     mitk::PadImageFilter::Pointer padImageFilter = mitk::PadImageFilter::New();
     padImageFilter->SetInput(0, mask);
     padImageFilter->SetInput(1, this);
     padImageFilter->SetPadConstant(0);
     padImageFilter->SetBinaryFilter(false);
     padImageFilter->SetLowerThreshold(0);
     padImageFilter->SetUpperThreshold(1);
 
     padImageFilter->Update();
 
     mitk::Image::Pointer paddedMask = padImageFilter->GetOutput();
 
     if (paddedMask.IsNull())
       return;
 
     AccessByItk_2(this, MaskStampProcessing, paddedMask, forceOverwrite);
   }
   catch (...)
   {
     mitkThrow() << "Could not stamp the provided mask on the selected label.";
   }
 }
 
 mitk::Image::Pointer mitk::LabelSetImage::CreateLabelMask(PixelType index)
 {
   if (!this->ExistLabel(index)) mitkThrow() << "Error, cannot return label mask. Label ID is invalid. Invalid ID: " << index;
 
   auto mask = mitk::Image::New();
 
   // mask->Initialize(this) does not work here if this label set image has a single slice,
   // since the mask would be automatically flattened to a 2-d image, whereas we expect the
   // original dimension of this label set image. Hence, initialize the mask more explicitly:
   mask->Initialize(this->GetPixelType(), this->GetDimension(), this->GetDimensions());
   mask->SetTimeGeometry(this->GetTimeGeometry()->Clone());
 
   ClearImageBuffer(mask);
 
   const auto groupID = this->GetGroupIndexOfLabel(index);
 
   auto destinationLabel = this->GetLabel(index)->Clone();
   destinationLabel->SetValue(1);
 
   TransferLabelContent(this->GetGroupImage(groupID), mask.GetPointer(),
     {destinationLabel},
     LabelSetImage::UNLABELED_VALUE, LabelSetImage::UNLABELED_VALUE, false,
     { { index, destinationLabel->GetValue()}}, MultiLabelSegmentation::MergeStyle::Replace, MultiLabelSegmentation::OverwriteStyle::IgnoreLocks);
 
   return mask;
 }
 
 void mitk::LabelSetImage::InitializeByLabeledImage(mitk::Image::Pointer image)
 {
   if (image.IsNull() || image->IsEmpty() || !image->IsInitialized())
     mitkThrow() << "Invalid labeled image.";
 
   try
   {
     this->Initialize(image);
 
     unsigned int byteSize = sizeof(LabelSetImage::PixelType);
     for (unsigned int dim = 0; dim < image->GetDimension(); ++dim)
     {
       byteSize *= image->GetDimension(dim);
     }
 
     mitk::ImageWriteAccessor *accessor = new mitk::ImageWriteAccessor(static_cast<mitk::Image *>(this));
     memset(accessor->GetData(), 0, byteSize);
     delete accessor;
 
     auto geometry = image->GetTimeGeometry()->Clone();
     this->SetTimeGeometry(geometry);
 
     if (image->GetDimension() == 3)
     {
       AccessTwoImagesFixedDimensionByItk(this, image, InitializeByLabeledImageProcessing, 3);
     }
     else if (image->GetDimension() == 4)
     {
       AccessTwoImagesFixedDimensionByItk(this, image, InitializeByLabeledImageProcessing, 4);
     }
     else
     {
       mitkThrow() << image->GetDimension() << "-dimensional label set images not yet supported";
     }
   }
-  catch (Exception e)
+  catch (Exception& e)
   {
     mitkReThrow(e) << "Could not intialize by provided labeled image.";
   }
   catch (...)
   {
     mitkThrow() << "Could not intialize by provided labeled image due to unkown error.";
   }
   this->Modified();
 }
 
 template <typename LabelSetImageType, typename ImageType>
 void mitk::LabelSetImage::InitializeByLabeledImageProcessing(LabelSetImageType *labelSetImage, ImageType *image)
 {
   typedef itk::ImageRegionConstIteratorWithIndex<ImageType> SourceIteratorType;
   typedef itk::ImageRegionIterator<LabelSetImageType> TargetIteratorType;
 
   TargetIteratorType targetIter(labelSetImage, labelSetImage->GetRequestedRegion());
   targetIter.GoToBegin();
 
   SourceIteratorType sourceIter(image, image->GetRequestedRegion());
   sourceIter.GoToBegin();
 
   while (!sourceIter.IsAtEnd())
   {
     const auto originalSourceValue = sourceIter.Get();
     const auto sourceValue = static_cast<PixelType>(originalSourceValue);
 
     if (originalSourceValue > mitk::Label::MAX_LABEL_VALUE)
     {
       mitkThrow() << "Cannot initialize MultiLabelSegmentation by image. Image contains a pixel value that exceeds the label value range. Invalid pixel value:" << originalSourceValue;
     }
 
     targetIter.Set(sourceValue);
 
     if (LabelSetImage::UNLABELED_VALUE!=sourceValue && !this->ExistLabel(sourceValue))
     {
       if (this->GetTotalNumberOfLabels() >= mitk::Label::MAX_LABEL_VALUE)
       {
         mitkThrow() << "Cannot initialize MultiLabelSegmentation by image. Image contains to many labels.";
       }
 
       std::stringstream name;
       name << "object-" << sourceValue;
 
       double rgba[4];
       this->GetLookupTable()->GetTableValue(sourceValue, rgba);
 
       mitk::Color color;
       color.SetRed(rgba[0]);
       color.SetGreen(rgba[1]);
       color.SetBlue(rgba[2]);
 
       auto label = mitk::Label::New();
       label->SetName(name.str().c_str());
       label->SetColor(color);
       label->SetOpacity(rgba[3]);
       label->SetValue(sourceValue);
 
       this->AddLabel(label,0,false);
     }
 
     ++sourceIter;
     ++targetIter;
   }
 }
 
 template <typename ImageType>
 void mitk::LabelSetImage::MaskStampProcessing(ImageType *itkImage, mitk::Image *mask, bool forceOverwrite)
 {
   typename ImageType::Pointer itkMask;
   mitk::CastToItkImage(mask, itkMask);
 
   typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
   typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
 
   SourceIteratorType sourceIter(itkMask, itkMask->GetLargestPossibleRegion());
   sourceIter.GoToBegin();
 
   TargetIteratorType targetIter(itkImage, itkImage->GetLargestPossibleRegion());
   targetIter.GoToBegin();
 
   const auto activeLabel = this->GetActiveLabel()->GetValue();
 
   while (!sourceIter.IsAtEnd())
   {
     PixelType sourceValue = sourceIter.Get();
     PixelType targetValue = targetIter.Get();
 
     if ((sourceValue != UNLABELED_VALUE) &&
         (forceOverwrite || !this->IsLabelLocked(targetValue))) // skip unlabeled pixels and locked labels
     {
       targetIter.Set(activeLabel);
     }
     ++sourceIter;
     ++targetIter;
   }
 
   this->Modified();
 }
 
 template <typename ImageType>
 void mitk::LabelSetImage::CalculateCenterOfMassProcessing(ImageType *itkImage, LabelValueType pixelValue)
 {
   if (ImageType::GetImageDimension() != 3)
   {
     return;
   }
 
   auto labelGeometryFilter = itk::LabelGeometryImageFilter<ImageType>::New();
   labelGeometryFilter->SetInput(itkImage);
   labelGeometryFilter->Update();
   auto centroid = labelGeometryFilter->GetCentroid(pixelValue);
 
   mitk::Point3D pos;
   pos[0] = centroid[0];
   pos[1] = centroid[1];
   pos[2] = centroid[2];
 
   this->GetLabel(pixelValue)->SetCenterOfMassIndex(pos);
   this->GetSlicedGeometry()->IndexToWorld(pos, pos);
   this->GetLabel(pixelValue)->SetCenterOfMassCoordinates(pos);
 }
 
 template <typename TPixel, unsigned int VImageDimension>
 void mitk::LabelSetImage::LayerContainerToImageProcessing(itk::Image<TPixel, VImageDimension> *target,
                                                           unsigned int layer)
 {
   typedef itk::Image<TPixel, VImageDimension> ImageType;
   typename ImageType::Pointer itkSource;
   // mitk::CastToItkImage(m_LayerContainer[layer], itkSource);
   itkSource = ImageToItkImage<TPixel, VImageDimension>(m_LayerContainer[layer]);
   typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
   typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
 
   SourceIteratorType sourceIter(itkSource, itkSource->GetLargestPossibleRegion());
   sourceIter.GoToBegin();
 
   TargetIteratorType targetIter(target, target->GetLargestPossibleRegion());
   targetIter.GoToBegin();
 
   while (!sourceIter.IsAtEnd())
   {
     targetIter.Set(sourceIter.Get());
     ++sourceIter;
     ++targetIter;
   }
 }
 
 template <typename TPixel, unsigned int VImageDimension>
 void mitk::LabelSetImage::ImageToLayerContainerProcessing(itk::Image<TPixel, VImageDimension> *source,
                                                           unsigned int layer) const
 {
   typedef itk::Image<TPixel, VImageDimension> ImageType;
   typename ImageType::Pointer itkTarget;
   // mitk::CastToItkImage(m_LayerContainer[layer], itkTarget);
   itkTarget = ImageToItkImage<TPixel, VImageDimension>(m_LayerContainer[layer]);
 
   typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
   typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
 
   SourceIteratorType sourceIter(source, source->GetLargestPossibleRegion());
   sourceIter.GoToBegin();
 
   TargetIteratorType targetIter(itkTarget, itkTarget->GetLargestPossibleRegion());
   targetIter.GoToBegin();
 
   while (!sourceIter.IsAtEnd())
   {
     targetIter.Set(sourceIter.Get());
     ++sourceIter;
     ++targetIter;
   }
 }
 
 template <typename ImageType>
 void mitk::LabelSetImage::EraseLabelProcessing(ImageType *itkImage, PixelType pixelValue)
 {
   typedef itk::ImageRegionIterator<ImageType> IteratorType;
 
   IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion());
   iter.GoToBegin();
 
   while (!iter.IsAtEnd())
   {
     PixelType value = iter.Get();
 
     if (value == pixelValue)
     {
       iter.Set(0);
     }
     ++iter;
   }
 }
 
 template <typename ImageType>
 void mitk::LabelSetImage::MergeLabelProcessing(ImageType *itkImage, PixelType pixelValue, PixelType index)
 {
   typedef itk::ImageRegionIterator<ImageType> IteratorType;
 
   IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion());
   iter.GoToBegin();
 
   while (!iter.IsAtEnd())
   {
     if (iter.Get() == index)
     {
       iter.Set(pixelValue);
     }
     ++iter;
   }
 }
 
 void mitk::LabelSetImage::AddLabelToMap(LabelValueType labelValue, mitk::Label* label, GroupIndexType groupID)
 {
   if (m_LabelMap.find(labelValue)!=m_LabelMap.end())
     mitkThrow() << "Segmentation is in an invalid state: Label value collision. A label was added with a LabelValue already in use. LabelValue: " << labelValue;
 
   if (!this->ExistGroup(groupID))
     mitkThrow() << "Cannot add label. Defined group is unkown. Invalid group index: " << groupID;
 
   m_LabelMap[labelValue] = label;
   m_LabelToGroupMap[labelValue] = groupID;
   auto groupFinding = std::find(m_GroupToLabelMap[groupID].begin(), m_GroupToLabelMap[groupID].end(), labelValue);
   if (groupFinding == m_GroupToLabelMap[groupID].end())
   {
     m_GroupToLabelMap[groupID].push_back(labelValue);
   }
 }
 
 void mitk::LabelSetImage::RegisterLabel(mitk::Label* label)
 {
   UpdateLookupTable(label->GetValue());
 
   auto command = itk::MemberCommand<LabelSetImage>::New();
   command->SetCallbackFunction(this, &LabelSetImage::OnLabelModified);
   label->AddObserver(itk::ModifiedEvent(), command);
 }
 
 void mitk::LabelSetImage::ReleaseLabel(Label* label)
 {
   if (nullptr == label) mitkThrow() << "Invalid call of ReleaseLabel with a nullptr.";
   label->RemoveAllObservers();
 }
 
 void mitk::LabelSetImage::ApplyToLabels(const LabelValueVectorType& values, std::function<void(Label*)>&& lambda)
 {
   auto labels = this->GetLabelsByValue(values);
   std::for_each(labels.begin(), labels.end(), lambda);
   this->InvokeEvent(LabelsChangedEvent(values));
 }
 
 void mitk::LabelSetImage::VisitLabels(const LabelValueVectorType& values, std::function<void(const Label*)>&& lambda) const
 {
   auto labels = this->GetConstLabelsByValue(values);
   std::for_each(labels.begin(), labels.end(), lambda);
 }
 
 
 void mitk::LabelSetImage::OnLabelModified(const Object* sender, const itk::EventObject&)
 {
   auto label = dynamic_cast<const Label*>(sender);
   if (nullptr == label)
     mitkThrow() << "LabelSet is in wrong state. LabelModified event is not send by a label instance.";
 
   Superclass::Modified();
   this->InvokeEvent(LabelModifiedEvent(label->GetValue()));
 }
 
 bool mitk::LabelSetImage::ExistLabel(LabelValueType value) const
 {
   auto finding = m_LabelMap.find(value);
   return m_LabelMap.end() != finding;
 }
 
 bool mitk::LabelSetImage::ExistLabel(LabelValueType value, GroupIndexType groupIndex) const
 {
   auto finding = m_LabelToGroupMap.find(value);
   if (m_LabelToGroupMap.end() != finding)
   {
     return finding->second == groupIndex;
   }
   return false;
 }
 
 bool mitk::LabelSetImage::ExistGroup(GroupIndexType index) const
 {
   return index < m_LayerContainer.size();
 }
 
 mitk::LabelSetImage::GroupIndexType mitk::LabelSetImage::GetGroupIndexOfLabel(LabelValueType value) const
 {
   auto finding = m_LabelToGroupMap.find(value);
   if (m_LabelToGroupMap.end() == finding)
   {
     mitkThrow()<< "Cannot deduce group index. Passed label value does not exist. Value: "<< value;
   }
   return finding->second;
 }
 
 
 const mitk::Label* mitk::LabelSetImage::GetLabel(LabelValueType value) const
 {
   auto finding = m_LabelMap.find(value);
   if (m_LabelMap.end() != finding)
   {
     return finding->second;
   }
   return nullptr;
 };
 
 mitk::Label* mitk::LabelSetImage::GetLabel(LabelValueType value)
 {
   auto finding = m_LabelMap.find(value);
   if (m_LabelMap.end() != finding)
   {
     return finding->second;
   }
   return nullptr;
 };
 
 bool mitk::LabelSetImage::IsLabelLocked(LabelValueType value) const
 {
   if (value == UNLABELED_VALUE)
   {
     return m_UnlabeledLabelLock;
   }
 
   const auto label = this->GetLabel(value);
   return label->GetLocked();
 }
 
 const mitk::LabelSetImage::ConstLabelVectorType mitk::LabelSetImage::GetLabels() const
 {
   ConstLabelVectorType result;
   for (auto [value, label] : m_LabelMap)
   {
     result.emplace_back(label);
   }
   return result;
 }
 
 const mitk::LabelSetImage::LabelVectorType mitk::LabelSetImage::GetLabels()
 {
   LabelVectorType result;
   for (auto [value, label] : m_LabelMap)
   {
     result.emplace_back(label);
   }
   return result;
 }
 
 const mitk::LabelSetImage::LabelVectorType mitk::LabelSetImage::GetLabelsByValue(const LabelValueVectorType& labelValues, bool ignoreMissing)
 {
   LabelVectorType result;
   for (const auto& labelValue : labelValues)
   {
     auto* label = this->GetLabel(labelValue);
 
     if (label != nullptr)
     {
       result.emplace_back(label);
     }
     else if (!ignoreMissing) mitkThrow() << "Error cannot get labels by Value. At least one passed value is unknown. Unknown value: " << labelValue;
   }
   return result;
 }
 
 const mitk::LabelSetImage::ConstLabelVectorType mitk::LabelSetImage::GetConstLabelsByValue(const LabelValueVectorType& labelValues, bool ignoreMissing) const
 {
   ConstLabelVectorType result;
   for (const auto& labelValue : labelValues)
   {
     const auto* label = this->GetLabel(labelValue);
 
     if (label != nullptr)
     {
       result.emplace_back(label);
     }
     else if (!ignoreMissing) mitkThrow() << "Error cannot get labels by Value. At least one passed value is unknown. Unknown value: " << labelValue;
   }
   return result;
 }
 
 const mitk::LabelSetImage::LabelValueVectorType mitk::LabelSetImage::GetLabelValuesByGroup(GroupIndexType index) const
 {
   if (!this->ExistGroup(index))
     mitkThrow() << "Cannot get labels of an invalid group. Invalid group index: " << index;
 
   return m_GroupToLabelMap[index];
 }
 
 const mitk::LabelSetImage::LabelValueVectorType mitk::LabelSetImage::GetLabelValuesByName(GroupIndexType index, std::string_view name) const
 {
   LabelValueVectorType result;
 
   auto searchName = [&result, name](const Label* l) { if(l->GetName() == name) result.push_back(l->GetValue()); };
 
   this->VisitLabels(this->GetLabelValuesByGroup(index), searchName);
 
   return result;
 }
 
 std::vector<std::string> mitk::LabelSetImage::GetLabelClassNames() const
 {
   std::set<std::string> names;
   auto searchName = [&names](const Label* l) { names.emplace(l->GetName()); };
   this->VisitLabels(this->GetAllLabelValues(), searchName);
 
   return std::vector<std::string>(names.begin(), names.end());
 }
 
 std::vector<std::string> mitk::LabelSetImage::GetLabelClassNamesByGroup(GroupIndexType index) const
 {
   std::set<std::string> names;
   auto searchName = [&names](const Label* l) { names.emplace(l->GetName()); };
   this->VisitLabels(this->GetLabelValuesByGroup(index), searchName);
 
   return std::vector<std::string>(names.begin(), names.end());
 }
 
 void mitk::LabelSetImage::SetAllLabelsVisible(bool visible)
 {
   auto setVisibility = [visible](Label* l) { l->SetVisible(visible); };
 
   this->ApplyToLabels(this->GetAllLabelValues(), setVisibility);
 }
 
 void mitk::LabelSetImage::SetAllLabelsVisibleByGroup(GroupIndexType group, bool visible)
 {
   auto setVisibility = [visible](Label* l) { l->SetVisible(visible); };
 
   this->ApplyToLabels(this->GetLabelValuesByGroup(group), setVisibility);
 }
 
 void mitk::LabelSetImage::SetAllLabelsVisibleByName(GroupIndexType group, std::string_view name, bool visible)
 {
   auto setVisibility = [visible](Label* l) { l->SetVisible(visible); };
 
   this->ApplyToLabels(this->GetLabelValuesByName(group, name), setVisibility);
 }
 
 void mitk::LabelSetImage::SetAllLabelsLocked(bool locked)
 {
   auto setLock = [locked](Label* l) { l->SetLocked(locked); };
 
   this->ApplyToLabels(this->GetAllLabelValues(), setLock);
 }
 
 void mitk::LabelSetImage::SetAllLabelsLockedByGroup(GroupIndexType group, bool locked)
 {
   auto setLock = [locked](Label* l) { l->SetLocked(locked); };
 
   this->ApplyToLabels(this->GetLabelValuesByGroup(group), setLock);
 }
 
 void mitk::LabelSetImage::SetAllLabelsLockedByName(GroupIndexType group, std::string_view name, bool locked)
 {
   auto setLock = [locked](Label* l) { l->SetLocked(locked); };
 
   this->ApplyToLabels(this->GetLabelValuesByName(group, name), setLock);
 }
 
 bool mitk::Equal(const mitk::LabelSetImage &leftHandSide,
                  const mitk::LabelSetImage &rightHandSide,
                  ScalarType eps,
                  bool verbose)
 {
   bool returnValue = true;
 
   /* LabelSetImage members */
 
   MITK_INFO(verbose) << "--- LabelSetImage Equal ---";
 
   // m_LookupTable;
   const mitk::LookupTable* lhsLUT = leftHandSide.GetLookupTable();
   const mitk::LookupTable* rhsLUT = rightHandSide.GetLookupTable();
 
   returnValue = *lhsLUT == *rhsLUT;
   if (!returnValue)
   {
     MITK_INFO(verbose) << "Lookup tabels not equal.";
     return returnValue;
     ;
   }
 
   // number layers
   returnValue = leftHandSide.GetNumberOfLayers() == rightHandSide.GetNumberOfLayers();
   if (!returnValue)
   {
     MITK_INFO(verbose) << "Number of layers not equal.";
     return false;
   }
 
   // total number labels
   returnValue = leftHandSide.GetTotalNumberOfLabels() == rightHandSide.GetTotalNumberOfLabels();
   if (!returnValue)
   {
     MITK_INFO(verbose) << "Total number of labels not equal.";
     return false;
   }
 
   // active layer
   returnValue = leftHandSide.GetActiveLayer() == rightHandSide.GetActiveLayer();
   if (!returnValue)
   {
     MITK_INFO(verbose) << "Active layer not equal.";
     return false;
   }
 
   if (4 == leftHandSide.GetDimension())
   {
     MITK_INFO(verbose) << "Can not compare image data for 4D images - skipping check.";
   }
   else
   {
     // working image data
     returnValue = mitk::Equal((const mitk::Image &)leftHandSide, (const mitk::Image &)rightHandSide, eps, verbose);
     if (!returnValue)
     {
       MITK_INFO(verbose) << "Working image data not equal.";
       return false;
     }
   }
 
   if (leftHandSide.GetTotalNumberOfLabels() != rightHandSide.GetTotalNumberOfLabels())
   {
     MITK_INFO(verbose) << "Number of labels are not equal.";
     return false;
   }
 
   for (unsigned int layerIndex = 0; layerIndex < leftHandSide.GetNumberOfLayers(); layerIndex++)
   {
     if (4 == leftHandSide.GetDimension())
     {
       MITK_INFO(verbose) << "Can not compare image data for 4D images - skipping check.";
     }
     else
     {
       // layer image data
       returnValue =
         mitk::Equal(*leftHandSide.GetGroupImage(layerIndex), *rightHandSide.GetGroupImage(layerIndex), eps, verbose);
       if (!returnValue)
       {
         MITK_INFO(verbose) << "Layer image data not equal.";
         return false;
       }
     }
 
     // label data
     auto leftLabelsInGroup = leftHandSide.GetLabelValuesByGroup(layerIndex);
     auto rightLabelsInGroup = rightHandSide.GetLabelValuesByGroup(layerIndex);
 
     if (leftLabelsInGroup.size()!=rightLabelsInGroup.size())
     {
       MITK_INFO(verbose) << "Number of layer labels is not equal. Invalid layer:" <<layerIndex;
       return false;
     }
 
     for (ConstLabelVector::size_type index = 0; index < leftLabelsInGroup.size(); ++index)
     {
       if (!mitk::Equal(*(leftHandSide.GetLabel(leftLabelsInGroup[index])), *(rightHandSide.GetLabel(rightLabelsInGroup[index])),eps,verbose))
       {
         MITK_INFO(verbose) << "At least one label in layer is not equal. Invalid layer:" << layerIndex;
         return false;
       }
     }
   }
 
   return returnValue;
 }
 
 bool mitk::Equal(const mitk::LabelSetImage::ConstLabelVectorType& leftHandSide,
   const mitk::LabelSetImage::ConstLabelVectorType& rightHandSide, ScalarType eps, bool verbose)
 {
   bool returnValue = true;
 
   // container size;
   returnValue = leftHandSide.size() == rightHandSide.size();
   if (!returnValue)
   {
     MITK_INFO(verbose) << "Number of labels not equal.";
     return returnValue;
     ;
   }
 
   // m_LabelContainer;
   auto lhsit = leftHandSide.begin();
   auto rhsit = rightHandSide.begin();
   for (; lhsit != leftHandSide.end(); ++lhsit, ++rhsit)
   {
     returnValue = mitk::Equal(**rhsit, **lhsit,eps,verbose);
     if (!returnValue)
     {
       MITK_INFO(verbose) << "Label in label container not equal.";
       return returnValue;
       ;
     }
   }
 
   return returnValue;
 }
 
 /**Helper function to convert a vector of labels into a label map
  * @pre every label in the vector has a unique value.*/
 using ConstLabelMapType = std::map<mitk::LabelSetImage::LabelValueType, mitk::Label::ConstPointer>;
 ConstLabelMapType ConvertLabelVectorToMap(const mitk::ConstLabelVector& labelV)
 {
   ConstLabelMapType result;
   for (auto label : labelV)
   {
     const auto value = label->GetValue();
     auto finding = result.find(value);
     if (finding != result.end()) mitkThrow() << "Operation failed. Cannot convert label vector into label map, because at least one label value is not unique. Violating label value: " << value;
     result.insert(std::make_pair(value, label));
   }
 
   return result;
 }
 
 
 /** Functor class that implements the label transfer and is used in conjunction with the itk::BinaryFunctorImageFilter.
 * For details regarding the usage of the filter and the functor patterns, please see info of itk::BinaryFunctorImageFilter.
 */
 template <class TDestinationPixel, class TSourcePixel, class TOutputpixel>
 class LabelTransferFunctor
 {
 
 public:
   LabelTransferFunctor() {};
 
   LabelTransferFunctor(const ConstLabelMapType& destinationLabels, mitk::Label::PixelType sourceBackground,
     mitk::Label::PixelType destinationBackground, bool destinationBackgroundLocked,
     mitk::Label::PixelType sourceLabel, mitk::Label::PixelType newDestinationLabel, mitk::MultiLabelSegmentation::MergeStyle mergeStyle,
     mitk::MultiLabelSegmentation::OverwriteStyle overwriteStyle) :
     m_DestinationLabels(destinationLabels), m_SourceBackground(sourceBackground),
     m_DestinationBackground(destinationBackground), m_DestinationBackgroundLocked(destinationBackgroundLocked),
     m_SourceLabel(sourceLabel), m_NewDestinationLabel(newDestinationLabel), m_MergeStyle(mergeStyle), m_OverwriteStyle(overwriteStyle)
   {
   };
 
   ~LabelTransferFunctor() {};
 
   bool operator!=(const LabelTransferFunctor& other)const
   {
     return !(*this == other);
   }
   bool operator==(const LabelTransferFunctor& other) const
   {
     return this->m_SourceBackground == other.m_SourceBackground &&
       this->m_DestinationBackground == other.m_DestinationBackground &&
       this->m_DestinationBackgroundLocked == other.m_DestinationBackgroundLocked &&
       this->m_SourceLabel == other.m_SourceLabel &&
       this->m_NewDestinationLabel == other.m_NewDestinationLabel &&
       this->m_MergeStyle == other.m_MergeStyle &&
       this->m_OverwriteStyle == other.m_OverwriteStyle &&
       this->m_DestinationLabels == other.m_DestinationLabels;
   }
 
   LabelTransferFunctor& operator=(const LabelTransferFunctor& other)
   {
     this->m_DestinationLabels = other.m_DestinationLabels;
     this->m_SourceBackground = other.m_SourceBackground;
     this->m_DestinationBackground = other.m_DestinationBackground;
     this->m_DestinationBackgroundLocked = other.m_DestinationBackgroundLocked;
     this->m_SourceLabel = other.m_SourceLabel;
     this->m_NewDestinationLabel = other.m_NewDestinationLabel;
     this->m_MergeStyle = other.m_MergeStyle;
     this->m_OverwriteStyle = other.m_OverwriteStyle;
 
     return *this;
   }
 
   inline TOutputpixel operator()(const TDestinationPixel& existingDestinationValue, const TSourcePixel& existingSourceValue)
   {
     if (existingSourceValue == this->m_SourceLabel)
     {
       if (mitk::MultiLabelSegmentation::OverwriteStyle::IgnoreLocks == this->m_OverwriteStyle)
       {
         return this->m_NewDestinationLabel;
       }
       else
       {
         if (existingDestinationValue == m_DestinationBackground)
         {
           if (!m_DestinationBackgroundLocked)
           {
             return this->m_NewDestinationLabel;
           }
         }
         else
         {
           auto labelFinding = this->m_DestinationLabels.find(existingDestinationValue);
           if (labelFinding==this->m_DestinationLabels.end() || !labelFinding->second->GetLocked())
           {
             return this->m_NewDestinationLabel;
           }
         }
       }
     }
     else if (mitk::MultiLabelSegmentation::MergeStyle::Replace == this->m_MergeStyle
       && existingSourceValue == this->m_SourceBackground
       && existingDestinationValue == this->m_NewDestinationLabel
       && (mitk::MultiLabelSegmentation::OverwriteStyle::IgnoreLocks == this->m_OverwriteStyle
           || !this->m_DestinationBackgroundLocked))
     {
       return this->m_DestinationBackground;
     }
 
     return existingDestinationValue;
   }
 
 private:
   ConstLabelMapType m_DestinationLabels;
   mitk::Label::PixelType m_SourceBackground = 0;
   mitk::Label::PixelType m_DestinationBackground = 0;
   bool m_DestinationBackgroundLocked = false;
   mitk::Label::PixelType m_SourceLabel = 1;
   mitk::Label::PixelType m_NewDestinationLabel = 1;
   mitk::MultiLabelSegmentation::MergeStyle m_MergeStyle = mitk::MultiLabelSegmentation::MergeStyle::Replace;
   mitk::MultiLabelSegmentation::OverwriteStyle m_OverwriteStyle = mitk::MultiLabelSegmentation::OverwriteStyle::RegardLocks;
 };
 
 /**Helper function used by TransferLabelContentAtTimeStep to allow the templating over different image dimensions in conjunction of AccessFixedPixelTypeByItk_n.*/
 template<unsigned int VImageDimension>
 void TransferLabelContentAtTimeStepHelper(const itk::Image<mitk::Label::PixelType, VImageDimension>* itkSourceImage, mitk::Image* destinationImage,
   const mitk::ConstLabelVector& destinationLabels, mitk::Label::PixelType sourceBackground, mitk::Label::PixelType destinationBackground,
   bool destinationBackgroundLocked, mitk::Label::PixelType sourceLabel, mitk::Label::PixelType newDestinationLabel, mitk::MultiLabelSegmentation::MergeStyle mergeStyle, mitk::MultiLabelSegmentation::OverwriteStyle overwriteStyle)
 {
   typedef itk::Image<mitk::Label::PixelType, VImageDimension> ContentImageType;
   typename ContentImageType::Pointer itkDestinationImage;
   mitk::CastToItkImage(destinationImage, itkDestinationImage);
 
   auto sourceRegion = itkSourceImage->GetLargestPossibleRegion();
   auto relevantRegion = itkDestinationImage->GetLargestPossibleRegion();
   bool overlapping = relevantRegion.Crop(sourceRegion);
 
   if (!overlapping)
   {
     mitkThrow() << "Invalid call of TransferLabelContentAtTimeStep; sourceImage and destinationImage seem to have no overlapping image region.";
   }
 
   typedef LabelTransferFunctor <mitk::Label::PixelType, mitk::Label::PixelType, mitk::Label::PixelType> LabelTransferFunctorType;
   typedef itk::BinaryFunctorImageFilter<ContentImageType, ContentImageType, ContentImageType, LabelTransferFunctorType> FilterType;
 
   LabelTransferFunctorType transferFunctor(ConvertLabelVectorToMap(destinationLabels), sourceBackground, destinationBackground,
     destinationBackgroundLocked, sourceLabel, newDestinationLabel, mergeStyle, overwriteStyle);
 
   auto transferFilter = FilterType::New();
 
   transferFilter->SetFunctor(transferFunctor);
   transferFilter->InPlaceOn();
   transferFilter->SetInput1(itkDestinationImage);
   transferFilter->SetInput2(itkSourceImage);
   transferFilter->GetOutput()->SetRequestedRegion(relevantRegion);
 
   transferFilter->Update();
 }
 
 void mitk::TransferLabelContentAtTimeStep(
   const Image* sourceImage, Image* destinationImage, const mitk::ConstLabelVector& destinationLabels, const TimeStepType timeStep, mitk::Label::PixelType sourceBackground,
   mitk::Label::PixelType destinationBackground, bool destinationBackgroundLocked, LabelValueMappingVector labelMapping,
   MultiLabelSegmentation::MergeStyle mergeStyle, MultiLabelSegmentation::OverwriteStyle overwriteStlye)
 {
   if (nullptr == sourceImage)
   {
     mitkThrow() << "Invalid call of TransferLabelContentAtTimeStep; sourceImage must not be null.";
   }
   if (nullptr == destinationImage)
   {
     mitkThrow() << "Invalid call of TransferLabelContentAtTimeStep; destinationImage must not be null.";
   }
 
   if (sourceImage == destinationImage && labelMapping.size() > 1)
   {
     MITK_DEBUG << "Warning. Using TransferLabelContentAtTimeStep or TransferLabelContent with equal source and destination and more then on label to transfer, can lead to wrong results. Please see documentation and verify that the usage is OK.";
   }
 
   Image::ConstPointer sourceImageAtTimeStep = SelectImageByTimeStep(sourceImage, timeStep);
   Image::Pointer destinationImageAtTimeStep = SelectImageByTimeStep(destinationImage, timeStep);
 
   if (nullptr == sourceImageAtTimeStep)
   {
     mitkThrow() << "Invalid call of TransferLabelContentAtTimeStep; sourceImage does not have the requested time step: " << timeStep;
   }
   if (nullptr == destinationImageAtTimeStep)
   {
     mitkThrow() << "Invalid call of TransferLabelContentAtTimeStep; destinationImage does not have the requested time step: " << timeStep;
   }
 
   auto destLabelMap = ConvertLabelVectorToMap(destinationLabels);
   for (const auto& [sourceLabel, newDestinationLabel] : labelMapping)
   {
     if (LabelSetImage::UNLABELED_VALUE!=newDestinationLabel && destLabelMap.end() == destLabelMap.find(newDestinationLabel))
     {
       mitkThrow() << "Invalid call of TransferLabelContentAtTimeStep. Defined destination label does not exist in destinationImage. newDestinationLabel: " << newDestinationLabel;
     }
 
     AccessFixedPixelTypeByItk_n(sourceImageAtTimeStep, TransferLabelContentAtTimeStepHelper, (Label::PixelType), (destinationImageAtTimeStep, destinationLabels, sourceBackground, destinationBackground, destinationBackgroundLocked, sourceLabel, newDestinationLabel, mergeStyle, overwriteStlye));
   }
   destinationImage->Modified();
 }
 
 void mitk::TransferLabelContent(
   const Image* sourceImage, Image* destinationImage, const mitk::ConstLabelVector& destinationLabels, mitk::Label::PixelType sourceBackground,
   mitk::Label::PixelType destinationBackground, bool destinationBackgroundLocked, LabelValueMappingVector labelMapping,
   MultiLabelSegmentation::MergeStyle mergeStyle, MultiLabelSegmentation::OverwriteStyle overwriteStlye)
 {
   if (nullptr == sourceImage)
   {
     mitkThrow() << "Invalid call of TransferLabelContent; sourceImage must not be null.";
   }
   if (nullptr == destinationImage)
   {
     mitkThrow() << "Invalid call of TransferLabelContent; destinationImage must not be null.";
   }
 
   const auto sourceTimeStepCount = sourceImage->GetTimeGeometry()->CountTimeSteps();
   if (sourceTimeStepCount != destinationImage->GetTimeGeometry()->CountTimeSteps())
   {
     mitkThrow() << "Invalid call of TransferLabelContent; mismatch between images in number of time steps.";
   }
 
   for (mitk::TimeStepType i = 0; i < sourceTimeStepCount; ++i)
   {
     TransferLabelContentAtTimeStep(sourceImage, destinationImage, destinationLabels, i, sourceBackground,
       destinationBackground, destinationBackgroundLocked, labelMapping, mergeStyle, overwriteStlye);
   }
 }
 
 void mitk::TransferLabelContentAtTimeStep(
   const LabelSetImage* sourceImage, LabelSetImage* destinationImage, const TimeStepType timeStep,
   LabelValueMappingVector labelMapping,
   MultiLabelSegmentation::MergeStyle mergeStyle, MultiLabelSegmentation::OverwriteStyle overwriteStlye)
 {
   if (nullptr == sourceImage)
   {
     mitkThrow() << "Invalid call of TransferLabelContentAtTimeStep; sourceImage must not be null.";
   }
 
   auto destinationLabels = destinationImage->GetConstLabelsByValue(destinationImage->GetLabelValuesByGroup(destinationImage->GetActiveLayer()));
 
   for (const auto& mappingElement : labelMapping)
   {
     if (LabelSetImage::UNLABELED_VALUE != mappingElement.first && !sourceImage->ExistLabel(mappingElement.first, sourceImage->GetActiveLayer()))
     {
       mitkThrow() << "Invalid call of TransferLabelContentAtTimeStep. Defined source label does not exist in sourceImage. SourceLabel: " << mappingElement.first;
     }
   }
 
   TransferLabelContentAtTimeStep(sourceImage, destinationImage, destinationLabels, timeStep, LabelSetImage::UNLABELED_VALUE, LabelSetImage::UNLABELED_VALUE, destinationImage->GetUnlabeledLabelLock(),
     labelMapping, mergeStyle, overwriteStlye);
 }
 
 void mitk::TransferLabelContent(
   const LabelSetImage* sourceImage, LabelSetImage* destinationImage,
   LabelValueMappingVector labelMapping,
   MultiLabelSegmentation::MergeStyle mergeStyle, MultiLabelSegmentation::OverwriteStyle overwriteStlye)
 {
   if (nullptr == sourceImage)
   {
     mitkThrow() << "Invalid call of TransferLabelContent; sourceImage must not be null.";
   }
   if (nullptr == destinationImage)
   {
     mitkThrow() << "Invalid call of TransferLabelContent; destinationImage must not be null.";
   }
 
   const auto sourceTimeStepCount = sourceImage->GetTimeGeometry()->CountTimeSteps();
   if (sourceTimeStepCount != destinationImage->GetTimeGeometry()->CountTimeSteps())
   {
     mitkThrow() << "Invalid call of TransferLabelContent; images have no equal number of time steps.";
   }
 
   for (mitk::TimeStepType i = 0; i < sourceTimeStepCount; ++i)
   {
     TransferLabelContentAtTimeStep(sourceImage, destinationImage, i, labelMapping, mergeStyle, overwriteStlye);
   }
 }
 
diff --git a/Modules/Multilabel/mitkLabelSetImage.h b/Modules/Multilabel/mitkLabelSetImage.h
index 454a5f6e4a..8d954fa01e 100644
--- a/Modules/Multilabel/mitkLabelSetImage.h
+++ b/Modules/Multilabel/mitkLabelSetImage.h
@@ -1,674 +1,672 @@
 /*============================================================================
 
 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 mitkLabelSetImage_h
 #define mitkLabelSetImage_h
 
 #include <mitkImage.h>
 #include <mitkLabel.h>
 #include <mitkLookupTable.h>
 #include <mitkMultiLabelEvents.h>
 #include <mitkMessage.h>
 
 #include <MitkMultilabelExports.h>
 
 namespace mitk
 {
   /** @brief LabelSetImage class for handling labels and layers in a segmentation session.
   *
   * Events that are potentially send by the class in regard to groups or labels:
   * - LabelAddedEvent is emitted whenever a new label has been added.
   * - LabelModifiedEvent is emitted whenever a label has been modified.
   * - LabelRemovedEvent is emitted whenever a label has been removed.
   * - LabelsChangedEvent is emitted when labels are changed (added, removed, modified). In difference to the other label events LabelsChanged is send only *one time* after the modification of the
   * MultiLableImage instance is finished. So e.g. even if 4 labels are changed by a merge operation, this event will
   * only be sent once (compared to LabelRemoved or LabelModified).
   * - GroupAddedEvent is emitted whenever a new group has been added.
   * - GroupModifiedEvent is emitted whenever a group has been modified.
   * - GroupRemovedEvent is emitted whenever a label has been removed.
   *
   * @ingroup Data
   */
   class MITKMULTILABEL_EXPORT LabelSetImage : public Image
   {
   public:
     /**
     * \brief BeforeChangeLayerEvent (e.g. used for GUI integration)
     * As soon as active labelset should be changed, the signal emits.
     * Emitted by SetActiveLayer(int layer);
     */
     Message<> BeforeChangeLayerEvent;
 
     /**
     * \brief AfterchangeLayerEvent (e.g. used for GUI integration)
     * As soon as active labelset was changed, the signal emits.
     * Emitted by SetActiveLayer(int layer);
     */
     Message<> AfterChangeLayerEvent;
 
     ///////////////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////////////
     // FUTURE MultiLabelSegmentation:
     // Section that already contains declarations used in the new class.
     // So this part of the interface will stay after refactoring towards
     // the new MultiLabelSegmentation class (see T28524). This section was introduced
     // because some of the planned features are already urgently needed.
     ///////////////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////////////
     mitkClassMacro(LabelSetImage, Image);
     itkNewMacro(Self);
 
     typedef mitk::Label::PixelType PixelType;
 
     using GroupIndexType = std::size_t;
     using LabelValueType = mitk::Label::PixelType;
     using ConstLabelVectorType = ConstLabelVector;
     using LabelVectorType = LabelVector;
     using LabelValueVectorType = std::vector<LabelValueType>;
 
     const static LabelValueType UNLABELED_VALUE;
 
     /** \brief Adds a label instance to a group of the multi label image.
     * @remark By default, if the pixel value of the label is already used in the image, the label
     * will get a new none conflicting value assigned. This can be controlled by correctLabelValue.
     * @param label Instance of an label that should be added or used as template
     * @param groupID The id of the group the label should be added to.
     * @param addAsClone Flag that controls, if the passed instance should be added (false; the image will then take ownership,
     * be aware that e.g. event observers will be added)
     * a clone of the instance (true).
     * @param correctLabelValue Flag that controls, if the value of the passed label should be correct, if this value is already used in
     * the multi label image. True: Conflicting values will be corrected, be assigning a none conflicting value. False: If the value is conflicting
     * an exception will be thrown.
     * @return Instance of the label as it was added to the label set.
     * @pre label must point to a valid instance.
     * @pre If correctLabelValue==false, label value must be non conflicting.
     * @pre groupID must indicate an existing group.
     */
     mitk::Label* AddLabel(mitk::Label* label, GroupIndexType groupID, bool addAsClone = true, bool correctLabelValue = true);
 
     /** \brief Adds a new label to a group of the image by providing name and color.
     * @param name (Class) name of the label instance that should be added.
     * @param color Color of the new label sinstance.
     * @param groupID The id of the group the label should be added to.
     * @return Instance of the label as it was added to the label set.
     * @pre groupID must indicate an existing group.
     */
     mitk::Label* AddLabel(const std::string& name, const Color& color, GroupIndexType groupID);
 
     /** \brief allows to adapt name and color of a certain label
     * @param labelValue Value of the label that should be changed
     * @param name New name for the label
     * @param color New color for the label
     * @pre Indicated label value must exist.
     */
     void RenameLabel(LabelValueType labelValue, const std::string& name, const Color& color);
 
     /**
      * @brief Removes the label with the given value.
      * The label is removed from the labelset and
      * the pixel with the value of the label are set to UNLABELED_VALUE.
      * @param labelValue the pixel value of the label to be removed. If the label is unknown,
      * the method will return without doing anything.
      */
     void RemoveLabel(LabelValueType labelValue);
 
     /**
      * @brief Removes labels from the mitk::MultiLabelSegmentation.
      * The label is removed from the labelset and
      * the pixel with the value of the label are set to UNLABELED_VALUE.
      * If a label value does not exist, it will be ignored.
      * @param vectorOfLabelPixelValues a list of labels to be removed
      */
     void RemoveLabels(const LabelValueVectorType& vectorOfLabelPixelValues);
 
     /**
      * @brief Erases the label with the given value from the labelset image.
      * The label itself will not be erased from the respective mitk::LabelSet. In order to
      * remove the label itself use mitk::LabelSetImage::RemoveLabels()
      * @param labelValue the pixel value of the label that will be erased from the labelset image
      * @pre labelValue must exist.
      */
     void EraseLabel(LabelValueType labelValue);
 
     /**
      * @brief Erases a list of labels with the given values from the labelset image.
      * @param labelValues the list of pixel values of the labels
      * that will be erased from the labelset image
      * @pre label values must exist
      */
     void EraseLabels(const LabelValueVectorType& labelValues);
 
     /**
      * @brief Removes a whole group including all its labels.
      * @remark with removing a group all groups with greater index will be reindexed to
      * close the gap. Hence externaly stored spatial group indices may become invalid.
      * @param group Group index of the spatial group that should be removed. If the spatial group does not exist, an
      * exception will be raised.
      * @pre group index must be valid.
      */
     void RemoveGroup(GroupIndexType group);
 
     /** \brief  Returns true if the value exists in the MultiLabelSegmentation instance*/
     bool ExistLabel(LabelValueType value) const;
 
     /**
      * @brief Checks if a label belongs in a certain spatial group
      * @param value the label value
      * @param groupIndex Indexp of the spacial group which should be checked for the label
      * @return true if the label exists otherwise false
      */
     bool ExistLabel(LabelValueType value, GroupIndexType groupIndex) const;
 
     /**
       * @brief  Returns true if the spatial group exists in the MultiLabelSegmentation instance.
       *
       * @param index Group index of the group that should be checked for existance.
       */
     bool ExistGroup(GroupIndexType index) const;
 
     /** Returns the group id of the based label value.
     * @pre label value must exists.
     */
     GroupIndexType GetGroupIndexOfLabel(LabelValueType value) const;
 
     /**
      * @brief Returns the mitk::Label with the given value.
      * @param value the pixel value of the label
      * @return the label instance if defined in the segmentation, otherwise nullptr.
      */
     const mitk::Label* GetLabel(LabelValueType value) const;
     mitk::Label* GetLabel(LabelValueType value);
 
     /** Returns a vector with pointers to all labels currently defined in the MultiLabelSegmentation
     instance.*/
     const ConstLabelVectorType GetLabels() const;
     const LabelVectorType GetLabels();
 
     /** Returns a vector of all label values currently defined in the MultiLabelSegmentation
     instance.*/
     const LabelValueVectorType GetAllLabelValues() const;
 
     /** @brief Returns a vector with pointers to all labels in the MultiLabelSegmentation indicated
     * by the passed label value vector.
     * @param labelValues Vector of values of labels that should be returned.
     * @ignoreMissing If true(Default) unknown labels Will be skipped in the result. If false,
     * an exception will be raised, if a label is requested.
     instance.*/
     const LabelVectorType GetLabelsByValue(const LabelValueVectorType& labelValues, bool ignoreMissing = true);
 
     /** @brief Returns a vector with const pointers to all labels in the MultiLabelSegmentation indicated
     * by the passed label value vector.
     * For details see GetLabelsByValue();
     */
     const ConstLabelVectorType GetConstLabelsByValue(const LabelValueVectorType& labelValues, bool ignoreMissing = false) const;
 
     /** Helper function that can be used to extract a vector of label values of a vector of label instance pointers.
      @overload.*/
     static LabelValueVectorType ExtractLabelValuesFromLabelVector(const ConstLabelVectorType& labels);
     /** Helper function that can be used to extract a vector of label values are vector of label instancess.*/
     static LabelValueVectorType ExtractLabelValuesFromLabelVector(const LabelVectorType& labels);
 
     /** Helper function that converts a given vector of label instance pointers into a vector of const pointers.*/
     static ConstLabelVectorType ConvertLabelVectorConst(const LabelVectorType& labels);
 
     /**
      * @brief Returns a vector of all label values located on the specified group.
      * @param index the index of the group for which the vector of labels should be retrieved.
      * If an invalid index is passed an exception will be raised.
      * @return the respective vector of label values.
      * @pre group index must exist.
      */
     const LabelValueVectorType GetLabelValuesByGroup(GroupIndexType index) const;
 
     /**
      * @brief Returns a vector of all label values located on the specified group having a certain name.
      * @param index the index of the group for which the vector of labels should be retrieved.
      * If an invalid index is passed an exception will be raised.
      * @param name Name of the label instances one is looking for.
      * @return the respective vector of label values.
      * @pre group index must exist.
      */
     const LabelValueVectorType GetLabelValuesByName(GroupIndexType index, std::string_view name) const;
 
     /**
     * Returns a vector with (class) names of all label instances used in the segmentation (over all groups)
     */
     std::vector<std::string> GetLabelClassNames() const;
 
     /**
     * Returns a vector with (class) names of all label instances present in a certain group.
     * @param index ID of the group, for which the label class names should be returned
     * @pre Indicated group must exist. */
     std::vector<std::string> GetLabelClassNamesByGroup(GroupIndexType index) const;
 
     /** Helper that returns an unused label value, that could be used e.g. if one wants to define a label externally
     * before adding it.
     * @return A label value currently not in use.
     * @remark is no unused label value can be provided an exception will be thrown.*/
     LabelValueType GetUnusedLabelValue() const;
 
     itkGetConstMacro(UnlabeledLabelLock, bool);
     itkSetMacro(UnlabeledLabelLock, bool);
     itkBooleanMacro(UnlabeledLabelLock);
 
     /** Set the visibility of all label instances accordingly to the passed state.
     */
     void SetAllLabelsVisible(bool visible);
 
     /** Set the visibility of all label instances in a group accordingly to the passed state.
     * @pre The specified group must exist.
     */
     void SetAllLabelsVisibleByGroup(GroupIndexType group, bool visible);
 
     /** Set the visibility of all label instances In a group with a given class name
     * accordingly to the passed state.
     * @pre The specified group must exist.
     */
     void SetAllLabelsVisibleByName(GroupIndexType group, std::string_view name, bool visible);
 
     /** Returns the lock state of the label (including UnlabeledLabel value).
      @pre Requested label does exist.*/
     bool IsLabelLocked(LabelValueType value) const;
 
     /** Set the lock state of all label instances accordingly to the passed state.
     */
     void SetAllLabelsLocked(bool locked);
 
     /** Set the lock state of all label instances in a group accordingly to the passed state.
     * @pre The specified group must exist.
     */
     void SetAllLabelsLockedByGroup(GroupIndexType group, bool locked);
 
     /** Set the lock state of all label instances In a group with a given class name
     * accordingly to the passed state.
     * @pre The specified group must exist.
     */
     void SetAllLabelsLockedByName(GroupIndexType group, std::string_view name, bool locked);
 
     /**
     * \brief Replaces the labels of a group with a given vector of labels.
     *
     * @remark The passed label instances will be cloned before added to ensure clear ownership
     * of the new labels.
     * @remark The pixel content of the old labels will not be removed.
     * @param groupID The index of the group that should have its labels replaced
     * @param newLabels The vector of new labels
     * @pre Group that shuold be replaced must exist.
     * @pre new label values must not be used in other groups.
     */
     void ReplaceGroupLabels(const GroupIndexType groupID, const ConstLabelVectorType& newLabels);
 
     /**@overload for none-const label vectors. */
     void ReplaceGroupLabels(const GroupIndexType groupID, const LabelVectorType& newLabels);
 
     /** Returns the pointer to the image that containes the labeling of the indicate group.
      *@pre groupID must reference an existing group.*/
     mitk::Image* GetGroupImage(GroupIndexType groupID);
 
     /** Returns the pointer to the image that containes the labeling of the indicate group.
      *@pre groupID must reference an existing group.*/
     const mitk::Image* GetGroupImage(GroupIndexType groupID) const;
 
     itkGetModifiableObjectMacro(LookupTable, mitk::LookupTable);
     void SetLookupTable(LookupTable* lut);
     /** Updates the lookup table for a label indicated by the passe label value using the color of the label.
     * @pre labelValue must esist.
     */
     void UpdateLookupTable(PixelType pixelValue);
 
     protected:
 
       void OnLabelModified(const Object* sender, const itk::EventObject&);
 
       /** Helper to ensure that the maps are correctly populated for a new label instance.*/
       void AddLabelToMap(LabelValueType labelValue, Label* label, GroupIndexType groupID);
       void RemoveLabelFromMap(LabelValueType labelValue);
       /** Helper to ensure label events are correctly connected and lookup table is updated for a new label instance.*/
       void RegisterLabel(Label* label);
       /** Helper to ensure label events are unregistered.*/
       void ReleaseLabel(Label* label);
 
       /** Helper class used internally to apply lamba functions to the labels specified by tha passed label value vector.
       */
       void ApplyToLabels(const LabelValueVectorType& values, std::function<void(Label*)>&& lambda);
       /** Helper class used internally to for visiting the labels specified by tha passed label value vector
       * with the lambda function.
       */
       void VisitLabels(const LabelValueVectorType& values, std::function<void(const Label*)>&& lambda) const;
 
       LabelValueType m_ActiveLabelValue;
 
     private:
       using LabelMapType = std::map<LabelValueType, Label::Pointer>;
       /** Dictionary that holds all known labels (label value is the key).*/
       LabelMapType m_LabelMap;
 
       using GroupNameVectorType = std::vector<std::string>;
       /** Vector storing the names of all groups. If a group has no user name defined, string is empty.*/
       GroupNameVectorType m_Groups;
 
       /**This type is internally used to track which label is currently
        * associated with which layer.*/
       using GroupToLabelMapType = std::vector<LabelValueVectorType>;
       /* Dictionary that maps between group id (key) and label values in the group (vector of label value).*/
       GroupToLabelMapType m_GroupToLabelMap;
       using LabelToGroupMapType = std::map<LabelValueType, GroupIndexType>;
       /* Dictionary that maps between label value (key) and group id (value)*/
       LabelToGroupMapType m_LabelToGroupMap;
 
       LookupTable::Pointer m_LookupTable;
 
       /** Indicates if the MultiLabelSegmentation allows to overwrite unlabeled pixels in normal pixel manipulation operations (e.g. TransferLabelConent).*/
       bool m_UnlabeledLabelLock;
 
     public:
 
 
     ///////////////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////////////
     // END FUTURE MultiLabelSegmentation
     ///////////////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////////////
     /**
       * \brief  */
       void UpdateCenterOfMass(PixelType pixelValue);
 
     /**
      * @brief Initialize an empty mitk::LabelSetImage using the information
      *        of an mitk::Image
      * @param image the image which is used for initializing the mitk::LabelSetImage
      */
     using mitk::Image::Initialize;
     void Initialize(const mitk::Image *image) override;
 
     /**
       * \brief removes all pixel content form the active layer.*/
     void ClearBuffer();
 
     /**
      * @brief Merges the mitk::Label with a given target value with the active label
      *
      * @param pixelValue          the value of the label that should be the new merged label
      * @param sourcePixelValue    the value of the label that should be merged into the specified one
-     * @param layer               the layer in which the merge should be performed
      */
-    void MergeLabel(PixelType pixelValue, PixelType sourcePixelValue, unsigned int layer = 0);
+    void MergeLabel(PixelType pixelValue, PixelType sourcePixelValue);
 
     /**
      * @brief Merges a list of mitk::Labels with the mitk::Label that has a specific value
      *
      * @param pixelValue                  the value of the label that should be the new merged label
      * @param vectorOfSourcePixelValues   the list of label values that should be merge into the specified one
-     * @param layer                       the layer in which the merge should be performed
      */
-    void MergeLabels(PixelType pixelValue, const std::vector<PixelType>& vectorOfSourcePixelValues, unsigned int layer = 0);
+    void MergeLabels(PixelType pixelValue, const std::vector<PixelType>& vectorOfSourcePixelValues);
 
     /**
      * @brief Gets the ID of the currently active layer
      * @return the ID of the active layer
      * @pre at least on group must exist.
      */
     unsigned int GetActiveLayer() const;
 
     /** \brief
 */
     Label* GetActiveLabel();
     /** \brief
     */
     const Label* GetActiveLabel() const;
 
     /**
      * @brief Get the number of all existing mitk::Labels for a given layer
      * @param layer the layer ID for which the active mitk::Labels should be retrieved
      * @return the number of all existing mitk::Labels for the given layer
      */
     unsigned int GetNumberOfLabels(unsigned int layer) const;
 
     /**
      * @brief Returns the number of all labels summed up across all layers
      * @return the overall number of labels across all layers
      */
     unsigned int GetTotalNumberOfLabels() const;
 
     /**
       * \brief  */
     mitk::Image::Pointer CreateLabelMask(PixelType index);
 
     /**
      * @brief Initialize a new mitk::LabelSetImage by a given image.
      * For all distinct pixel values of the parameter image new labels will
      * be created. If the number of distinct pixel values exceeds mitk::Label::MAX_LABEL_VALUE
      * an excption will be raised.
      * @param image the image which is used for initialization
      */
     void InitializeByLabeledImage(mitk::Image::Pointer image);
 
     /**
       * \brief  */
     void MaskStamp(mitk::Image *mask, bool forceOverwrite);
 
     /**
       * \brief  */
     void SetActiveLayer(unsigned int layer);
     void SetActiveLabel(LabelValueType label);
 
     /**
       * \brief  */
     unsigned int GetNumberOfLayers() const;
 
     /**
      * \brief Adds a new layer to the LabelSetImage. The new layer will be set as the active one.
      * \param labelSet a labelset that will be added to the new layer if provided
      * \return the layer ID of the new layer
      */
     GroupIndexType AddLayer(ConstLabelVector labels = {});
 
     /**
     * \brief Adds a layer based on a provided mitk::Image.
     * \param layerImage is added to the vector of label images
     * \param labels labels that will be cloned and added to the new layer if provided
     * \return the layer ID of the new layer
     */
     GroupIndexType AddLayer(mitk::Image::Pointer layerImage, ConstLabelVector labels = {});
 
   protected:
     mitkCloneMacro(Self);
 
       LabelSetImage();
     LabelSetImage(const LabelSetImage &other);
     ~LabelSetImage() override;
 
     template <typename TPixel, unsigned int VImageDimension>
     void LayerContainerToImageProcessing(itk::Image<TPixel, VImageDimension> *source, unsigned int layer);
 
     template <typename TPixel, unsigned int VImageDimension>
     void ImageToLayerContainerProcessing(itk::Image<TPixel, VImageDimension> *source, unsigned int layer) const;
 
     template <typename ImageType>
     void CalculateCenterOfMassProcessing(ImageType *input, LabelValueType index);
 
     template <typename ImageType>
     void EraseLabelProcessing(ImageType *input, PixelType index);
 
     template <typename ImageType>
     void MergeLabelProcessing(ImageType *input, PixelType pixelValue, PixelType index);
 
     template <typename ImageType>
     void MaskStampProcessing(ImageType *input, mitk::Image *mask, bool forceOverwrite);
 
     template <typename LabelSetImageType, typename ImageType>
     void InitializeByLabeledImageProcessing(LabelSetImageType *input, ImageType *other);
 
     /** helper needed for ensuring unique values.
       returns a sorted list of all labels (including the value for Unlabeled pixels..*/
     LabelValueVectorType GetUsedLabelValues() const;
 
     std::vector<Image::Pointer> m_LayerContainer;
 
     int m_ActiveLayer;
     bool m_activeLayerInvalid;
   };
 
   /**
   * @brief Equal A function comparing two label set images for beeing equal in meta- and imagedata
   *
   * @ingroup MITKTestingAPI
   *
   * Following aspects are tested for equality:
   *  - LabelSetImage members
   *  - working image data
   *  - layer image data
   *  - labels in label set
   *
   * @param rightHandSide An image to be compared
   * @param leftHandSide An image to be compared
   * @param eps Tolerance for comparison. You can use mitk::eps in most cases.
   * @param verbose Flag indicating if the user wants detailed console output or not.
   * @return true, if all subsequent comparisons are true, false otherwise
   */
   MITKMULTILABEL_EXPORT bool Equal(const mitk::LabelSetImage &leftHandSide,
                                    const mitk::LabelSetImage &rightHandSide,
                                    ScalarType eps,
                                    bool verbose);
 
   /**
   * @brief Equal A function comparing two vectors of labels for beeing equal in data
   *
   * @ingroup MITKTestingAPI
   *
   * Following aspects are tested for equality:
   *  - Labels in vector
   *
   * @param rightHandSide An vector of labels to be compared
   * @param leftHandSide An vector of labels to be compared
   * @param eps Tolarence for comparison. You can use mitk::eps in most cases.
   * @param verbose Flag indicating if the user wants detailed console output or not.
   * @return true, if all subsequent comparisons are true, false otherwise
   */
   MITKMULTILABEL_EXPORT bool Equal(const mitk::LabelSetImage::ConstLabelVectorType& leftHandSide,
     const mitk::LabelSetImage::ConstLabelVectorType& rightHandSide,
     ScalarType eps,
     bool verbose);
 
 
   /** temporery namespace that is used until the new class MultiLabelSegmentation is
     introduced. It allows to already introduce/use some upcoming definitions, while
     refactoring code.*/
   namespace MultiLabelSegmentation
   {
     enum class MergeStyle
     {
       Replace, //The old label content of a label value will be replaced by its new label content.
                //Therefore pixels that are labeled might become unlabeled again.
                //(This means that a lock of the value is also ignored).
       Merge //The union of old and new label content will be generated.
     };
 
     enum class OverwriteStyle
     {
       RegardLocks, //Locked labels in the same spatial group will not be overwritten/changed.
       IgnoreLocks //Label locks in the same spatial group will be ignored, so these labels might be changed.
     };
   }
 
   using LabelValueMappingVector = std::vector < std::pair<Label::PixelType, Label::PixelType> >;
 
   /**Helper function that transfers pixels of the specified source label from source image to the destination image by using
   a specified destination label for a specific timestep. Function processes the whole image volume of the specified time step.
   @remark in its current implementation the function only transfers contents of the active layer of the passed LabelSetImages.
   @remark the function assumes that it is only called with source and destination image of same geometry.
   @remark CAUTION: The function is not save if sourceImage and destinationImage are the same instance and more than one label is transferred,
   because the changes are made in-place for performance reasons in multiple passes. If a mapped value A equals an "old value"
   that occurs later in the mapping, one ends up with a wrong transfer, as a pixel would be first mapped to A and then later again, because
   it is also an "old" value in the mapping table.
   @param sourceImage Pointer to the LabelSetImage which active layer should be used as source for the transfer.
   @param destinationImage Pointer to the LabelSetImage which active layer should be used as destination for the transfer.
   @param labelMapping Map that encodes the mappings of all label pixel transfers that should be done. First element is the
   label in the source image. The second element is the label that transferred pixels should become in the destination image.
   The order in which the labels will be transfered is the same order of elements in the labelMapping.
   If you use a heterogeneous label mapping (e.g. (1,2); so changing the label while transfering), keep in mind that
   for the MergeStyle and OverwriteStyle only the destination label (second element) is relevant (e.g. what should be
   altered with MergeStyle Replace).
   @param mergeStyle indicates how the transfer should be done (merge or replace). For more details see documentation of
   MultiLabelSegmentation::MergeStyle.
   @param overwriteStlye indicates if label locks in the destination image should be regarded or not. For more details see
   documentation of MultiLabelSegmentation::OverwriteStyle.
   @param timeStep indicate the time step that should be transferred.
   @pre sourceImage and destinationImage must be valid
   @pre sourceImage and destinationImage must contain the indicated timeStep
   @pre sourceImage must contain all indicated sourceLabels in its active layer.
   @pre destinationImage must contain all indicated destinationLabels in its active layer.*/
   MITKMULTILABEL_EXPORT void TransferLabelContentAtTimeStep(const LabelSetImage* sourceImage, LabelSetImage* destinationImage,
     const TimeStepType timeStep, LabelValueMappingVector labelMapping = { {1,1} },
     MultiLabelSegmentation::MergeStyle mergeStyle = MultiLabelSegmentation::MergeStyle::Replace,
     MultiLabelSegmentation::OverwriteStyle overwriteStlye = MultiLabelSegmentation::OverwriteStyle::RegardLocks);
 
   /**Helper function that transfers pixels of the specified source label from source image to the destination image by using
   a specified destination label. Function processes the whole image volume for all time steps.
   For more details please see TransferLabelContentAtTimeStep for LabelSetImages.
   @sa TransferLabelContentAtTimeStep*/
   MITKMULTILABEL_EXPORT void TransferLabelContent(const LabelSetImage* sourceImage, LabelSetImage* destinationImage, LabelValueMappingVector labelMapping = { {1,1} },
     MultiLabelSegmentation::MergeStyle mergeStyle = MultiLabelSegmentation::MergeStyle::Replace,
     MultiLabelSegmentation::OverwriteStyle overwriteStlye = MultiLabelSegmentation::OverwriteStyle::RegardLocks);
 
 
   /**Helper function that transfers pixels of the specified source label from source image to the destination image by using
   a specified destination label for a specific timestep. Function processes the whole image volume of the specified time step.
   @remark the function assumes that it is only called with source and destination image of same geometry.
   @remark CAUTION: The function is not save, if sourceImage and destinationImage are the same instance and you transfer more then one
   label, because the changes are made inplace for performance reasons but not in one pass. If a mapped value A equals a "old value"
   that is later in the mapping, one ends up with a wrong transfer, as a pixel would be first mapped to A and then latter again, because
   it is also an "old" value in the mapping table.
   @param sourceImage Pointer to the image that should be used as source for the transfer.
   @param destinationImage Pointer to the image that should be used as destination for the transfer.
   @param destinationLabelVector Reference to the vector of labels (incl. lock states) in the destination image. Unkown pixel
   values in the destinationImage will be assumed to be unlocked.
   @param sourceBackground Value indicating the background in the source image.
   @param destinationBackground Value indicating the background in the destination image.
   @param destinationBackgroundLocked Value indicating the lock state of the background in the destination image.
   @param labelMapping Map that encodes the mappings of all label pixel transfers that should be done. First element is the
   label in the source image. The second element is the label that transferred pixels should become in the destination image.
   The order in which the labels will be transfered is the same order of elements in the labelMapping.
   If you use a heterogeneous label mapping (e.g. (1,2); so changing the label while transfering), keep in mind that
   for the MergeStyle and OverwriteStyle only the destination label (second element) is relevant (e.g. what should be
   altered with MergeStyle Replace).
   @param mergeStyle indicates how the transfer should be done (merge or replace). For more details see documentation of
   MultiLabelSegmentation::MergeStyle.
   @param overwriteStlye indicates if label locks in the destination image should be regarded or not. For more details see
   documentation of MultiLabelSegmentation::OverwriteStyle.
   @param timeStep indicate the time step that should be transferred.
   @pre sourceImage, destinationImage and destinationLabelVector must be valid
   @pre sourceImage and destinationImage must contain the indicated timeStep
   @pre destinationLabelVector must contain all indicated destinationLabels for mapping.*/
   MITKMULTILABEL_EXPORT void TransferLabelContentAtTimeStep(const Image* sourceImage, Image* destinationImage, const mitk::ConstLabelVector& destinationLabelVector,
     const TimeStepType timeStep, mitk::Label::PixelType sourceBackground = LabelSetImage::UNLABELED_VALUE,
     mitk::Label::PixelType destinationBackground = LabelSetImage::UNLABELED_VALUE,
     bool destinationBackgroundLocked = false,
     LabelValueMappingVector labelMapping = { {1,1} },
     MultiLabelSegmentation::MergeStyle mergeStyle = MultiLabelSegmentation::MergeStyle::Replace,
     MultiLabelSegmentation::OverwriteStyle overwriteStlye = MultiLabelSegmentation::OverwriteStyle::RegardLocks);
 
   /**Helper function that transfers pixels of the specified source label from source image to the destination image by using
   a specified destination label. Function processes the whole image volume for all time steps.
   For more details please see TransferLabelContentAtTimeStep.
   @sa TransferLabelContentAtTimeStep*/
   MITKMULTILABEL_EXPORT void TransferLabelContent(const Image* sourceImage, Image* destinationImage, const mitk::ConstLabelVector& destinationLabelVector,
     mitk::Label::PixelType sourceBackground = LabelSetImage::UNLABELED_VALUE,
     mitk::Label::PixelType destinationBackground = LabelSetImage::UNLABELED_VALUE,
     bool destinationBackgroundLocked = false,
     LabelValueMappingVector labelMapping = { {1,1} },
     MultiLabelSegmentation::MergeStyle mergeStyle = MultiLabelSegmentation::MergeStyle::Replace,
     MultiLabelSegmentation::OverwriteStyle overwriteStlye = MultiLabelSegmentation::OverwriteStyle::RegardLocks);
 
 } // namespace mitk
 
 #endif
diff --git a/Modules/Multilabel/mitkMultiLabelIOHelper.cpp b/Modules/Multilabel/mitkMultiLabelIOHelper.cpp
index ed0a404377..9303c04431 100644
--- a/Modules/Multilabel/mitkMultiLabelIOHelper.cpp
+++ b/Modules/Multilabel/mitkMultiLabelIOHelper.cpp
@@ -1,440 +1,440 @@
 /*============================================================================
 
 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 "mitkMultiLabelIOHelper.h"
 
 #include "mitkLabelSetImage.h"
 #include <mitkBasePropertySerializer.h>
 
 #include "itkMetaDataDictionary.h"
 #include "itkMetaDataObject.h"
 
 #include <tinyxml2.h>
 
 namespace
 {
   std::string EnsureExtension(const std::string& filename)
   {
     const std::string extension = ".lsetp";
 
     if (filename.size() < extension.size() || std::string::npos == filename.find(extension, filename.size() - extension.size()))
       return filename + extension;
 
     return filename;
   }
 }
 
 bool mitk::MultiLabelIOHelper::SaveLabelSetImagePreset(const std::string &presetFilename,
                                                      const mitk::LabelSetImage *inputImage)
 {
   const auto filename = EnsureExtension(presetFilename);
 
   tinyxml2::XMLDocument xmlDocument;
   xmlDocument.InsertEndChild(xmlDocument.NewDeclaration());
 
   auto *rootElement = xmlDocument.NewElement("LabelSetImagePreset");
   rootElement->SetAttribute("layers", inputImage->GetNumberOfLayers());
   xmlDocument.InsertEndChild(rootElement);
 
   for (unsigned int layerIndex = 0; layerIndex < inputImage->GetNumberOfLayers(); layerIndex++)
   {
     auto *layerElement = xmlDocument.NewElement("Layer");
     layerElement->SetAttribute("index", layerIndex);
     layerElement->SetAttribute("labels", inputImage->GetNumberOfLabels(layerIndex));
     rootElement->InsertEndChild(layerElement);
 
     auto labelsInGroup = inputImage->GetConstLabelsByValue(inputImage->GetLabelValuesByGroup(layerIndex));
 
-    for (const auto label : labelsInGroup)
+    for (const auto& label : labelsInGroup)
       layerElement->InsertEndChild(MultiLabelIOHelper::GetLabelAsXMLElement(xmlDocument, label));
   }
 
   return tinyxml2::XML_SUCCESS == xmlDocument.SaveFile(filename.c_str());
 }
 
 bool mitk::MultiLabelIOHelper::LoadLabelSetImagePreset(const std::string &presetFilename,
                                                      mitk::LabelSetImage *inputImage)
 {
   if (nullptr == inputImage)
     return false;
 
   const auto filename = EnsureExtension(presetFilename);
 
   tinyxml2::XMLDocument xmlDocument;
 
   if (tinyxml2::XML_SUCCESS != xmlDocument.LoadFile(filename.c_str()))
   {
     MITK_WARN << "Label set preset file \"" << filename << "\" does not exist or cannot be opened";
     return false;
   }
 
   auto *rootElement = xmlDocument.FirstChildElement("LabelSetImagePreset");
 
   if (nullptr == rootElement)
   {
     MITK_WARN << "Not a valid Label set preset";
     return false;
   }
 
   auto activeLayerBackup = inputImage->GetActiveLayer();
 
   int numberOfLayers = 0;
   rootElement->QueryIntAttribute("layers", &numberOfLayers);
 
   auto* layerElement = rootElement->FirstChildElement("Layer");
 
   if (nullptr == layerElement)
   {
     MITK_WARN << "Label set preset does not contain any layers";
     return false;
   }
 
   for (int layerIndex = 0; layerIndex < numberOfLayers; layerIndex++)
   {
     int numberOfLabels = 0;
     layerElement->QueryIntAttribute("labels", &numberOfLabels);
 
     if (!inputImage->ExistGroup(layerIndex))
     {
       while (!inputImage->ExistGroup(layerIndex))
       {
         inputImage->AddLayer();
       }
     }
 
     auto *labelElement = layerElement->FirstChildElement("Label");
 
     if (nullptr == labelElement)
       continue;
 
     for (int labelIndex = 0; labelIndex < numberOfLabels; labelIndex++)
     {
       auto label = mitk::MultiLabelIOHelper::LoadLabelFromXMLDocument(labelElement);
       const auto labelValue = label->GetValue();
 
       if (LabelSetImage::UNLABELED_VALUE != labelValue)
       {
         if (inputImage->ExistLabel(labelValue))
         {
           // Override existing label with label from preset
           auto alreadyExistingLabel = inputImage->GetLabel(labelValue);
           alreadyExistingLabel->ConcatenatePropertyList(label);
           inputImage->UpdateLookupTable(labelValue);
         }
         else
         {
           inputImage->AddLabel(label, layerIndex, false);
         }
       }
 
       labelElement = labelElement->NextSiblingElement("Label");
 
       if (nullptr == labelElement)
         continue;
     }
 
     layerElement = layerElement->NextSiblingElement("Layer");
 
     if (nullptr == layerElement)
       continue;
   }
 
   inputImage->SetActiveLayer(activeLayerBackup);
 
   return true;
 }
 
 tinyxml2::XMLElement *mitk::MultiLabelIOHelper::GetLabelAsXMLElement(tinyxml2::XMLDocument &doc, const Label *label)
 {
   auto *labelElem = doc.NewElement("Label");
 
   if (nullptr != label)
   {
     // add XML contents
     const PropertyList::PropertyMap* propmap = label->GetMap();
     for (auto iter = propmap->begin(); iter != propmap->end(); ++iter)
     {
       std::string key = iter->first;
       const BaseProperty* property = iter->second;
       auto* element = PropertyToXMLElement(doc, key, property);
       if (element)
         labelElem->InsertEndChild(element);
     }
   }
 
   return labelElem;
 }
 
 mitk::Label::Pointer mitk::MultiLabelIOHelper::LoadLabelFromXMLDocument(const tinyxml2::XMLElement *labelElem)
 {
   // reread
   auto *propElem = labelElem->FirstChildElement("property");
 
   std::string name;
   mitk::BaseProperty::Pointer prop;
 
   mitk::Label::Pointer label = mitk::Label::New();
   while (propElem)
   {
     MultiLabelIOHelper::PropertyFromXMLElement(name, prop, propElem);
     label->SetProperty(name, prop);
     propElem = propElem->NextSiblingElement("property");
   }
 
   return label.GetPointer();
 }
 
 tinyxml2::XMLElement *mitk::MultiLabelIOHelper::PropertyToXMLElement(tinyxml2::XMLDocument &doc, const std::string &key, const BaseProperty *property)
 {
   auto *keyelement = doc.NewElement("property");
   keyelement->SetAttribute("key", key.c_str());
   keyelement->SetAttribute("type", property->GetNameOfClass());
 
   // construct name of serializer class
   std::string serializername(property->GetNameOfClass());
   serializername += "Serializer";
 
   std::list<itk::LightObject::Pointer> allSerializers =
     itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str());
   if (allSerializers.size() < 1)
     MITK_ERROR << "No serializer found for " << property->GetNameOfClass() << ". Skipping object";
 
   if (allSerializers.size() > 1)
     MITK_WARN << "Multiple serializers found for " << property->GetNameOfClass() << "Using arbitrarily the first one.";
 
   for (auto iter = allSerializers.begin(); iter != allSerializers.end();
        ++iter)
   {
     if (auto *serializer = dynamic_cast<BasePropertySerializer *>(iter->GetPointer()))
     {
       serializer->SetProperty(property);
       try
       {
         auto *valueelement = serializer->Serialize(doc);
         if (valueelement)
           keyelement->InsertEndChild(valueelement);
       }
       catch (std::exception &e)
       {
         MITK_ERROR << "Serializer " << serializer->GetNameOfClass() << " failed: " << e.what();
       }
       break;
     }
   }
   return keyelement;
 }
 
 bool mitk::MultiLabelIOHelper::PropertyFromXMLElement(std::string &key,
                                                     mitk::BaseProperty::Pointer &prop,
                                                     const tinyxml2::XMLElement *elem)
 {
   const char* typeC = elem->Attribute("type");
   std::string type = nullptr != typeC
     ? typeC
     : "";
 
   const char* keyC = elem->Attribute("key");
   key = nullptr != keyC
     ? keyC
     : "";
 
   // construct name of serializer class
   std::string serializername(type);
   serializername += "Serializer";
 
   std::list<itk::LightObject::Pointer> allSerializers =
     itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str());
   if (allSerializers.size() < 1)
     MITK_ERROR << "No serializer found for " << type << ". Skipping object";
 
   if (allSerializers.size() > 1)
     MITK_WARN << "Multiple deserializers found for " << type << "Using arbitrarily the first one.";
 
   for (auto iter = allSerializers.begin(); iter != allSerializers.end();
        ++iter)
   {
     if (auto *serializer = dynamic_cast<BasePropertySerializer *>(iter->GetPointer()))
     {
       try
       {
         prop = serializer->Deserialize(elem->FirstChildElement());
       }
       catch (std::exception &e)
       {
         MITK_ERROR << "Deserializer " << serializer->GetNameOfClass() << " failed: " << e.what();
         return false;
       }
       break;
     }
   }
   if (prop.IsNull())
     return false;
   return true;
 }
 
 int mitk::MultiLabelIOHelper::GetIntByKey(const itk::MetaDataDictionary& dic, const std::string& str)
 {
   std::vector<std::string> imgMetaKeys = dic.GetKeys();
   std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
   std::string metaString("");
   for (; itKey != imgMetaKeys.end(); itKey++)
   {
     itk::ExposeMetaData<std::string>(dic, *itKey, metaString);
     if (itKey->find(str.c_str()) != std::string::npos)
     {
       return atoi(metaString.c_str());
     }
   }
   return 0;
 }
 
 std::string mitk::MultiLabelIOHelper::GetStringByKey(const itk::MetaDataDictionary& dic, const std::string& str)
 {
   std::vector<std::string> imgMetaKeys = dic.GetKeys();
   std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
   std::string metaString("");
   for (; itKey != imgMetaKeys.end(); itKey++)
   {
     itk::ExposeMetaData<std::string>(dic, *itKey, metaString);
     if (itKey->find(str.c_str()) != std::string::npos)
     {
       return metaString;
     }
   }
   return metaString;
 }
 
 nlohmann::json mitk::MultiLabelIOHelper::SerializeMultLabelGroupsToJSON(const mitk::LabelSetImage* inputImage)
 {
   if (nullptr == inputImage)
   {
     mitkThrow() << "Invalid call of SerializeMultLabelGroupsToJSON. Passed image pointer is null.";
   }
 
   nlohmann::json result;
 
   for (LabelSetImage::GroupIndexType i = 0; i < inputImage->GetNumberOfLayers(); i++)
   {
     nlohmann::json jgroup;
     nlohmann::json jlabels;
 
     for (const auto& label : inputImage->GetConstLabelsByValue(inputImage->GetLabelValuesByGroup(i)))
     {
       jlabels.emplace_back(SerializeLabelToJSON(label));
     }
     jgroup["labels"] = jlabels;
     result.emplace_back(jgroup);
   }
   return result;
 };
 
 std::vector<mitk::LabelVector> mitk::MultiLabelIOHelper::DeserializeMultiLabelGroupsFromJSON(const nlohmann::json& listOfLabelSets)
 {
   std::vector<LabelVector> result;
 
   for (const auto& jlabelset : listOfLabelSets)
   {
     LabelVector labelSet;
     if (jlabelset.find("labels") != jlabelset.end())
     {
       auto jlabels = jlabelset["labels"];
 
       for (const auto& jlabel : jlabels)
       {
         labelSet.push_back(DeserializeLabelFromJSON(jlabel));
       }
     }
     result.emplace_back(labelSet);
   }
 
   return result;
 }
 
 nlohmann::json mitk::MultiLabelIOHelper::SerializeLabelToJSON(const Label* label)
 {
   if (nullptr == label)
   {
     mitkThrow() << "Invalid call of GetLabelAsJSON. Passed label pointer is null.";
   }
 
   nlohmann::json j;
   j["name"] = label->GetName();
 
   j["value"] = label->GetValue();
 
   nlohmann::json jcolor;
   jcolor["type"] = "ColorProperty";
   jcolor["value"] = {label->GetColor().GetRed(), label->GetColor().GetGreen(), label->GetColor().GetBlue() };
   j["color"] = jcolor;
 
   j["locked"] = label->GetLocked();
   j["opacity"] = label->GetOpacity();
   j["visible"] = label->GetVisible();
   return j;
 };
 
 template<typename TValueType> bool GetValueFromJson(const nlohmann::json& labelJson, const std::string& key, TValueType& value)
 {
   if (labelJson.find(key) != labelJson.end())
   {
     try
     {
       value = labelJson[key].get<TValueType>();
       return true;
     }
     catch (...)
     {
       MITK_ERROR << "Unable to read label information from json. Value has wrong type. Failed key: " << key << "; invalid value: " << labelJson[key].dump();
       throw;
     }
   }
   return false;
 }
 
 mitk::Label::Pointer mitk::MultiLabelIOHelper::DeserializeLabelFromJSON(const nlohmann::json& labelJson)
 {
   Label::Pointer resultLabel = Label::New();
 
   std::string name = "Unkown label name";
   GetValueFromJson(labelJson, "name", name);
   resultLabel->SetName(name);
 
   Label::PixelType value = 1;
   GetValueFromJson(labelJson, "value", value);
   resultLabel->SetValue(value);
 
   if (labelJson.find("color") != labelJson.end())
   {
     auto jcolor = labelJson["color"]["value"];
     Color color;
     color.SetRed(jcolor[0].get<float>());
     color.SetGreen(jcolor[1].get<float>());
     color.SetBlue(jcolor[2].get<float>());
 
     resultLabel->SetColor(color);
   }
 
   bool locked = false;
   if (GetValueFromJson(labelJson, "locked", locked))
     resultLabel->SetLocked(locked);
 
   float opacity = 1.;
   if (GetValueFromJson(labelJson, "opacity", opacity))
     resultLabel->SetOpacity(opacity);
 
 
   bool visible = true;
   if (GetValueFromJson(labelJson, "visible", visible))
     resultLabel->SetVisible(visible);
 
   return resultLabel;
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.cpp b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.cpp
index 8f15a6f40b..1e21abc95f 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.cpp
@@ -1,1123 +1,1123 @@
 /*============================================================================
 
 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 <QmitkMultiLabelInspector.h>
 
 // mitk
 #include <mitkRenderingManager.h>
 #include <mitkLabelSetImageHelper.h>
 #include <mitkDICOMSegmentationPropertyHelper.h>
 
 // Qmitk
 #include <QmitkMultiLabelTreeModel.h>
 #include <QmitkLabelColorItemDelegate.h>
 #include <QmitkLabelToggleItemDelegate.h>
 #include <QmitkStyleManager.h>
 
 // Qt
 #include <QMenu>
 #include <QLabel>
 #include <QWidgetAction>
 #include <QMessageBox>
 
 #include <ui_QmitkMultiLabelInspectorControls.h>
 
 QmitkMultiLabelInspector::QmitkMultiLabelInspector(QWidget* parent/* = nullptr*/)
   : QWidget(parent), m_Controls(new Ui::QmitkMultiLabelInspector)
 {
   m_Controls->setupUi(this);
 
   m_Model = new QmitkMultiLabelTreeModel(this);
 
   m_Controls->view->setModel(m_Model);
 
   m_ColorItemDelegate = new QmitkLabelColorItemDelegate(this);
 
   auto visibleIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/visible.svg"));
   auto invisibleIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/invisible.svg"));
   m_VisibilityItemDelegate = new QmitkLabelToggleItemDelegate(visibleIcon, invisibleIcon, this);
 
   auto lockIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/lock.svg"));
   auto unlockIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/unlock.svg"));
   m_LockItemDelegate = new QmitkLabelToggleItemDelegate(lockIcon, unlockIcon, this);
 
   auto* view = this->m_Controls->view;
   view->setItemDelegateForColumn(1, m_LockItemDelegate);
   view->setItemDelegateForColumn(2, m_ColorItemDelegate);
   view->setItemDelegateForColumn(3, m_VisibilityItemDelegate);
 
   auto* header = view->header();
   header->setSectionResizeMode(0,QHeaderView::Stretch);
   header->setSectionResizeMode(1, QHeaderView::ResizeToContents);
   header->setSectionResizeMode(2, QHeaderView::ResizeToContents);
   header->setSectionResizeMode(3, QHeaderView::ResizeToContents);
   view->setContextMenuPolicy(Qt::CustomContextMenu);
 
   connect(m_Model, &QAbstractItemModel::modelReset, this, &QmitkMultiLabelInspector::OnModelReset);
   connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), SLOT(OnChangeModelSelection(const QItemSelection&, const QItemSelection&)));
   connect(view, &QAbstractItemView::customContextMenuRequested, this, &QmitkMultiLabelInspector::OnContextMenuRequested);
   connect(view, &QAbstractItemView::doubleClicked, this, &QmitkMultiLabelInspector::OnItemDoubleClicked);
 }
 
 QmitkMultiLabelInspector::~QmitkMultiLabelInspector()
 {
   delete m_Controls;
 }
 
 void QmitkMultiLabelInspector::Initialize()
 {
   m_LastValidSelectedLabels = {};
   m_ModelManipulationOngoing = false;
   m_Model->SetSegmentation(m_Segmentation);
   m_Controls->view->expandAll();
 
   m_LastValidSelectedLabels = {};
 
   //in singel selection mode, if at least one label exist select the first label of the mode.
   if (m_Segmentation.IsNotNull() && !this->GetMultiSelectionMode() && m_Segmentation->GetTotalNumberOfLabels() > 0)
   {
     auto firstIndex = m_Model->FirstLabelInstanceIndex(QModelIndex());
     auto labelVariant = firstIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
 
     if (labelVariant.isValid())
     {
       this->SetSelectedLabel(labelVariant.value<LabelValueType>());
       m_Controls->view->selectionModel()->setCurrentIndex(firstIndex, QItemSelectionModel::NoUpdate);
     }
   }
 }
 
 void QmitkMultiLabelInspector::SetMultiSelectionMode(bool multiMode)
 {
   m_Controls->view->setSelectionMode(multiMode
      ? QAbstractItemView::SelectionMode::MultiSelection
      : QAbstractItemView::SelectionMode::SingleSelection);
 }
 
 bool QmitkMultiLabelInspector::GetMultiSelectionMode() const
 {
   return QAbstractItemView::SelectionMode::MultiSelection == m_Controls->view->selectionMode();
 }
 
 void QmitkMultiLabelInspector::SetAllowVisibilityModification(bool visibilityMod)
 {
   m_AllowVisibilityModification = visibilityMod;
   this->m_Model->SetAllowVisibilityModification(visibilityMod);
 }
 
 void QmitkMultiLabelInspector::SetAllowLabelModification(bool labelMod)
 {
   m_AllowLabelModification = labelMod;
 }
 
 bool QmitkMultiLabelInspector::GetAllowVisibilityModification() const
 {
   return m_AllowVisibilityModification;
 }
 
 void QmitkMultiLabelInspector::SetAllowLockModification(bool lockMod)
 {
   m_AllowLockModification = lockMod;
   this->m_Model->SetAllowLockModification(lockMod);
 }
 
 bool QmitkMultiLabelInspector::GetAllowLockModification() const
 {
   return m_AllowLockModification;
 }
 
 bool QmitkMultiLabelInspector::GetAllowLabelModification() const
 {
   return m_AllowLabelModification;
 }
 
 void QmitkMultiLabelInspector::SetDefaultLabelNaming(bool defaultLabelNaming)
 {
   m_DefaultLabelNaming = defaultLabelNaming;
 }
 
 void QmitkMultiLabelInspector::SetMultiLabelSegmentation(mitk::LabelSetImage* segmentation)
 {
   if (segmentation != m_Segmentation)
   {
     m_Segmentation = segmentation;
     this->Initialize();
   }
 }
 
 bool QmitkMultiLabelInspector::GetModelManipulationOngoing() const
 {
   return m_ModelManipulationOngoing;
 }
 
 void QmitkMultiLabelInspector::OnModelReset()
 {
   m_LastValidSelectedLabels = {};
   m_ModelManipulationOngoing = false;
 }
 
 bool EqualLabelSelections(const QmitkMultiLabelInspector::LabelValueVectorType& selection1, const QmitkMultiLabelInspector::LabelValueVectorType& selection2)
 {
   if (selection1.size() == selection2.size())
   {
     // lambda to compare node pointer inside both lists
     return std::is_permutation(selection1.begin(), selection1.end(), selection2.begin());
   }
 
   return false;
 }
 
 void QmitkMultiLabelInspector::SetSelectedLabels(const LabelValueVectorType& selectedLabels)
 {
   if (EqualLabelSelections(this->GetSelectedLabels(), selectedLabels))
   {
     return;
   }
 
   this->UpdateSelectionModel(selectedLabels);
   m_LastValidSelectedLabels = selectedLabels;
 }
 
 void QmitkMultiLabelInspector::UpdateSelectionModel(const LabelValueVectorType& selectedLabels)
 {
   // create new selection by retrieving the corresponding indices of the labels
   QItemSelection newCurrentSelection;
   for (const auto& labelID : selectedLabels)
   {
     QModelIndexList matched = m_Model->match(m_Model->index(0, 0), QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole, QVariant(labelID), 1, Qt::MatchRecursive);
     if (!matched.empty())
     {
       newCurrentSelection.select(matched.front(), matched.front());
     }
   }
 
   m_Controls->view->selectionModel()->select(newCurrentSelection, QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Current);
 }
 
 void QmitkMultiLabelInspector::SetSelectedLabel(mitk::LabelSetImage::LabelValueType selectedLabel)
 {
   this->SetSelectedLabels({ selectedLabel });
 }
 
 QmitkMultiLabelInspector::LabelValueVectorType QmitkMultiLabelInspector::GetSelectedLabelsFromSelectionModel() const
 {
   LabelValueVectorType result;
   QModelIndexList selectedIndexes = m_Controls->view->selectionModel()->selectedIndexes();
   for (const auto& index : std::as_const(selectedIndexes))
   {
     QVariant qvariantDataNode = m_Model->data(index, QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
     if (qvariantDataNode.canConvert<mitk::LabelSetImage::LabelValueType>())
     {
       result.push_back(qvariantDataNode.value<mitk::LabelSetImage::LabelValueType>());
     }
   }
   return result;
 }
 
 QmitkMultiLabelInspector::LabelValueVectorType QmitkMultiLabelInspector::GetSelectedLabels() const
 {
   return m_LastValidSelectedLabels;
 }
 
 mitk::Label* QmitkMultiLabelInspector::GetFirstSelectedLabelObject() const
 {
   if (m_LastValidSelectedLabels.empty() || m_Segmentation.IsNull())
     return nullptr;
 
   return m_Segmentation->GetLabel(m_LastValidSelectedLabels.front());
 }
 
 void QmitkMultiLabelInspector::OnChangeModelSelection(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/)
 {
   if (!m_ModelManipulationOngoing)
   {
     auto internalSelection = GetSelectedLabelsFromSelectionModel();
     if (internalSelection.empty())
     {
       //empty selections are not allowed by UI interactions, there should always be at least on label selected.
       //but selections are e.g. also cleared if the model is updated (e.g. due to addition of labels)
       UpdateSelectionModel(m_LastValidSelectedLabels);
     }
     else
     {
       m_LastValidSelectedLabels = internalSelection;
       emit CurrentSelectionChanged(GetSelectedLabels());
     }
   }
 }
 
 void QmitkMultiLabelInspector::WaitCursorOn() const
 {
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 }
 
 void QmitkMultiLabelInspector::WaitCursorOff() const
 {
   this->RestoreOverrideCursor();
 }
 
 void QmitkMultiLabelInspector::RestoreOverrideCursor() const
 {
   QApplication::restoreOverrideCursor();
 }
 
 mitk::Label* QmitkMultiLabelInspector::GetCurrentLabel() const
 {
   auto currentIndex = this->m_Controls->view->currentIndex();
   auto labelVariant = currentIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelDataRole);
   mitk::Label::Pointer currentIndexLabel = nullptr;
 
   if (labelVariant.isValid())
   {
     auto uncastedLabel = labelVariant.value<void*>();
     currentIndexLabel = static_cast<mitk::Label*>(uncastedLabel);
   }
   return currentIndexLabel;
 }
 
 QmitkMultiLabelInspector::IndexLevelType QmitkMultiLabelInspector::GetCurrentLevelType() const
 {
   auto currentIndex = this->m_Controls->view->currentIndex();
   auto labelInstanceVariant = currentIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceDataRole);
   auto labelVariant = currentIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelDataRole);
 
   if (labelInstanceVariant.isValid() )
   {
     return IndexLevelType::LabelInstance;
   }
   else if (labelVariant.isValid())
   {
     return IndexLevelType::LabelClass;
   }
 
   return IndexLevelType::Group;
 }
 
 QmitkMultiLabelInspector::LabelValueVectorType QmitkMultiLabelInspector::GetCurrentlyAffactedLabelInstances() const
 {
   auto currentIndex = m_Controls->view->currentIndex();
   return m_Model->GetLabelsInSubTree(currentIndex);
 }
 
 QmitkMultiLabelInspector::LabelValueVectorType QmitkMultiLabelInspector::GetLabelInstancesOfSelectedFirstLabel() const
 {
   if (m_Segmentation.IsNull())
     return {};
 
   if (this->GetSelectedLabels().empty())
     return {};
 
   const auto index = m_Model->indexOfLabel(this->GetSelectedLabels().front());
   return m_Model->GetLabelInstancesOfSameLabelClass(index);
 }
 
 mitk::Label* QmitkMultiLabelInspector::AddNewLabelInstanceInternal(mitk::Label* templateLabel)
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of AddNewLabelInstance.";
 
   if (nullptr == templateLabel)
     mitkThrow() << "QmitkMultiLabelInspector is in an invalid state. AddNewLabelInstanceInternal was called with a non existing label as template";
 
   auto groupID = m_Segmentation->GetGroupIndexOfLabel(templateLabel->GetValue());
   m_ModelManipulationOngoing = true;
   auto newLabel = m_Segmentation->AddLabel(templateLabel, groupID, true);
   m_ModelManipulationOngoing = false;
   this->SetSelectedLabel(newLabel->GetValue());
 
   auto index = m_Model->indexOfLabel(newLabel->GetValue());
   if (index.isValid())
   {
     m_Controls->view->expand(index.parent());
   }
   else
   {
     mitkThrow() << "Segmentation or QmitkMultiLabelTreeModel is in an invalid state. Label is not present in the model after adding it to the segmentation. Label value: " << newLabel->GetValue();
   }
 
   emit ModelUpdated();
   return newLabel;
 }
 
 mitk::Label* QmitkMultiLabelInspector::AddNewLabelInstance()
 {
   auto currentLabel = this->GetFirstSelectedLabelObject();
   if (nullptr == currentLabel)
     return nullptr;
 
   return this->AddNewLabelInstanceInternal(currentLabel);
 }
 
 mitk::Label* QmitkMultiLabelInspector::AddNewLabelInternal(const mitk::LabelSetImage::GroupIndexType& containingGroup)
 {
   auto newLabel = mitk::LabelSetImageHelper::CreateNewLabel(m_Segmentation);
 
   if (!m_DefaultLabelNaming)
     emit LabelRenameRequested(newLabel, false);
 
   m_ModelManipulationOngoing = true;
   m_Segmentation->AddLabel(newLabel, containingGroup, false);
   m_ModelManipulationOngoing = false;
 
   this->SetSelectedLabel(newLabel->GetValue());
 
   auto index = m_Model->indexOfLabel(newLabel->GetValue());
 
   if (!index.isValid())
     mitkThrow() << "Segmentation or QmitkMultiLabelTreeModel is in an invalid state. Label is not present in the "
                    "model after adding it to the segmentation. Label value: " << newLabel->GetValue();
 
   m_Controls->view->expand(index.parent());
 
   emit ModelUpdated();
 
   return newLabel;
 }
 
 mitk::Label* QmitkMultiLabelInspector::AddNewLabel()
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of AddNewLabel.";
 
   if (m_Segmentation.IsNull())
   {
     return nullptr;
   }
 
   auto currentLabel = this->GetFirstSelectedLabelObject();
   mitk::LabelSetImage::GroupIndexType groupID = nullptr != currentLabel
     ? m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue())
     : 0;
 
   return AddNewLabelInternal(groupID);
 }
 
 void QmitkMultiLabelInspector::DeleteLabelInstance()
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of DeleteLabelInstance.";
 
   if (m_Segmentation.IsNull())
     return;
 
   auto label = this->GetFirstSelectedLabelObject();
 
   if (nullptr == label)
     return;
 
   auto index = m_Model->indexOfLabel(label->GetValue());
   auto instanceName = index.data(Qt::DisplayRole);
 
   auto question = "Do you really want to delete label instance \"" + instanceName.toString() + "\"?";
   auto answer = QMessageBox::question(this, QString("Delete label instances"), question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answer == QMessageBox::Yes)
     this->DeleteLabelInternal({ label->GetValue() });
 }
 
 void QmitkMultiLabelInspector::DeleteLabel()
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of DeleteLabel.";
 
   if (m_Segmentation.IsNull())
     return;
 
   const auto label = this->GetFirstSelectedLabelObject();
 
   if (nullptr == label)
     return;
 
   const auto relevantLabels = this->GetLabelInstancesOfSelectedFirstLabel();
 
   if (relevantLabels.empty())
     return;
 
   auto question = "Do you really want to delete label \"" + QString::fromStdString(label->GetName());
   question = relevantLabels.size()==1 ? question + "\"?" : question + "\" with all "+QString::number(relevantLabels.size()) +" instances?";
 
   auto answer = QMessageBox::question(this, QString("Delete label"), question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answer == QMessageBox::Yes)
     this->DeleteLabelInternal(relevantLabels);
 }
 
 void QmitkMultiLabelInspector::DeleteLabelInternal(const LabelValueVectorType& labelValues)
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of DeleteLabelInternal.";
 
   if (m_Segmentation.IsNull())
   {
     return;
   }
 
   QVariant nextLabelVariant;
 
   this->WaitCursorOn();
   m_ModelManipulationOngoing = true;
   for (auto labelValue : labelValues)
   {
     if (labelValue == labelValues.back())
     {
       auto currentIndex = m_Model->indexOfLabel(labelValue);
       auto nextIndex = m_Model->ClosestLabelInstanceIndex(currentIndex);
       nextLabelVariant = nextIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
     }
 
     m_Segmentation->RemoveLabel(labelValue);
   }
   m_ModelManipulationOngoing = false;
   this->WaitCursorOff();
 
   if (nextLabelVariant.isValid())
   {
     auto newLabelValue = nextLabelVariant.value<LabelValueType>();
     this->SetSelectedLabel(newLabelValue);
 
     auto index = m_Model->indexOfLabel(newLabelValue); //we have to get index again, because it could have changed due to remove operation.
     if (index.isValid())
     {
       m_Controls->view->expand(index.parent());
     }
     else
     {
       mitkThrow() << "Segmentation or QmitkMultiLabelTreeModel is in an invalid state. Label is not present in the model after adding it to the segmentation. Label value: " << newLabelValue;
     }
   }
   else
   {
     this->SetSelectedLabels({});
   }
 
   emit ModelUpdated();
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 mitk::Label* QmitkMultiLabelInspector::AddNewGroup()
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of AddNewLabel.";
 
   if (m_Segmentation.IsNull())
   {
     return nullptr;
   }
 
   mitk::LabelSetImage::GroupIndexType groupID = 0;
   mitk::Label* newLabel = nullptr;
   m_ModelManipulationOngoing = true;
   try
   {
     this->WaitCursorOn();
     groupID = m_Segmentation->AddLayer();
     m_Segmentation->SetActiveLayer(groupID);
     this->WaitCursorOff();
     newLabel =  this->AddNewLabelInternal(groupID);
   }
   catch (mitk::Exception& e)
   {
     this->WaitCursorOff();
     m_ModelManipulationOngoing = false;
     MITK_ERROR << "Exception caught: " << e.GetDescription();
     QMessageBox::information(this, "Add group", "Could not add a new group. See error log for details.");
   }
   m_ModelManipulationOngoing = false;
 
   emit ModelUpdated();
   return newLabel;
 }
 
 void QmitkMultiLabelInspector::RemoveGroupInternal(const mitk::LabelSetImage::GroupIndexType& groupID)
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of RemoveLabel.";
 
   if (m_Segmentation.IsNull())
     return;
 
   if (m_Segmentation->GetNumberOfLayers() < 2)
     return;
 
   auto currentIndex = m_Model->indexOfGroup(groupID);
   auto nextIndex = m_Model->ClosestLabelInstanceIndex(currentIndex);
   auto labelVariant = nextIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
 
   try
   {
     this->WaitCursorOn();
     m_ModelManipulationOngoing = true;
     m_Segmentation->RemoveGroup(groupID);
     m_ModelManipulationOngoing = false;
     this->WaitCursorOff();
   }
   catch (mitk::Exception& e)
   {
     m_ModelManipulationOngoing = false;
     this->WaitCursorOff();
     MITK_ERROR << "Exception caught: " << e.GetDescription();
     QMessageBox::information(this, "Delete group", "Could not delete the currently active group. See error log for details.");
     return;
   }
 
   if (labelVariant.isValid())
   {
     auto newLabelValue = labelVariant.value<LabelValueType>();
     this->SetSelectedLabel(newLabelValue);
 
     auto index = m_Model->indexOfLabel(newLabelValue); //we have to get index again, because it could have changed due to remove operation.
     if (index.isValid())
     {
       m_Controls->view->expand(index.parent());
     }
     else
     {
       mitkThrow() << "Segmentation or QmitkMultiLabelTreeModel is in an invalid state. Label is not present in the model after adding it to the segmentation. Label value: " << newLabelValue;
     }
   }
   else
   {
     this->SetSelectedLabels({});
   }
 
   emit ModelUpdated();
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkMultiLabelInspector::RemoveGroup()
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of RemoveLabel.";
 
   if (m_Segmentation.IsNull())
     return;
 
   if (m_Segmentation->GetNumberOfLayers() < 2)
   {
     QMessageBox::information(this, "Delete group", "Cannot delete last remaining group. A segmentation must contain at least a single group.");
     return;
   }
 
   const auto* selectedLabel = this->GetFirstSelectedLabelObject();
 
   if (selectedLabel == nullptr)
     return;
 
   const auto group = m_Segmentation->GetGroupIndexOfLabel(selectedLabel->GetValue());
 
   auto question = QStringLiteral("Do you really want to delete group %1 including all of its labels?").arg(group);
   auto answer = QMessageBox::question(this, QStringLiteral("Delete group %1").arg(group), question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
 
   if (answer != QMessageBox::Yes)
     return;
 
   this->RemoveGroupInternal(group);
 }
 
 void QmitkMultiLabelInspector::OnDeleteGroup()
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of RemoveLabel.";
 
   if (m_Segmentation.IsNull())
     return;
 
   auto currentIndex = this->m_Controls->view->currentIndex();
   auto groupIDVariant = currentIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::GroupIDRole);
 
   if (groupIDVariant.isValid())
   {
     auto groupID = groupIDVariant.value<mitk::LabelSetImage::GroupIndexType>();
 
     auto question = QStringLiteral("Do you really want to delete group %1 including all of its labels?").arg(groupID);
     auto answer = QMessageBox::question(this, QString("Delete group %1").arg(groupID), question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
 
     if (answer != QMessageBox::Yes)
       return;
 
     this->RemoveGroupInternal(groupID);
   }
 };
 
 
 void QmitkMultiLabelInspector::OnContextMenuRequested(const QPoint& /*pos*/)
 {
   if (m_Segmentation.IsNull() || !this->isEnabled())
     return;
 
   const auto indexLevel = this->GetCurrentLevelType();
 
   if (IndexLevelType::Group == indexLevel)
   {
     QMenu* menu = new QMenu(this);
 
     if (m_AllowLabelModification)
     {
       QAction* addInstanceAction = new QAction(QmitkStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/icon_label_add.svg")), "&Add label", this);
       QObject::connect(addInstanceAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnAddLabel);
       menu->addAction(addInstanceAction);
 
       if (m_Segmentation->GetNumberOfLayers() > 1)
       {
         QAction* removeAction = new QAction(QmitkStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/icon_group_delete.svg")), "Delete group", this);
         QObject::connect(removeAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnDeleteGroup);
         menu->addAction(removeAction);
       }
     }
 
     if (m_AllowLockModification)
     {
       menu->addSeparator();
       QAction* lockAllAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/lock.svg")), "Lock group", this);
       QObject::connect(lockAllAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnLockAffectedLabels);
       menu->addAction(lockAllAction);
 
       QAction* unlockAllAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/unlock.svg")), "Unlock group", this);
       QObject::connect(unlockAllAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnUnlockAffectedLabels);
       menu->addAction(unlockAllAction);
     }
 
     if (m_AllowVisibilityModification)
     {
       menu->addSeparator();
 
       QAction* viewAllAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/visible.svg")), "Show group", this);
       QObject::connect(viewAllAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnSetAffectedLabelsVisible);
       menu->addAction(viewAllAction);
 
       QAction* hideAllAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/invisible.svg")), "Hide group", this);
       QObject::connect(hideAllAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnSetAffectedLabelsInvisible);
       menu->addAction(hideAllAction);
 
       menu->addSeparator();
 
       auto opacityAction = this->CreateOpacityAction();
       if (nullptr != opacityAction)
         menu->addAction(opacityAction);
     }
     menu->popup(QCursor::pos());
   }
   else if (IndexLevelType::LabelClass == indexLevel)
   {
     QMenu* menu = new QMenu(this);
 
     if (m_AllowLabelModification)
     {
       QAction* addInstanceAction = new QAction(QmitkStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/icon_label_add_instance.svg")), "Add label instance", this);
       QObject::connect(addInstanceAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnAddLabelInstance);
       menu->addAction(addInstanceAction);
 
       QAction* renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "&Rename label", this);
       QObject::connect(renameAction, SIGNAL(triggered(bool)), this, SLOT(OnRenameLabel(bool)));
       menu->addAction(renameAction);
 
       QAction* removeAction = new QAction(QmitkStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/icon_label_delete.svg")), "&Delete label", this);
       QObject::connect(removeAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnDeleteAffectedLabel);
       menu->addAction(removeAction);
     }
 
     if (m_AllowLockModification)
     {
       menu->addSeparator();
       QAction* lockAllAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/lock.svg")), "Lock label instances", this);
       QObject::connect(lockAllAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnLockAffectedLabels);
       menu->addAction(lockAllAction);
 
       QAction* unlockAllAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/unlock.svg")), "Unlock label instances", this);
       QObject::connect(unlockAllAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnUnlockAffectedLabels);
       menu->addAction(unlockAllAction);
     }
 
     if (m_AllowVisibilityModification)
     {
       menu->addSeparator();
 
       QAction* viewAllAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/visible.svg")), "Show label instances", this);
       QObject::connect(viewAllAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnSetAffectedLabelsVisible);
       menu->addAction(viewAllAction);
 
       QAction* hideAllAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/invisible.svg")), "Hide label instances", this);
       QObject::connect(hideAllAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnSetAffectedLabelsInvisible);
       menu->addAction(hideAllAction);
 
       menu->addSeparator();
 
       auto opacityAction = this->CreateOpacityAction();
       if (nullptr!=opacityAction)
         menu->addAction(opacityAction);
     }
     menu->popup(QCursor::pos());
   }
   else
   {
     auto selectedLabelValues = this->GetSelectedLabels();
     if (selectedLabelValues.empty())
       return;
 
     QMenu* menu = new QMenu(this);
 
     if (this->GetMultiSelectionMode() && selectedLabelValues.size() > 1)
     {
       QAction* mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge selection on current label", this);
       QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabels(bool)));
       menu->addAction(mergeAction);
 
       QAction* removeLabelsAction = new QAction(QmitkStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/icon_label_delete_instance.svg")), "&Delete selected labels", this);
       QObject::connect(removeLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnDeleteLabels(bool)));
       menu->addAction(removeLabelsAction);
 
       QAction* clearLabelsAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "&Clear selected labels", this);
       QObject::connect(clearLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnClearLabels(bool)));
       menu->addAction(clearLabelsAction);
     }
     else
     {
       if (m_AllowLabelModification)
       {
         QAction* addInstanceAction = new QAction(QmitkStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/icon_label_add_instance.svg")), "&Add label instance", this);
         QObject::connect(addInstanceAction, &QAction::triggered, this, &QmitkMultiLabelInspector::OnAddLabelInstance);
         menu->addAction(addInstanceAction);
 
         const auto selectedLabelIndex = m_Model->indexOfLabel(selectedLabelValues.front());
 
         if (m_Model->GetLabelInstancesOfSameLabelClass(selectedLabelIndex).size() > 1) // Only labels that actually appear as instance (having additional instances)
         {
           QAction* renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "&Rename label instance", this);
           QObject::connect(renameAction, SIGNAL(triggered(bool)), this, SLOT(OnRenameLabel(bool)));
           menu->addAction(renameAction);
 
           QAction* removeInstanceAction = new QAction(QmitkStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/icon_label_delete_instance.svg")), "&Delete label instance", this);
           QObject::connect(removeInstanceAction, &QAction::triggered, this, &QmitkMultiLabelInspector::DeleteLabelInstance);
           menu->addAction(removeInstanceAction);
         }
         else
         {
           QAction* renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "&Rename label", this);
           QObject::connect(renameAction, SIGNAL(triggered(bool)), this, SLOT(OnRenameLabel(bool)));
           menu->addAction(renameAction);
         }
 
         QAction* removeLabelAction = new QAction(QmitkStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/icon_label_delete.svg")), "Delete &label", this);
         QObject::connect(removeLabelAction, &QAction::triggered, this, &QmitkMultiLabelInspector::DeleteLabel);
         menu->addAction(removeLabelAction);
 
         QAction* clearAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "&Clear content", this);
         QObject::connect(clearAction, SIGNAL(triggered(bool)), this, SLOT(OnClearLabel(bool)));
         menu->addAction(clearAction);
       }
 
       if (m_AllowVisibilityModification)
       {
         menu->addSeparator();
         QAction* viewOnlyAction = new QAction(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/visible.svg")), "Hide everything in group but this", this);
         QObject::connect(viewOnlyAction, SIGNAL(triggered(bool)), this, SLOT(OnSetOnlyActiveLabelVisible(bool)));
         menu->addAction(viewOnlyAction);
 
         menu->addSeparator();
 
         auto opacityAction = this->CreateOpacityAction();
         if (nullptr != opacityAction)
           menu->addAction(opacityAction);
       }
     }
     menu->popup(QCursor::pos());
   }
 }
 
 QWidgetAction* QmitkMultiLabelInspector::CreateOpacityAction()
 {
   auto relevantLabelValues = this->GetCurrentlyAffactedLabelInstances();
   std::vector<mitk::Label*> relevantLabels;
 
   if (!relevantLabelValues.empty())
   {
     for (auto value : relevantLabelValues)
     {
       auto label = this->m_Segmentation->GetLabel(value);
       if (nullptr == label)
         mitkThrow() << "Invalid state. Internal model returned a label value that does not exist in segmentation. Invalid value:" << value;
       relevantLabels.emplace_back(label);
     }
 
     auto* opacitySlider = new QSlider;
     opacitySlider->setMinimum(0);
     opacitySlider->setMaximum(100);
     opacitySlider->setOrientation(Qt::Horizontal);
 
     auto opacity = relevantLabels.front()->GetOpacity();
     opacitySlider->setValue(static_cast<int>(opacity * 100));
     auto segmentation = m_Segmentation;
 
     QObject::connect(opacitySlider, &QSlider::valueChanged, this, [segmentation, relevantLabels](const int value)
     {
       auto opacity = static_cast<float>(value) / 100.0f;
       for (auto label : relevantLabels)
       {
         label->SetOpacity(opacity);
         segmentation->UpdateLookupTable(label->GetValue());
       }
       mitk::RenderingManager::GetInstance()->RequestUpdateAll();
     }
     );
 
     QLabel* opacityLabel = new QLabel("Opacity: ");
     QVBoxLayout* opacityWidgetLayout = new QVBoxLayout;
     opacityWidgetLayout->setContentsMargins(4, 4, 4, 4);
     opacityWidgetLayout->addWidget(opacityLabel);
     opacityWidgetLayout->addWidget(opacitySlider);
     QWidget* opacityWidget = new QWidget;
     opacityWidget->setLayout(opacityWidgetLayout);
     QWidgetAction* opacityAction = new QWidgetAction(this);
     opacityAction->setDefaultWidget(opacityWidget);
 
     return opacityAction;
   }
 
   return nullptr;
 }
 
 void QmitkMultiLabelInspector::OnClearLabels(bool /*value*/)
 {
   QString question = "Do you really want to clear the selected labels?";
 
   QMessageBox::StandardButton answerButton = QMessageBox::question(
     this, "Clear selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->WaitCursorOn();
     m_Segmentation->EraseLabels(this->GetSelectedLabels());
     this->WaitCursorOff();
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkMultiLabelInspector::OnDeleteAffectedLabel()
 {
   if (!m_AllowLabelModification)
     mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of RemoveLabel.";
 
   if (m_Segmentation.IsNull())
   {
     return;
   }
 
   auto affectedLabels = GetCurrentlyAffactedLabelInstances();
   auto currentLabel = m_Segmentation->GetLabel(affectedLabels.front());
   QString question = "Do you really want to delete all instances of label \"" + QString::fromStdString(currentLabel->GetName()) + "\"?";
 
   QMessageBox::StandardButton answerButton =
     QMessageBox::question(this, "Delete label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->DeleteLabelInternal(affectedLabels);
   }
 }
 
 void QmitkMultiLabelInspector::OnDeleteLabels(bool /*value*/)
 {
   QString question = "Do you really want to remove the selected labels?";
   QMessageBox::StandardButton answerButton = QMessageBox::question(
     this, "Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->WaitCursorOn();
     m_Segmentation->RemoveLabels(this->GetSelectedLabels());
     this->WaitCursorOff();
   }
 }
 
 void QmitkMultiLabelInspector::OnMergeLabels(bool /*value*/)
 {
   auto currentLabel = GetCurrentLabel();
   QString question = "Do you really want to merge selected labels into \"" + QString::fromStdString(currentLabel->GetName())+"\"?";
 
   QMessageBox::StandardButton answerButton = QMessageBox::question(
     this, "Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->WaitCursorOn();
-    m_Segmentation->MergeLabels(currentLabel->GetValue(), this->GetSelectedLabels(), m_Segmentation->GetActiveLayer());
+    m_Segmentation->MergeLabels(currentLabel->GetValue(), this->GetSelectedLabels());
     this->WaitCursorOff();
 
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkMultiLabelInspector::OnAddLabel()
 {
   auto currentIndex = this->m_Controls->view->currentIndex();
   auto groupIDVariant = currentIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::GroupIDRole);
 
   if (groupIDVariant.isValid())
   {
     auto groupID = groupIDVariant.value<mitk::LabelSetImage::GroupIndexType>();
     this->AddNewLabelInternal(groupID);
   }
 }
 
 void QmitkMultiLabelInspector::OnAddLabelInstance()
 {
   auto currentLabel = this->GetCurrentLabel();
   if (nullptr == currentLabel)
     return;
 
   this->AddNewLabelInstanceInternal(currentLabel);
 }
 
 void QmitkMultiLabelInspector::OnClearLabel(bool /*value*/)
 {
   auto currentLabel = GetFirstSelectedLabelObject();
   QString question = "Do you really want to clear the contents of label \"" + QString::fromStdString(currentLabel->GetName())+"\"?";
 
   QMessageBox::StandardButton answerButton =
     QMessageBox::question(this, "Clear label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->WaitCursorOn();
     m_Segmentation->EraseLabel(currentLabel->GetValue());
     this->WaitCursorOff();
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkMultiLabelInspector::OnRenameLabel(bool /*value*/)
 {
   auto relevantLabelValues = this->GetCurrentlyAffactedLabelInstances();
   auto currentLabel = this->GetCurrentLabel();
 
   emit LabelRenameRequested(currentLabel, true);
 
   for (auto value : relevantLabelValues)
   {
     if (value != currentLabel->GetValue())
     {
       auto label = this->m_Segmentation->GetLabel(value);
       if (nullptr == label)
         mitkThrow() << "Invalid state. Internal model returned a label value that does not exist in segmentation. Invalid value:" << value;
 
       label->SetName(currentLabel->GetName());
       label->SetColor(currentLabel->GetColor());
       m_Segmentation->UpdateLookupTable(label->GetValue());
       mitk::DICOMSegmentationPropertyHelper::SetDICOMSegmentProperties(label);
     }
   }
   emit ModelUpdated();
 }
 
 
 void QmitkMultiLabelInspector::SetLockOfAffectedLabels(bool locked) const
 {
   auto relevantLabelValues = this->GetCurrentlyAffactedLabelInstances();
 
   if (!relevantLabelValues.empty())
   {
     for (auto value : relevantLabelValues)
     {
       auto label = this->m_Segmentation->GetLabel(value);
       if (nullptr == label)
         mitkThrow() << "Invalid state. Internal model returned a label value that does not exist in segmentation. Invalid value:" << value;
       label->SetLocked(locked);
     }
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkMultiLabelInspector::OnUnlockAffectedLabels()
 {
   this->SetLockOfAffectedLabels(false);
 }
 
 void QmitkMultiLabelInspector::OnLockAffectedLabels()
 {
   this->SetLockOfAffectedLabels(true);
 }
 
 void QmitkMultiLabelInspector::SetVisibilityOfAffectedLabels(bool visible) const
 {
   auto relevantLabelValues = this->GetCurrentlyAffactedLabelInstances();
 
   if (!relevantLabelValues.empty())
   {
     for (auto value : relevantLabelValues)
     {
       auto label = this->m_Segmentation->GetLabel(value);
       if (nullptr == label)
         mitkThrow() << "Invalid state. Internal model returned a label value that does not exist in segmentation. Invalid value:" << value;
       label->SetVisible(visible);
       m_Segmentation->UpdateLookupTable(label->GetValue());
     }
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkMultiLabelInspector::OnSetAffectedLabelsVisible()
 {
   this->SetVisibilityOfAffectedLabels(true);
 }
 
 void QmitkMultiLabelInspector::OnSetAffectedLabelsInvisible()
 {
   this->SetVisibilityOfAffectedLabels(false);
 }
 
 void QmitkMultiLabelInspector::OnSetOnlyActiveLabelVisible(bool /*value*/)
 {
   auto currentLabel = GetFirstSelectedLabelObject();
   const auto labelID = currentLabel->GetValue();
   m_Segmentation->SetAllLabelsVisible(false);
 
   currentLabel->SetVisible(true);
   m_Segmentation->UpdateLookupTable(labelID);
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 
   this->PrepareGoToLabel(labelID);
 }
 
 void QmitkMultiLabelInspector::OnItemDoubleClicked(const QModelIndex& index)
 {
   if (!index.isValid()) return;
   if (index.column() > 0) return;
 
   auto labelVariant = index.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
 
   if (!labelVariant.isValid()) return;
 
   const auto labelID = labelVariant.value<mitk::Label::PixelType>();
 
   if (QApplication::queryKeyboardModifiers().testFlag(Qt::AltModifier))
   {
     this->OnRenameLabel(false);
     return;
   }
 
   this->PrepareGoToLabel(labelID);
 }
 
 void QmitkMultiLabelInspector::PrepareGoToLabel(mitk::Label::PixelType labelID) const
 {
   this->WaitCursorOn();
   m_Segmentation->UpdateCenterOfMass(labelID);
   const auto currentLabel = m_Segmentation->GetLabel(labelID);
   const mitk::Point3D& pos = currentLabel->GetCenterOfMassCoordinates();
   this->WaitCursorOff();
 
   if (pos.GetVnlVector().max_value() > 0.0)
   {
     emit GoToLabel(currentLabel->GetValue(), pos);
   }
 }
 
diff --git a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.cpp b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.cpp
index dfedd05609..574f44d36f 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.cpp
@@ -1,1025 +1,1024 @@
 /*============================================================================
 
 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 "QmitkMultiLabelTreeModel.h"
 
 #include <mitkMultiLabelEvents.h>
 #include <mitkRenderingManager.h>
 
 #include <QmitkStyleManager.h>
 
 
 class QmitkMultiLabelSegTreeItem
 {
 public:
   enum class ItemType
   {
     Group,
     Label,
     Instance
   };
 
   QmitkMultiLabelSegTreeItem()
   {
   };
 
   explicit QmitkMultiLabelSegTreeItem(ItemType type, QmitkMultiLabelSegTreeItem* parentItem,
     mitk::Label* label = nullptr, std::string className = ""): m_parentItem(parentItem), m_ItemType(type), m_Label(label), m_ClassName(className)
   {
   };
 
   ~QmitkMultiLabelSegTreeItem()
   {
     for (auto item : m_childItems)
     {
       delete item;
     }
   };
 
   void AppendChild(QmitkMultiLabelSegTreeItem* child)
   {
       m_childItems.push_back(child);
   };
 
   void RemoveChild(std::size_t row)
   {
     if (row < m_childItems.size())
     {
       delete m_childItems[row];
       m_childItems.erase(m_childItems.begin() + row);
     }
   };
 
   int Row() const
   {
     if (m_parentItem)
     {
       auto finding = std::find(m_parentItem->m_childItems.begin(), m_parentItem->m_childItems.end(), this);
       if (finding != m_parentItem->m_childItems.end())
       {
         return std::distance(m_parentItem->m_childItems.begin(), finding);
       }
     }
 
     return 0;
   };
 
   QmitkMultiLabelSegTreeItem* ParentItem()
   {
     return m_parentItem;
   };
 
   const QmitkMultiLabelSegTreeItem* ParentItem() const
   {
     return m_parentItem;
   };
 
   const QmitkMultiLabelSegTreeItem* NextSibblingItem() const
   {
     if (m_parentItem)
     {
       const std::vector<QmitkMultiLabelSegTreeItem*>::size_type row = this->Row();
       if (row + 1 < m_parentItem->m_childItems.size())
         return m_parentItem->m_childItems[row+1];
     }
 
     return nullptr;
   };
 
   const QmitkMultiLabelSegTreeItem* PrevSibblingItem() const
   {
     if (m_parentItem)
     {
       const std::vector<QmitkMultiLabelSegTreeItem*>::size_type row = this->Row();
       if (row > 0)
         return m_parentItem->m_childItems[row-1];
     }
 
     return nullptr;
   };
 
   const QmitkMultiLabelSegTreeItem* RootItem() const
   {
     auto item = this;
     while (item->m_parentItem != nullptr)
     {
       item = item->m_parentItem;
     }
     return item;
   };
 
   std::size_t GetGroupID() const
   {
     auto root = this->RootItem();
     auto item = this;
     if (root == this) return 0;
 
     while (root != item->m_parentItem)
     {
       item = item->m_parentItem;
     }
 
     auto iter = std::find(root->m_childItems.begin(), root->m_childItems.end(), item);
 
     if (root->m_childItems.end() == iter) mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Root does not have an currentItem as child that has root as parent.";
 
     return std::distance(root->m_childItems.begin(), iter);
   }
 
   bool HandleAsInstance() const
   {
     return (ItemType::Instance == m_ItemType) || ((ItemType::Label == m_ItemType) && (m_childItems.size() == 1));
   }
 
   mitk::Label* GetLabel() const
   {
     if (ItemType::Instance == m_ItemType)
     {
       return m_Label;
     }
     if (ItemType::Label == m_ItemType)
     {
       if (m_childItems.empty()) mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Internal label currentItem has no instance currentItem.";
       return m_childItems[0]->GetLabel();
     }
 
     return nullptr;
   };
 
   mitk::LabelSetImage::LabelValueType GetLabelValue() const
   {
     auto label = this->GetLabel();
 
     if (nullptr == label)
     {
       mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Called GetLabelValue on an group currentItem.";
     }
 
     return label->GetValue();
   };
 
   /** returns a vector containing all label values of referenced by this item or its child items.*/
   std::vector< mitk::LabelSetImage::LabelValueType> GetLabelsInSubTree() const
   {
     if (this->m_ItemType == ItemType::Instance)
     {
       return { this->GetLabelValue() };
     }
 
     std::vector< mitk::LabelSetImage::LabelValueType> result;
     for (const auto child : this->m_childItems)
     {
       auto childresult = child->GetLabelsInSubTree();
       result.reserve(result.size() + childresult.size());
       result.insert(result.end(), childresult.begin(), childresult.end());
     }
 
     return result;
   }
 
   std::vector<QmitkMultiLabelSegTreeItem*> m_childItems;
   QmitkMultiLabelSegTreeItem* m_parentItem = nullptr;
   ItemType m_ItemType = ItemType::Group;
   mitk::Label::Pointer m_Label;
   std::string m_ClassName;
 };
 
 QModelIndex GetIndexByItem(const QmitkMultiLabelSegTreeItem* start, const QmitkMultiLabelTreeModel* model)
 {
   QModelIndex parentIndex = QModelIndex();
   if (nullptr != start->m_parentItem)
   {
     parentIndex = GetIndexByItem(start->m_parentItem, model);
   }
   else
   {
     return parentIndex;
   }
 
   return model->index(start->Row(), 0, parentIndex);
 }
 
 QmitkMultiLabelSegTreeItem* GetGroupItem(QmitkMultiLabelTreeModel::GroupIndexType groupIndex, QmitkMultiLabelSegTreeItem* root)
 {
   if (nullptr != root && groupIndex < root->m_childItems.size())
   {
     return root->m_childItems[groupIndex];
   }
 
   return nullptr;
 }
 
 QmitkMultiLabelSegTreeItem* GetInstanceItem(QmitkMultiLabelTreeModel::LabelValueType labelValue, QmitkMultiLabelSegTreeItem* root)
 {
   QmitkMultiLabelSegTreeItem* result = nullptr;
 
   for (auto item : root->m_childItems)
   {
     result = GetInstanceItem(labelValue, item);
     if (nullptr != result) return result;
   }
 
   if (root->m_ItemType == QmitkMultiLabelSegTreeItem::ItemType::Instance && root->GetLabelValue() == labelValue)
   {
     return root;
   }
 
   return nullptr;
 }
 
 const QmitkMultiLabelSegTreeItem* GetFirstInstanceLikeItem(const QmitkMultiLabelSegTreeItem* startItem)
 {
   const QmitkMultiLabelSegTreeItem* result = nullptr;
 
   if (nullptr != startItem)
   {
     if (startItem->HandleAsInstance())
     {
       result = startItem;
     }
     else if (!startItem->m_childItems.empty())
     {
       result = GetFirstInstanceLikeItem(startItem->m_childItems.front());
     }
   }
 
   return result;
 }
 
 QmitkMultiLabelSegTreeItem* GetLabelItemInGroup(const std::string& labelName, QmitkMultiLabelSegTreeItem* group)
 {
   if (nullptr != group)
   {
     auto predicate = [labelName](const QmitkMultiLabelSegTreeItem* item) { return labelName == item->m_ClassName; };
     auto finding = std::find_if(group->m_childItems.begin(), group->m_childItems.end(), predicate);
     if (group->m_childItems.end() != finding)
     {
       return *finding;
     }
   }
 
   return nullptr;
 }
 
 QmitkMultiLabelTreeModel::QmitkMultiLabelTreeModel(QObject *parent) : QAbstractItemModel(parent)
 {
   m_RootItem = std::make_unique<QmitkMultiLabelSegTreeItem>();
 }
 
 QmitkMultiLabelTreeModel ::~QmitkMultiLabelTreeModel()
 {
   this->SetSegmentation(nullptr);
 };
 
 int QmitkMultiLabelTreeModel::columnCount(const QModelIndex& /*parent*/) const
 {
   return 4;
 }
 
 int QmitkMultiLabelTreeModel::rowCount(const QModelIndex &parent) const
 {
   if (parent.column() > 0)
     return 0;
 
   if (m_Segmentation.IsNull())
     return 0;
 
   QmitkMultiLabelSegTreeItem* parentItem = m_RootItem.get();
 
   if (parent.isValid())
     parentItem = static_cast<QmitkMultiLabelSegTreeItem *>(parent.internalPointer());
 
   if (parentItem->HandleAsInstance())
   {
     return 0;
   }
 
   return parentItem->m_childItems.size();
 }
 
 QVariant QmitkMultiLabelTreeModel::data(const QModelIndex &index, int role) const
 {
   if (!index.isValid())
     return QVariant();
 
   auto item = static_cast<QmitkMultiLabelSegTreeItem*>(index.internalPointer());
 
   if (!item)
     return QVariant();
 
   if (role == Qt::DisplayRole||role == Qt::EditRole)
   {
     if (TableColumns::NAME_COL == index.column())
     {
       switch (item->m_ItemType)
       {
         case QmitkMultiLabelSegTreeItem::ItemType::Group:
           return QVariant(QString("Group %1").arg(item->GetGroupID()));
 
         case QmitkMultiLabelSegTreeItem::ItemType::Label:
         {
           auto label = item->GetLabel();
 
           if (nullptr == label)
             mitkThrow() << "Invalid internal state. QmitkMultiLabelTreeModel currentItem is refering to a label that does not exist.";
 
           QString name = QString::fromStdString(label->GetName());
 
           if (!item->HandleAsInstance())
             name = name + QString(" (%1 instances)").arg(item->m_childItems.size());
 
           return QVariant(name);
         }
 
         case QmitkMultiLabelSegTreeItem::ItemType::Instance:
         {
           auto label = item->GetLabel();
 
           if (nullptr == label)
             mitkThrow() << "Invalid internal state. QmitkMultiLabelTreeModel currentItem is refering to a label that does not exist.";
 
           return QVariant(QString::fromStdString(label->GetName()) + QString(" [%1]").arg(item->GetLabelValue()));
         }
       }
     }
     else
     {
       if (item->HandleAsInstance())
       {
         auto label = item->GetLabel();
 
         if (TableColumns::LOCKED_COL == index.column())
         {
           return QVariant(label->GetLocked());
         }
         else if (TableColumns::COLOR_COL == index.column())
         {
           return QVariant(QColor(label->GetColor().GetRed() * 255, label->GetColor().GetGreen() * 255, label->GetColor().GetBlue() * 255));
         }
         else if (TableColumns::VISIBLE_COL == index.column())
         {
           return QVariant(label->GetVisible());
         }
       }
     }
   }
   else if (role == ItemModelRole::LabelDataRole)
   {
     auto label = item->GetLabel();
     if (nullptr!=label)  return QVariant::fromValue<void*>(label);
   }
   else if (role == ItemModelRole::LabelValueRole)
   {
     auto label = item->GetLabel();
     if (nullptr != label)  return QVariant(label->GetValue());
   }
   else if (role == ItemModelRole::LabelInstanceDataRole)
   {
     if (item->HandleAsInstance())
     {
       auto label = item->GetLabel();
       return QVariant::fromValue<void*>(label);
     }
   }
   else if (role == ItemModelRole::LabelInstanceValueRole)
   {
     if (item->HandleAsInstance())
     {
       auto label = item->GetLabel();
       return QVariant(label->GetValue());
     }
   }
   else if (role == ItemModelRole::GroupIDRole)
   {
     QVariant v;
     v.setValue(item->GetGroupID());
     return v;
   }
 
   return QVariant();
 }
 
 mitk::Color QtToMitk(const QColor& color)
 {
   mitk::Color mitkColor;
 
   mitkColor.SetRed(color.red() / 255.0f);
   mitkColor.SetGreen(color.green() / 255.0f);
   mitkColor.SetBlue(color.blue() / 255.0f);
 
   return mitkColor;
 }
 
 bool QmitkMultiLabelTreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
 {
   if (!index.isValid())
     return false;
 
   auto item = static_cast<QmitkMultiLabelSegTreeItem*>(index.internalPointer());
 
   if (!item)
     return false;
 
   if (role == Qt::EditRole)
   {
     if (TableColumns::NAME_COL != index.column())
     {
       if (item->HandleAsInstance())
       {
         auto label = item->GetLabel();
 
         if (TableColumns::LOCKED_COL == index.column())
         {
           label->SetLocked(value.toBool());
         }
         else if (TableColumns::COLOR_COL == index.column())
         {
           label->SetColor(QtToMitk(value.value<QColor>()));
         }
         else if (TableColumns::VISIBLE_COL == index.column())
         {
           label->SetVisible(value.toBool());
         }
-        auto groupID = m_Segmentation->GetGroupIndexOfLabel(label->GetValue());
         m_Segmentation->UpdateLookupTable(label->GetValue());
         m_Segmentation->Modified();
         mitk::RenderingManager::GetInstance()->RequestUpdateAll();
       }
       else
       {
 
       }
       return true;
     }
   }
   return false;
 }
 
 QModelIndex QmitkMultiLabelTreeModel::index(int row, int column, const QModelIndex &parent) const
 {
   if (!hasIndex(row, column, parent))
     return QModelIndex();
 
   auto parentItem = m_RootItem.get();
 
   if (parent.isValid())
     parentItem = static_cast<QmitkMultiLabelSegTreeItem *>(parent.internalPointer());
 
   QmitkMultiLabelSegTreeItem *childItem = parentItem->m_childItems[row];
   if (childItem)
     return createIndex(row, column, childItem);
   else
     return QModelIndex();
 }
 
 QModelIndex QmitkMultiLabelTreeModel::indexOfLabel(mitk::Label::PixelType labelValue) const
 {
   if (labelValue == mitk::LabelSetImage::UNLABELED_VALUE) return QModelIndex();
   auto relevantItem = GetInstanceItem(labelValue, this->m_RootItem.get());
 
   if (nullptr == relevantItem)
     return QModelIndex();
 
   auto labelItem = relevantItem->ParentItem();
 
   if (labelItem->m_childItems.size() == 1)
   { //was the only instance of the label, therefor return the label item instat.
     relevantItem = labelItem;
   }
 
   return GetIndexByItem(relevantItem, this);
 }
 
 QModelIndex QmitkMultiLabelTreeModel::indexOfGroup(mitk::LabelSetImage::GroupIndexType groupIndex) const
 {
   auto relevantItem = GetGroupItem(groupIndex, this->m_RootItem.get());
 
   if (nullptr == relevantItem) QModelIndex();
 
   return GetIndexByItem(relevantItem, this);
 }
 
 QModelIndex QmitkMultiLabelTreeModel::parent(const QModelIndex &child) const
 {
   if (!child.isValid())
     return QModelIndex();
 
   QmitkMultiLabelSegTreeItem *childItem = static_cast<QmitkMultiLabelSegTreeItem *>(child.internalPointer());
   QmitkMultiLabelSegTreeItem *parentItem = childItem->ParentItem();
 
   if (parentItem == m_RootItem.get())
     return QModelIndex();
 
   return createIndex(parentItem->Row(), 0, parentItem);
 }
 
 QModelIndex QmitkMultiLabelTreeModel::ClosestLabelInstanceIndex(const QModelIndex& currentIndex) const
 {
   if (!currentIndex.isValid()) return QModelIndex();
 
   auto currentItem = static_cast<const QmitkMultiLabelSegTreeItem*>(currentIndex.internalPointer());
   if (!currentItem) return QModelIndex();
 
   if (currentItem->RootItem() != this->m_RootItem.get()) mitkThrow() << "Invalid call. Passed currentIndex does not seem to be a valid index of this model. It is either outdated or from another model.";
 
   const QmitkMultiLabelSegTreeItem* resultItem = nullptr;
   auto searchItem = currentItem;
   const auto rootItem = currentItem->RootItem();
 
   while (searchItem != rootItem)
   {
     const auto* sibling = searchItem;
 
     while (sibling != nullptr)
     {
       sibling = sibling->NextSibblingItem();
       resultItem = GetFirstInstanceLikeItem(sibling);
 
       if (nullptr != resultItem)
         break;
     }
 
     if (nullptr != resultItem)
       break;
 
     // No next closest label instance on this level -> check for closest before
     sibling = searchItem;
 
     while (sibling != nullptr)
     {
       sibling = sibling->PrevSibblingItem();
       resultItem = GetFirstInstanceLikeItem(sibling);
 
       if (nullptr != resultItem)
         break;
     }
 
     if (nullptr != resultItem)
       break;
 
     // No closest label instance before current on this level -> moeve one level up
     searchItem = searchItem->ParentItem();
   }
 
   if (nullptr == resultItem)
     return QModelIndex();
 
   return GetIndexByItem(resultItem, this);
 }
 
 QModelIndex QmitkMultiLabelTreeModel::FirstLabelInstanceIndex(const QModelIndex& currentIndex) const
 {
   const QmitkMultiLabelSegTreeItem* currentItem = nullptr;
 
   if (!currentIndex.isValid())
   {
     currentItem = this->m_RootItem.get();
   }
   else
   {
     currentItem = static_cast<const QmitkMultiLabelSegTreeItem*>(currentIndex.internalPointer());
   }
 
   if (!currentItem) return QModelIndex();
 
   if (currentItem->RootItem() != this->m_RootItem.get()) mitkThrow() << "Invalid call. Passed currentIndex does not seem to be a valid index of this model. It is either outdated or from another model.";
 
   const QmitkMultiLabelSegTreeItem* resultItem = nullptr;
   resultItem = GetFirstInstanceLikeItem(currentItem);
 
   if (nullptr == resultItem)
     return QModelIndex();
 
   return GetIndexByItem(resultItem, this);
 }
 
 ///** Returns the index to the next node in the tree that behaves like an instance (label node with only one instance
 //or instance node). If current index is at the end, an invalid index is returned.*/
 //QModelIndex QmitkMultiLabelTreeModel::PrevLabelInstanceIndex(const QModelIndex& currentIndex) const;
 
 std::vector <QmitkMultiLabelTreeModel::LabelValueType> QmitkMultiLabelTreeModel::GetLabelsInSubTree(const QModelIndex& currentIndex) const
 {
   const QmitkMultiLabelSegTreeItem* currentItem = nullptr;
 
   if (!currentIndex.isValid())
   {
     currentItem = this->m_RootItem.get();
   }
   else
   {
     currentItem = static_cast<const QmitkMultiLabelSegTreeItem*>(currentIndex.internalPointer());
   }
 
   if (!currentItem) return {};
 
   return currentItem->GetLabelsInSubTree();
 }
 
 std::vector <QmitkMultiLabelTreeModel::LabelValueType> QmitkMultiLabelTreeModel::GetLabelInstancesOfSameLabelClass(const QModelIndex& currentIndex) const
 {
   const QmitkMultiLabelSegTreeItem* currentItem = nullptr;
 
   if (currentIndex.isValid())
   {
     currentItem = static_cast<const QmitkMultiLabelSegTreeItem*>(currentIndex.internalPointer());
   }
 
   if (!currentItem)
     return {};
 
   if (QmitkMultiLabelSegTreeItem::ItemType::Group == currentItem->m_ItemType)
     return {};
 
   if (QmitkMultiLabelSegTreeItem::ItemType::Instance == currentItem->m_ItemType)
     currentItem = currentItem->ParentItem();
 
   return currentItem->GetLabelsInSubTree();
 }
 
 Qt::ItemFlags QmitkMultiLabelTreeModel::flags(const QModelIndex &index) const
 {
   if (!index.isValid())
     return Qt::NoItemFlags;
 
   if (!index.isValid())
     return Qt::NoItemFlags;
 
   auto item = static_cast<QmitkMultiLabelSegTreeItem*>(index.internalPointer());
 
   if (!item)
     return Qt::NoItemFlags;
 
   if (TableColumns::NAME_COL != index.column())
   {
     if (item->HandleAsInstance() &&
       ((TableColumns::VISIBLE_COL == index.column() && m_AllowVisibilityModification) ||
        (TableColumns::COLOR_COL == index.column() && m_AllowVisibilityModification) || //m_AllowVisibilityModification controls visibility and color
        (TableColumns::LOCKED_COL == index.column() && m_AllowLockModification)))
     {
       return Qt::ItemIsEnabled | Qt::ItemIsEditable;
     }
     else
     {
       return Qt::ItemIsEnabled;
     }
   }
   else
   {
     if (item->HandleAsInstance())
     {
       return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
     }
     else
     {
       return Qt::ItemIsEnabled;
     }
   }
 
   return Qt::NoItemFlags;
 }
 
 QVariant QmitkMultiLabelTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
 {
   if ((Qt::DisplayRole == role) && (Qt::Horizontal == orientation))
   {
     if (TableColumns::NAME_COL == section)
     {
       return "Name";
     }
     else if (TableColumns::LOCKED_COL == section)
     {
       return "Locked";
     }
     else if (TableColumns::COLOR_COL == section)
     {
       return "Color";
     }
     else if (TableColumns::VISIBLE_COL == section)
     {
       return "Visibility";
     }
   }
   return QVariant();
 }
 
 const mitk::LabelSetImage* QmitkMultiLabelTreeModel::GetSegmentation() const
 {
   return m_Segmentation;
 }
 
 
 void QmitkMultiLabelTreeModel::SetSegmentation(mitk::LabelSetImage* segmentation)
 {
   if (m_Segmentation != segmentation)
   {
     this->m_Segmentation = segmentation;
     this->AddObserver();
 
     this->UpdateInternalTree();
   }
 }
 
 
 /**Helper function that adds a labek into the item tree. Passes back the new created instance iten*/
 QmitkMultiLabelSegTreeItem* AddLabelToGroupTree(mitk::Label* label, QmitkMultiLabelSegTreeItem* groupItem, bool& newLabelItemCreated)
 {
   if (nullptr == groupItem) return nullptr;
   if (nullptr == label) return nullptr;
 
   newLabelItemCreated = false;
 
   std::set<std::string> labelNames;
   for (auto labelItem : groupItem->m_childItems)
   {
     labelNames.emplace(labelItem->GetLabel()->GetName());
   }
 
   QmitkMultiLabelSegTreeItem* labelItem = nullptr;
   auto finding = labelNames.find(label->GetName());
   if (finding != labelNames.end())
   { //other label with same name exists
     labelItem = groupItem->m_childItems[std::distance(labelNames.begin(), finding)];
   }
   else
   {
     newLabelItemCreated = true;
     labelItem = new QmitkMultiLabelSegTreeItem(QmitkMultiLabelSegTreeItem::ItemType::Label, groupItem, nullptr, label->GetName());
 
     auto predicate = [label](const std::string& name) { return name > label->GetName(); };
     auto insertFinding = std::find_if(labelNames.begin(), labelNames.end(), predicate);
 
     groupItem->m_childItems.insert(groupItem->m_childItems.begin() + std::distance(labelNames.begin(), insertFinding), labelItem);
   }
 
   auto instanceItem = new QmitkMultiLabelSegTreeItem(QmitkMultiLabelSegTreeItem::ItemType::Instance, labelItem, label);
 
   auto predicate = [label](const QmitkMultiLabelSegTreeItem* item) { return item->GetLabelValue() > label->GetValue(); };
   auto insertFinding = std::find_if(labelItem->m_childItems.begin(), labelItem->m_childItems.end(), predicate);
   labelItem->m_childItems.insert(labelItem->m_childItems.begin() + std::distance(labelItem->m_childItems.begin(), insertFinding), instanceItem);
 
   return instanceItem;
 }
 
 void QmitkMultiLabelTreeModel::GenerateInternalGroupTree(unsigned int groupID, QmitkMultiLabelSegTreeItem* groupItem)
 {
   auto labels = m_Segmentation->GetLabelsByValue(m_Segmentation->GetLabelValuesByGroup(groupID));
 
   for (auto& label : labels)
   {
     if (label->GetValue()== mitk::LabelSetImage::UNLABELED_VALUE) continue;
 
     bool newItemCreated = false;
     AddLabelToGroupTree(label, groupItem, newItemCreated);
   }
 }
 
 QmitkMultiLabelSegTreeItem* QmitkMultiLabelTreeModel::GenerateInternalTree()
 {
   auto rootItem = new QmitkMultiLabelSegTreeItem();
 
   if (m_Segmentation.IsNotNull())
   {
     for (unsigned int groupID = 0; groupID < m_Segmentation->GetNumberOfLayers(); ++groupID)
     {
       auto groupItem = new QmitkMultiLabelSegTreeItem(QmitkMultiLabelSegTreeItem::ItemType::Group, rootItem);
       rootItem->AppendChild(groupItem);
 
       GenerateInternalGroupTree(groupID, groupItem);
     }
   }
 
   return rootItem;
 }
 
 void QmitkMultiLabelTreeModel::UpdateInternalTree()
 {
   emit beginResetModel();
   auto newTree = this->GenerateInternalTree();
   this->m_RootItem.reset(newTree);
   emit endResetModel();
   emit modelChanged();
 }
 
 void QmitkMultiLabelTreeModel::ITKEventHandler(const itk::EventObject& e)
 {
   if (mitk::LabelAddedEvent().CheckEvent(&e))
   {
     auto labelEvent = dynamic_cast<const mitk::AnyLabelEvent*>(&e);
     this->OnLabelAdded(labelEvent->GetLabelValue());
   }
   else if (mitk::LabelModifiedEvent().CheckEvent(&e))
   {
     auto labelEvent = dynamic_cast<const mitk::AnyLabelEvent*>(&e);
     this->OnLabelModified(labelEvent->GetLabelValue());
   }
   else if (mitk::LabelRemovedEvent().CheckEvent(&e))
   {
     auto labelEvent = dynamic_cast<const mitk::AnyLabelEvent*>(&e);
     this->OnLabelRemoved(labelEvent->GetLabelValue());
   }
   else if (mitk::GroupAddedEvent().CheckEvent(&e))
   {
     auto labelEvent = dynamic_cast<const mitk::AnyGroupEvent*>(&e);
     this->OnGroupAdded(labelEvent->GetGroupID());
   }
   else if (mitk::GroupModifiedEvent().CheckEvent(&e))
   {
     auto labelEvent = dynamic_cast<const mitk::AnyGroupEvent*>(&e);
     this->OnGroupModified(labelEvent->GetGroupID());
   }
   else if (mitk::GroupRemovedEvent().CheckEvent(&e))
   {
     auto labelEvent = dynamic_cast<const mitk::AnyGroupEvent*>(&e);
     this->OnGroupRemoved(labelEvent->GetGroupID());
   }
 }
 
 void QmitkMultiLabelTreeModel::AddObserver()
 {
   m_LabelAddedObserver.Reset();
   m_LabelModifiedObserver.Reset();
   m_LabelRemovedObserver.Reset();
   m_GroupAddedObserver.Reset();
   m_GroupModifiedObserver.Reset();
   m_GroupRemovedObserver.Reset();
 
   if (this->m_Segmentation.IsNotNull())
   {
     auto& model = *this;
 
     m_LabelAddedObserver.Reset(m_Segmentation, mitk::LabelAddedEvent(), [&model](const itk::EventObject& event){model.ITKEventHandler(event);});
     m_LabelModifiedObserver.Reset(m_Segmentation, mitk::LabelModifiedEvent(), [&model](const itk::EventObject& event) {model.ITKEventHandler(event); });
     m_LabelRemovedObserver.Reset(m_Segmentation, mitk::LabelRemovedEvent(), [&model](const itk::EventObject& event) {model.ITKEventHandler(event); });
     m_GroupAddedObserver.Reset(m_Segmentation, mitk::GroupAddedEvent(), [&model](const itk::EventObject& event) {
       model.ITKEventHandler(event); });
     m_GroupModifiedObserver.Reset(m_Segmentation, mitk::GroupModifiedEvent(), [&model](const itk::EventObject& event) {model.ITKEventHandler(event); });
     m_GroupRemovedObserver.Reset(m_Segmentation, mitk::GroupRemovedEvent(), [&model](const itk::EventObject& event) {model.ITKEventHandler(event); });
   }
 }
 
 void QmitkMultiLabelTreeModel::OnLabelAdded(LabelValueType labelValue)
 {
   GroupIndexType groupIndex = m_Segmentation->GetGroupIndexOfLabel(labelValue);
   auto label = m_Segmentation->GetLabel(labelValue);
   if (nullptr == label) mitkThrow() << "Invalid internal state. Segmentation signaled the addition of an label that does not exist in the segmentation. Invalid label value:" << labelValue;
   if (labelValue == mitk::LabelSetImage::UNLABELED_VALUE) return;
 
   auto groupItem = GetGroupItem(groupIndex, this->m_RootItem.get());
 
   bool newLabelCreated = false;
   auto instanceItem = AddLabelToGroupTree(label, groupItem, newLabelCreated);
 
   if (newLabelCreated)
   {
     if (groupItem->m_childItems.size() == 1)
     { //first label added
       auto groupIndex = GetIndexByItem(groupItem, this);
       emit dataChanged(groupIndex, groupIndex);
       this->beginInsertRows(groupIndex, instanceItem->ParentItem()->Row(), instanceItem->ParentItem()->Row());
       this->endInsertRows();
     }
     else
     { //whole new label level added to group item
       auto groupIndex = GetIndexByItem(groupItem, this);
       this->beginInsertRows(groupIndex, instanceItem->ParentItem()->Row(), instanceItem->ParentItem()->Row());
       this->endInsertRows();
     }
   }
   else
   {
     if (instanceItem->ParentItem()->m_childItems.size() < 3)
     { //second instance item was added, so label item will now able to colapse
       // -> the whole label node has to be updated.
       auto labelIndex = GetIndexByItem(instanceItem->ParentItem(), this);
       emit dataChanged(labelIndex, labelIndex);
       this->beginInsertRows(labelIndex, 0, instanceItem->ParentItem()->m_childItems.size()-1);
       this->endInsertRows();
     }
     else
     {
       // instance item was added to existing label item with multiple instances
       //-> just notify the row insertion
       auto labelIndex = GetIndexByItem(instanceItem->ParentItem(), this);
       this->beginInsertRows(labelIndex, instanceItem->Row(), instanceItem->Row());
       this->endInsertRows();
     }
   }
 }
 
 void QmitkMultiLabelTreeModel::OnLabelModified(LabelValueType labelValue)
 {
   if (labelValue == mitk::LabelSetImage::UNLABELED_VALUE) return;
 
   auto instanceItem = GetInstanceItem(labelValue, this->m_RootItem.get());
 
   if (nullptr == instanceItem)
   {
     mitkThrow() << "Internal invalid state. QmitkMultiLabelTreeModel recieved a LabelModified signal for a label that is not represented in the model. Invalid label: " << labelValue;
   }
 
   auto labelItem = instanceItem->ParentItem();
 
   if (labelItem->m_ClassName == instanceItem->GetLabel()->GetName())
   { //only the state of the label changed, but not its position in the model tree.
 
     auto index = GetIndexByItem(labelItem, this);
     emit dataChanged(index, index);
   }
   else
   { //the name of the label changed and thus its place in the model tree, delete the current item and add a new one
     this->OnLabelRemoved(labelValue);
     this->OnLabelAdded(labelValue);
   }
 }
 
 void QmitkMultiLabelTreeModel::OnLabelRemoved(LabelValueType labelValue)
 {
   if (labelValue == mitk::LabelSetImage::UNLABELED_VALUE) return;
   auto instanceItem = GetInstanceItem(labelValue, this->m_RootItem.get());
 
   if (nullptr == instanceItem) mitkThrow() << "Internal invalid state. QmitkMultiLabelTreeModel recieved a LabelRemoved signal for a label that is not represented in the model. Invalid label: " << labelValue;
 
   auto labelItem = instanceItem->ParentItem();
 
   if (labelItem->m_childItems.size() > 2)
   {
     auto labelIndex = GetIndexByItem(labelItem, this);
     this->beginRemoveRows(labelIndex, instanceItem->Row(), instanceItem->Row());
     labelItem->RemoveChild(instanceItem->Row());
     this->endRemoveRows();
   }
   else if (labelItem->m_childItems.size() == 2)
   { //After removal only one label is left -> the whole label node is about to be changed (no instances are shown any more).
     auto labelIndex = GetIndexByItem(labelItem, this);
     this->beginRemoveRows(labelIndex, instanceItem->Row(), instanceItem->Row());
     labelItem->RemoveChild(instanceItem->Row());
     this->endRemoveRows();
     emit dataChanged(labelIndex, labelIndex);
   }
   else
   { //was the only instance of the label, therefor also remove the label node from the tree.
     auto groupItem = labelItem->ParentItem();
     auto groupIndex = GetIndexByItem(groupItem, this);
     this->beginRemoveRows(groupIndex, labelItem->Row(), labelItem->Row());
     groupItem->RemoveChild(labelItem->Row());
     this->endRemoveRows();
   }
 }
 
 void QmitkMultiLabelTreeModel::OnGroupAdded(GroupIndexType groupIndex)
 {
   if (m_ShowGroups)
   {
     this->beginInsertRows(QModelIndex(), groupIndex, groupIndex);
     auto rootItem = m_RootItem.get();
     auto groupItem = new QmitkMultiLabelSegTreeItem(QmitkMultiLabelSegTreeItem::ItemType::Group, rootItem);
     rootItem->AppendChild(groupItem);
     this->GenerateInternalGroupTree(groupIndex, groupItem);
     this->endInsertRows();
   }
 }
 
 void QmitkMultiLabelTreeModel::OnGroupModified(GroupIndexType /*groupIndex*/)
 {
   //currently not needed
 }
 
 void QmitkMultiLabelTreeModel::OnGroupRemoved(GroupIndexType groupIndex)
 {
   if (m_ShowGroups)
   {
     this->beginRemoveRows(QModelIndex(), groupIndex, groupIndex);
     auto root = m_RootItem.get();
     root->RemoveChild(groupIndex);
     this->endRemoveRows();
   }
 }
 
 void QmitkMultiLabelTreeModel::SetAllowVisibilityModification(bool vmod)
 {
   m_AllowVisibilityModification = vmod;
 }
 
 bool QmitkMultiLabelTreeModel::GetAllowVisibilityModification() const
 {
   return m_AllowVisibilityModification;
 }
 
 void QmitkMultiLabelTreeModel::SetAllowLockModification(bool lmod)
 {
   m_AllowLockModification = lmod;
 }
 
 bool QmitkMultiLabelTreeModel::GetAllowLockModification() const
 {
   return m_AllowLockModification;
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
index 6b4948cc16..6a259e5039 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
@@ -1,1474 +1,1472 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "QmitkSlicesInterpolator.h"
 #include "QmitkRenderWindow.h"
 #include "QmitkRenderWindowWidget.h"
 
 #include "mitkApplyDiffImageOperation.h"
 #include "mitkColorProperty.h"
 #include "mitkCoreObjectFactory.h"
 #include "mitkDiffImageApplier.h"
 #include "mitkInteractionConst.h"
 #include "mitkLevelWindowProperty.h"
 #include "mitkOperationEvent.h"
 #include "mitkProgressBar.h"
 #include "mitkProperties.h"
 #include "mitkRenderingManager.h"
 #include "mitkSegTool2D.h"
 #include "mitkSliceNavigationController.h"
 #include "mitkSurfaceToImageFilter.h"
 #include <mitkTimeNavigationController.h>
 #include "mitkToolManager.h"
 #include "mitkUndoController.h"
 
 #include <mitkExtractSliceFilter.h>
 #include <mitkPlanarCircle.h>
 #include <mitkImageReadAccessor.h>
 #include <mitkImageTimeSelector.h>
 #include <mitkImageWriteAccessor.h>
 #include <mitkPlaneProposer.h>
 #include <mitkUnstructuredGridClusteringFilter.h>
 #include <mitkVtkImageOverwrite.h>
 #include <mitkShapeBasedInterpolationAlgorithm.h>
 #include <itkCommand.h>
 
 #include <mitkImageToContourFilter.h>
 #include <mitkImagePixelReadAccessor.h>
 
 //  Includes for the merge operation
 #include "mitkImageToContourFilter.h"
 #include <mitkLabelSetImage.h>
 
 #include <QCheckBox>
 #include <QCursor>
 #include <QMenu>
 #include <QMessageBox>
 #include <QPushButton>
 #include <QVBoxLayout>
 
 #include <vtkDoubleArray.h>
 #include <vtkFieldData.h>
 #include <vtkPolyVertex.h>
 #include <vtkUnstructuredGrid.h>
 #include <vtkPolyData.h>
 
 #include <array>
 #include <atomic>
 #include <thread>
 #include <vector>
 
 namespace
 {
   template <typename T = mitk::BaseData>
   itk::SmartPointer<T> GetData(const mitk::DataNode* dataNode)
   {
     return nullptr != dataNode
       ? dynamic_cast<T*>(dataNode->GetData())
       : nullptr;
   }
 }
 
 float SURFACE_COLOR_RGB[3] = {0.49f, 1.0f, 0.16f};
 
 const QmitkSlicesInterpolator::ActionToSliceDimensionMapType QmitkSlicesInterpolator::CreateActionToSlicer(const QList<QmitkRenderWindow*>& windows)
 {
   std::map<QAction *, mitk::SliceNavigationController *> actionToSliceDimension;
   for (auto* window : windows)
   {
     std::string windowName;
     auto renderWindowWidget = dynamic_cast<QmitkRenderWindowWidget*>(window->parentWidget());
     if (renderWindowWidget)
     {
       windowName = renderWindowWidget->GetCornerAnnotationText();
     }
     else
     {
       windowName = window->GetRenderer()->GetName();
     }
     auto slicer = window->GetSliceNavigationController();
     actionToSliceDimension[new QAction(QString::fromStdString(windowName), nullptr)] = slicer;
   }
 
   return actionToSliceDimension;
 }
 
 mitk::Image::Pointer ExtractSliceFromImage(mitk::Image* image,
                                           const mitk::PlaneGeometry * contourPlane,
                                           unsigned int timeStep)
 {
   vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
   // set to false to extract a slice
   reslice->SetOverwriteMode(false);
   reslice->Modified();
 
   mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice);
   extractor->SetInput(image);
   extractor->SetTimeStep(timeStep);
   extractor->SetWorldGeometry(contourPlane);
   extractor->SetVtkOutputRequest(false);
   extractor->SetResliceTransformByGeometry(image->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
   extractor->Update();
   mitk::Image::Pointer slice = extractor->GetOutput();
   return slice;
 }
 
 QmitkSlicesInterpolator::QmitkSlicesInterpolator(QWidget *parent, const char * /*name*/)
   : QWidget(parent),
     m_Interpolator(mitk::SegmentationInterpolationController::New()),
     m_SurfaceInterpolator(mitk::SurfaceInterpolationController::GetInstance()),
     m_ToolManager(nullptr),
     m_Initialized(false),
     m_LastSNC(nullptr),
     m_LastSliceIndex(0),
     m_2DInterpolationEnabled(false),
     m_3DInterpolationEnabled(false),
     m_CurrentActiveLabelValue(0),
     m_FirstRun(true)
 {
   m_GroupBoxEnableExclusiveInterpolationMode = new QGroupBox("Interpolation", this);
 
   QVBoxLayout *vboxLayout = new QVBoxLayout(m_GroupBoxEnableExclusiveInterpolationMode);
 
   m_EdgeDetector = mitk::FeatureBasedEdgeDetectionFilter::New();
   m_PointScorer = mitk::PointCloudScoringFilter::New();
 
   m_CmbInterpolation = new QComboBox(m_GroupBoxEnableExclusiveInterpolationMode);
   m_CmbInterpolation->addItem("Disabled");
   m_CmbInterpolation->addItem("2-Dimensional");
   m_CmbInterpolation->addItem("3-Dimensional");
   vboxLayout->addWidget(m_CmbInterpolation);
 
   m_BtnApply2D = new QPushButton("Confirm for single slice", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApply2D);
 
   m_BtnApplyForAllSlices2D = new QPushButton("Confirm for all slices", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApplyForAllSlices2D);
 
   m_BtnApply3D = new QPushButton("Confirm", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnApply3D);
 
   m_BtnReinit3DInterpolation = new QPushButton("Reinit Interpolation", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_BtnReinit3DInterpolation);
 
   m_ChkShowPositionNodes = new QCheckBox("Show Position Nodes", m_GroupBoxEnableExclusiveInterpolationMode);
   vboxLayout->addWidget(m_ChkShowPositionNodes);
 
   this->HideAllInterpolationControls();
 
   connect(m_CmbInterpolation, SIGNAL(currentIndexChanged(int)), this, SLOT(OnInterpolationMethodChanged(int)));
   connect(m_BtnApply2D, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked()));
   connect(m_BtnApplyForAllSlices2D, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked()));
   connect(m_BtnApply3D, SIGNAL(clicked()), this, SLOT(OnAccept3DInterpolationClicked()));
 
 
   connect(m_BtnReinit3DInterpolation, SIGNAL(clicked()), this, SLOT(OnReinit3DInterpolation()));
   connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SLOT(OnShowMarkers(bool)));
   connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SIGNAL(SignalShowMarkerNodes(bool)));
 
   QHBoxLayout *layout = new QHBoxLayout(this);
   layout->addWidget(m_GroupBoxEnableExclusiveInterpolationMode);
   this->setLayout(layout);
 
   itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::Pointer command =
     itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
   command->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnInterpolationInfoChanged);
   InterpolationInfoChangedObserverTag = m_Interpolator->AddObserver(itk::ModifiedEvent(), command);
 
   itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::Pointer command2 =
     itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
   command2->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged);
   SurfaceInterpolationInfoChangedObserverTag = m_SurfaceInterpolator->AddObserver(itk::ModifiedEvent(), command2);
 
   auto command3 = itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
   command3->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnInterpolationAborted);
   InterpolationAbortedObserverTag = m_Interpolator->AddObserver(itk::AbortEvent(), command3);
 
   // feedback node and its visualization properties
   m_FeedbackNode = mitk::DataNode::New();
   mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(m_FeedbackNode);
 
   m_FeedbackNode->SetProperty("binary", mitk::BoolProperty::New(true));
   m_FeedbackNode->SetProperty("outline binary", mitk::BoolProperty::New(true));
   m_FeedbackNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 0.0));
   m_FeedbackNode->SetProperty("texture interpolation", mitk::BoolProperty::New(false));
   m_FeedbackNode->SetProperty("layer", mitk::IntProperty::New(20));
   m_FeedbackNode->SetProperty("levelwindow", mitk::LevelWindowProperty::New(mitk::LevelWindow(0, 1)));
   m_FeedbackNode->SetProperty("name", mitk::StringProperty::New("Interpolation feedback"));
   m_FeedbackNode->SetProperty("opacity", mitk::FloatProperty::New(0.8));
   m_FeedbackNode->SetProperty("helper object", mitk::BoolProperty::New(true));
 
   m_InterpolatedSurfaceNode = mitk::DataNode::New();
   m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
   m_InterpolatedSurfaceNode->SetProperty("name", mitk::StringProperty::New("Surface Interpolation feedback"));
   m_InterpolatedSurfaceNode->SetProperty("opacity", mitk::FloatProperty::New(0.5));
   m_InterpolatedSurfaceNode->SetProperty("line width", mitk::FloatProperty::New(4.0f));
   m_InterpolatedSurfaceNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
   m_InterpolatedSurfaceNode->SetProperty("helper object", mitk::BoolProperty::New(true));
   m_InterpolatedSurfaceNode->SetVisibility(false);
 
   QWidget::setContentsMargins(0, 0, 0, 0);
   if (QWidget::layout() != nullptr)
   {
     QWidget::layout()->setContentsMargins(0, 0, 0, 0);
   }
 
 
   // For running 3D Interpolation in background
   // create a QFuture and a QFutureWatcher
 
   connect(&m_Watcher, SIGNAL(started()), this, SLOT(StartUpdateInterpolationTimer()));
   connect(&m_Watcher, SIGNAL(finished()), this, SLOT(OnSurfaceInterpolationFinished()));
   connect(&m_Watcher, SIGNAL(finished()), this, SLOT(StopUpdateInterpolationTimer()));
   m_Timer = new QTimer(this);
   connect(m_Timer, SIGNAL(timeout()), this, SLOT(ChangeSurfaceColor()));
 }
 
 void QmitkSlicesInterpolator::SetDataStorage(mitk::DataStorage::Pointer storage)
 {
   if (m_DataStorage == storage)
   {
     return;
   }
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.RemoveListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
   }
 
   m_DataStorage = storage;
   m_SurfaceInterpolator->SetDataStorage(storage);
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.AddListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
   }
 }
 
 void QmitkSlicesInterpolator::SetActiveLabelValue(mitk::LabelSetImage::LabelValueType labelValue)
 {
   bool changedValue = labelValue != this->m_CurrentActiveLabelValue;
 
   this->m_CurrentActiveLabelValue = labelValue;
 
   if (changedValue) this->OnActiveLabelChanged(labelValue);
 };
 
 
 mitk::DataStorage *QmitkSlicesInterpolator::GetDataStorage()
 {
   if (m_DataStorage.IsNotNull())
   {
     return m_DataStorage;
   }
   else
   {
     return nullptr;
   }
 }
 
 void QmitkSlicesInterpolator::InitializeWindow(QmitkRenderWindow* window)
 {
   auto slicer = window->GetSliceNavigationController();
 
   if (slicer == nullptr)
   {
     MITK_WARN << "Tried setting up interpolation for a render window that does not have a slice navigation controller set";
     return;
   }
 
   // Has to be initialized
   m_LastSNC = slicer;
 
   itk::MemberCommand<QmitkSlicesInterpolator>::Pointer deleteCommand =
     itk::MemberCommand<QmitkSlicesInterpolator>::New();
   deleteCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted);
   m_ControllerToDeleteObserverTag[slicer] = slicer->AddObserver(itk::DeleteEvent(), deleteCommand);
 
   itk::MemberCommand<QmitkSlicesInterpolator>::Pointer sliceChangedCommand =
     itk::MemberCommand<QmitkSlicesInterpolator>::New();
   sliceChangedCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnSliceChanged);
   m_ControllerToSliceObserverTag[slicer] = slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), sliceChangedCommand);
 }
 
 void QmitkSlicesInterpolator::Initialize(mitk::ToolManager *toolManager,
                                          const QList<QmitkRenderWindow*>& windows)
 {
   Q_ASSERT(!windows.empty());
 
   if (m_Initialized)
   {
     // remove old observers
     this->Uninitialize();
   }
 
   m_ToolManager = toolManager;
 
   if (m_ToolManager)
   {
     // set enabled only if a segmentation is selected
     mitk::DataNode *node = m_ToolManager->GetWorkingData(0);
     QWidget::setEnabled(node != nullptr);
 
     // react whenever the set of selected segmentation changes
     m_ToolManager->WorkingDataChanged +=
       mitk::MessageDelegate<QmitkSlicesInterpolator>(this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified);
     m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkSlicesInterpolator>(
       this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified);
 
     auto* timeNavigationController = mitk::RenderingManager::GetInstance()->GetTimeNavigationController();
     itk::MemberCommand<QmitkSlicesInterpolator>::Pointer timeChangedCommand =
       itk::MemberCommand<QmitkSlicesInterpolator>::New();
     timeChangedCommand->SetCallbackFunction(this, &QmitkSlicesInterpolator::OnTimeChanged);
     m_ControllerToTimeObserverTag =
       timeNavigationController->AddObserver(mitk::TimeNavigationController::TimeEvent(0), timeChangedCommand);
 
     m_TimePoint = timeNavigationController->GetSelectedTimePoint();
 
     // connect to the slice navigation controller. after each change, call the interpolator
     for (auto* window : windows)
     {
       this->InitializeWindow(window);
     }
 
     m_ActionToSlicerMap = CreateActionToSlicer(windows);
   }
 
   m_Initialized = true;
 }
 
 void QmitkSlicesInterpolator::Uninitialize()
 {
   if (m_ToolManager.IsNotNull())
   {
     m_ToolManager->WorkingDataChanged -=
       mitk::MessageDelegate<QmitkSlicesInterpolator>(this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified);
     m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkSlicesInterpolator>(
       this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified);
   }
 
   auto* timeNavigationController = mitk::RenderingManager::GetInstance()->GetTimeNavigationController();
   timeNavigationController->RemoveObserver(m_ControllerToTimeObserverTag);
 
 for (auto* slicer : m_ControllerToSliceObserverTag.keys())
   {
     slicer->RemoveObserver(m_ControllerToDeleteObserverTag.take(slicer));
     slicer->RemoveObserver(m_ControllerToSliceObserverTag.take(slicer));
   }
 
   m_ActionToSlicerMap.clear();
   m_ToolManager = nullptr;
 
   m_Initialized = false;
 }
 
 QmitkSlicesInterpolator::~QmitkSlicesInterpolator()
 {
   if (m_Initialized)
   {
     // remove old observers
     this->Uninitialize();
   }
 
   WaitForFutures();
 
   if (m_DataStorage.IsNotNull())
   {
     m_DataStorage->RemoveNodeEvent.RemoveListener(
       mitk::MessageDelegate1<QmitkSlicesInterpolator, const mitk::DataNode*>(this, &QmitkSlicesInterpolator::NodeRemoved)
     );
 
     if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
       m_DataStorage->Remove(m_InterpolatedSurfaceNode);
   }
 
   // remove observer
   m_Interpolator->RemoveObserver(InterpolationAbortedObserverTag);
   m_Interpolator->RemoveObserver(InterpolationInfoChangedObserverTag);
   m_SurfaceInterpolator->RemoveObserver(SurfaceInterpolationInfoChangedObserverTag);
 
   m_SurfaceInterpolator->SetCurrentInterpolationSession(nullptr);
 
   delete m_Timer;
 }
 
 /**
 External enableization...
 */
 void QmitkSlicesInterpolator::setEnabled(bool enable)
 {
   QWidget::setEnabled(enable);
 
   // Set the gui elements of the different interpolation modi enabled
   if (enable)
   {
     if (m_2DInterpolationEnabled)
     {
       this->Show2DInterpolationControls(true);
       m_Interpolator->Activate2DInterpolation(true);
     }
     else if (m_3DInterpolationEnabled)
     {
       this->Show3DInterpolationControls(true);
       this->Show3DInterpolationResult(true);
     }
   }
   // Set all gui elements of the interpolation disabled
   else
   {
     this->HideAllInterpolationControls();
     this->Show3DInterpolationResult(false);
   }
 }
 
 void QmitkSlicesInterpolator::On2DInterpolationEnabled(bool status)
 {
   OnInterpolationActivated(status);
   m_Interpolator->Activate2DInterpolation(status);
 }
 
 void QmitkSlicesInterpolator::On3DInterpolationEnabled(bool status)
 {
   On3DInterpolationActivated(status);
 }
 
 void QmitkSlicesInterpolator::OnInterpolationDisabled(bool status)
 {
   if (status)
   {
     OnInterpolationActivated(!status);
     On3DInterpolationActivated(!status);
     this->Show3DInterpolationResult(false);
   }
 }
 
 void QmitkSlicesInterpolator::HideAllInterpolationControls()
 {
   this->Show2DInterpolationControls(false);
   this->Show3DInterpolationControls(false);
 }
 
 void QmitkSlicesInterpolator::Show2DInterpolationControls(bool show)
 {
   m_BtnApply2D->setVisible(show);
   m_BtnApplyForAllSlices2D->setVisible(show);
 }
 
 void QmitkSlicesInterpolator::Show3DInterpolationControls(bool show)
 {
   m_BtnApply3D->setVisible(show);
 
   m_ChkShowPositionNodes->setVisible(show);
   m_BtnReinit3DInterpolation->setVisible(show);
 }
 
 void QmitkSlicesInterpolator::OnInterpolationMethodChanged(int index)
 {
   switch (index)
   {
     case 0: // Disabled
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation");
       this->HideAllInterpolationControls();
       this->OnInterpolationActivated(false);
       this->On3DInterpolationActivated(false);
       this->Show3DInterpolationResult(false);
       m_Interpolator->Activate2DInterpolation(false);
       break;
 
     case 1: // 2D
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)");
       this->HideAllInterpolationControls();
       this->Show2DInterpolationControls(true);
       this->OnInterpolationActivated(true);
       this->On3DInterpolationActivated(false);
       this->Show3DInterpolationResult(false);
       m_Interpolator->Activate2DInterpolation(true);
       break;
 
     case 2: // 3D
       m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)");
       this->HideAllInterpolationControls();
       this->Show3DInterpolationControls(true);
       this->OnInterpolationActivated(false);
       this->On3DInterpolationActivated(true);
       m_Interpolator->Activate2DInterpolation(false);
       break;
 
     default:
       MITK_ERROR << "Unknown interpolation method!";
       m_CmbInterpolation->setCurrentIndex(0);
       break;
   }
 }
 
 void QmitkSlicesInterpolator::OnShowMarkers(bool state)
 {
   mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers =
     m_DataStorage->GetSubset(mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true)));
 
   for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End();
        ++it)
   {
     it->Value()->SetProperty("helper object", mitk::BoolProperty::New(!state));
   }
 }
 
 void QmitkSlicesInterpolator::OnToolManagerWorkingDataModified()
 {
   if (m_ToolManager->GetWorkingData(0) != nullptr)
   {
     m_Segmentation = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());
     m_BtnReinit3DInterpolation->setEnabled(true);
   }
   else
   {
     // If no workingdata is set, remove the interpolation feedback
     this->GetDataStorage()->Remove(m_FeedbackNode);
     m_FeedbackNode->SetData(nullptr);
     this->GetDataStorage()->Remove(m_InterpolatedSurfaceNode);
     m_InterpolatedSurfaceNode->SetData(nullptr);
     m_BtnReinit3DInterpolation->setEnabled(false);
     m_CmbInterpolation->setCurrentIndex(0);
     return;
   }
   // Updating the current selected segmentation for the 3D interpolation
   this->SetCurrentContourListID();
 
   if (m_2DInterpolationEnabled)
   {
     OnInterpolationActivated(true); // re-initialize if needed
   }
 }
 
 void QmitkSlicesInterpolator::OnToolManagerReferenceDataModified()
 {
 }
 
 void QmitkSlicesInterpolator::OnTimeChanged(itk::Object *sender, const itk::EventObject &e)
 {
   if (!dynamic_cast<const mitk::TimeNavigationController::TimeEvent*>(&e))
   {
     return;
   }
 
   const auto* timeNavigationController = dynamic_cast<mitk::TimeNavigationController*>(sender);
   if (nullptr == timeNavigationController)
   {
     return;
   }
 
   bool timeChanged = m_TimePoint != timeNavigationController->GetSelectedTimePoint();
   m_TimePoint = timeNavigationController->GetSelectedTimePoint();
 
   if (m_Watcher.isRunning())
     m_Watcher.waitForFinished();
 
   if (timeChanged)
   {
     if (m_3DInterpolationEnabled)
     {
       m_InterpolatedSurfaceNode->SetData(nullptr);
     }
     m_SurfaceInterpolator->Modified();
   }
 
   if (nullptr == m_LastSNC)
   {
     return;
   }
 
   if (TranslateAndInterpolateChangedSlice(m_LastSNC->GetCreatedWorldGeometry()))
   {
     m_LastSNC->GetRenderer()->RequestUpdate();
   }
 }
 
 void QmitkSlicesInterpolator::OnSliceChanged(itk::Object *sender, const itk::EventObject &e)
 {
   if (!dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent*>(&e))
   {
     return;
   }
 
   auto sliceNavigationController = dynamic_cast<mitk::SliceNavigationController*>(sender);
   if (nullptr == sliceNavigationController)
   {
     return;
   }
 
   if(m_2DInterpolationEnabled)
   {
     this->On2DInterpolationEnabled(m_2DInterpolationEnabled);
   }  
 
   if (TranslateAndInterpolateChangedSlice(e, sliceNavigationController))
   {
     sliceNavigationController->GetRenderer()->RequestUpdate();
   }
 }
 
 bool QmitkSlicesInterpolator::TranslateAndInterpolateChangedSlice(const itk::EventObject& e,
   mitk::SliceNavigationController* sliceNavigationController)
 {
   const mitk::SliceNavigationController::GeometrySliceEvent* event =
     dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent*>(&e);
 
   mitk::TimeGeometry* timeGeometry = event->GetTimeGeometry();
   m_LastSNC = sliceNavigationController;
 
   return this->TranslateAndInterpolateChangedSlice(timeGeometry);
 }
 
 bool QmitkSlicesInterpolator::TranslateAndInterpolateChangedSlice(const mitk::TimeGeometry* timeGeometry)
 {
   if (!m_2DInterpolationEnabled)
   {
     return false;
   }
 
   if (nullptr == timeGeometry)
   {
     return false;
   }
 
   if (!timeGeometry->IsValidTimePoint(m_TimePoint))
   {
     return false;
   }
 
   mitk::SlicedGeometry3D* slicedGeometry =
     dynamic_cast<mitk::SlicedGeometry3D*>(timeGeometry->GetGeometryForTimePoint(m_TimePoint).GetPointer());
   if (nullptr == slicedGeometry)
   {
     return false;
   }
 
   mitk::PlaneGeometry* plane = dynamic_cast<mitk::PlaneGeometry*>(slicedGeometry->GetPlaneGeometry(m_LastSNC->GetStepper()->GetPos()));
   if (nullptr == plane)
   {
     return false;
   }
 
   this->Interpolate(plane);
   return true;
 }
 
 void QmitkSlicesInterpolator::Interpolate(mitk::PlaneGeometry *plane)
 {
   if (nullptr == m_ToolManager)
   {
     return;
   }
 
   mitk::DataNode* node = m_ToolManager->GetWorkingData(0);
   if (nullptr == node)
   {
     return;
   }
 
   m_Segmentation = dynamic_cast<mitk::Image*>(node->GetData());
   if (nullptr == m_Segmentation)
   {
     return;
   }
 
   if (!m_Segmentation->GetTimeGeometry()->IsValidTimePoint(m_TimePoint))
   {
     MITK_WARN << "Cannot interpolate WorkingImage. Passed time point is not within the time bounds of WorkingImage. "
                  "Time point: "
               << m_TimePoint;
     return;
   }
 
   const auto timeStep = m_Segmentation->GetTimeGeometry()->TimePointToTimeStep(m_TimePoint);
 
   int clickedSliceDimension = -1;
   int clickedSliceIndex = -1;
 
   // calculate real slice position, i.e. slice of the image
   mitk::SegTool2D::DetermineAffectedImageSlice(m_Segmentation, plane, clickedSliceDimension, clickedSliceIndex);
 
   mitk::Image::Pointer interpolation =
     m_Interpolator->Interpolate(clickedSliceDimension, clickedSliceIndex, plane, timeStep);
   m_FeedbackNode->SetData(interpolation);
 
   //  maybe just have a variable that stores the active label color.
   if (m_ToolManager)
   {
     auto* workingNode = m_ToolManager->GetWorkingData(0);
     if (workingNode != nullptr)
     {
       auto* activeLabel = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData())->GetActiveLabel();
       if (nullptr != activeLabel)
       {
         auto activeColor = activeLabel->GetColor();
         m_FeedbackNode->SetProperty("color", mitk::ColorProperty::New(activeColor));
       }
     }
   }
 
   m_LastSliceIndex = clickedSliceIndex;
 }
 
 void QmitkSlicesInterpolator::OnSurfaceInterpolationFinished()
 {
   mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
 
   if (workingNode && workingNode->GetData())
   {
     const auto segmentation = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData());
 
     if (segmentation == nullptr)
     {
       MITK_ERROR << "Run3DInterpolation triggered with no MultiLabelSegmentation as working data.";
       return;
     }
     mitk::Surface::Pointer interpolatedSurface = m_SurfaceInterpolator->GetInterpolationResult(segmentation, m_CurrentActiveLabelValue, segmentation->GetTimeGeometry()->TimePointToTimeStep(m_TimePoint));
 
     if (interpolatedSurface.IsNotNull())
     {
       m_BtnApply3D->setEnabled(true);;
 
       m_InterpolatedSurfaceNode->SetData(interpolatedSurface);
       this->Show3DInterpolationResult(true);
 
       if (!m_DataStorage->Exists(m_InterpolatedSurfaceNode))
       {
         m_DataStorage->Add(m_InterpolatedSurfaceNode);
       }
     }
     else
     {
       m_BtnApply3D->setEnabled(false);
 
       if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
       {
         this->Show3DInterpolationResult(false);
       }
     }
   }
 
   m_BtnReinit3DInterpolation->setEnabled(true);
 
   for (auto* slicer : m_ControllerToSliceObserverTag.keys())
   {
     slicer->GetRenderer()->RequestUpdate();
   }
 }
 
 void QmitkSlicesInterpolator::OnAcceptInterpolationClicked()
 {
   auto* workingNode = m_ToolManager->GetWorkingData(0);
   auto* planeGeometry = m_LastSNC->GetCurrentPlaneGeometry();
   auto* interpolatedPreview = dynamic_cast<mitk::Image*>(m_FeedbackNode->GetData());
   if (nullptr == workingNode || nullptr == interpolatedPreview)
     return;
 
   auto* segmentationImage = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData());
   if (nullptr == segmentationImage)
     return;
 
   if (!segmentationImage->GetTimeGeometry()->IsValidTimePoint(m_TimePoint))
   {
     MITK_WARN << "Cannot accept interpolation. Time point selected by SliceNavigationController is not within the "
       "time bounds of segmentation. Time point: "
       << m_TimePoint;
     return;
   }
 
   const auto timeStep = segmentationImage->GetTimeGeometry()->TimePointToTimeStep(m_TimePoint);
 
   auto interpolatedSlice = mitk::SegTool2D::GetAffectedImageSliceAs2DImage(planeGeometry, segmentationImage, timeStep)->Clone();
   auto activeValue = segmentationImage->GetActiveLabel()->GetValue();
   mitk::TransferLabelContentAtTimeStep(
     interpolatedPreview,
     interpolatedSlice,
     segmentationImage->GetConstLabelsByValue(segmentationImage->GetLabelValuesByGroup(segmentationImage->GetActiveLayer())),
     timeStep,
     0,
     mitk::LabelSetImage::UNLABELED_VALUE,
     false,
     { {0, mitk::LabelSetImage::UNLABELED_VALUE}, {1, activeValue} }
   );
 
   mitk::SegTool2D::WriteBackSegmentationResult(workingNode, planeGeometry, interpolatedSlice, timeStep);
   m_FeedbackNode->SetData(nullptr);
 }
 
 void QmitkSlicesInterpolator::AcceptAllInterpolations(mitk::SliceNavigationController *slicer)
 {
   /*
    * What exactly is done here:
    * 1. We create an empty diff image for the current segmentation
    * 2. All interpolated slices are written into the diff image
    * 3. Then the diffimage is applied to the original segmentation
    */
   if (m_Segmentation)
   {
     mitk::Image::Pointer segmentation3D = m_Segmentation;
     unsigned int timeStep = 0;
 
     if (4 == m_Segmentation->GetDimension())
     {
       const auto* geometry = m_Segmentation->GetTimeGeometry();
 
       if (!geometry->IsValidTimePoint(m_TimePoint))
       {
         MITK_WARN << "Cannot accept all interpolations. Time point selected by passed SliceNavigationController is not "
                      "within the time bounds of segmentation. Time point: "
                   << m_TimePoint;
         return;
       }
 
       mitk::Image::Pointer activeLabelImage;
       try
       {
         auto labelSetImage = dynamic_cast<mitk::LabelSetImage *>(m_Segmentation);
         activeLabelImage = labelSetImage->CreateLabelMask(labelSetImage->GetActiveLabel()->GetValue());
       }
       catch (const std::exception& e)
       {
         MITK_ERROR << e.what() << " | NO LABELSETIMAGE IN WORKING NODE\n";
       }
 
       m_Interpolator->SetSegmentationVolume(activeLabelImage);
 
       timeStep = geometry->TimePointToTimeStep(m_TimePoint);
 
       auto timeSelector = mitk::ImageTimeSelector::New();
       timeSelector->SetInput(m_Segmentation);
       timeSelector->SetTimeNr(timeStep);
       timeSelector->Update();
 
       segmentation3D = timeSelector->GetOutput();
     }
 
     // Create an empty diff image for the undo operation
     auto diffImage = mitk::Image::New();
     diffImage->Initialize(segmentation3D);
 
     // Create scope for ImageWriteAccessor so that the accessor is destroyed right after use
     {
       mitk::ImageWriteAccessor accessor(diffImage);
 
       // Set all pixels to zero
       auto pixelType = mitk::MakeScalarPixelType<mitk::Tool::DefaultSegmentationDataType>();
 
       // For legacy purpose support former pixel type of segmentations (before multilabel)
       if (itk::IOComponentEnum::UCHAR == m_Segmentation->GetImageDescriptor()->GetChannelDescriptor().GetPixelType().GetComponentType())
         pixelType = mitk::MakeScalarPixelType<unsigned char>();
 
       memset(accessor.GetData(), 0, pixelType.GetSize() * diffImage->GetDimension(0) * diffImage->GetDimension(1) * diffImage->GetDimension(2));
     }
 
     // Since we need to shift the plane it must be clone so that the original plane isn't altered
     auto slicedGeometry = m_Segmentation->GetSlicedGeometry();
     auto planeGeometry = slicer->GetCurrentPlaneGeometry()->Clone();
     int sliceDimension = -1;
     int sliceIndex = -1;
 
     mitk::SegTool2D::DetermineAffectedImageSlice(m_Segmentation, planeGeometry, sliceDimension, sliceIndex);
 
     const auto numSlices = m_Segmentation->GetDimension(sliceDimension);
     mitk::ProgressBar::GetInstance()->AddStepsToDo(numSlices);
 
     std::atomic_uint totalChangedSlices;
 
     // Reuse interpolation algorithm instance for each slice to cache boundary calculations
     auto algorithm = mitk::ShapeBasedInterpolationAlgorithm::New();
 
     // Distribute slice interpolations to multiple threads
     const auto numThreads = std::min(std::thread::hardware_concurrency(), numSlices);
     std::vector<std::vector<unsigned int>> sliceIndices(numThreads);
 
     for (std::remove_const_t<decltype(numSlices)> sliceIndex = 0; sliceIndex < numSlices; ++sliceIndex)
       sliceIndices[sliceIndex % numThreads].push_back(sliceIndex);
 
     std::vector<std::thread> threads;
     threads.reserve(numThreads);
 
     // This lambda will be executed by the threads
     auto interpolate = [=, &interpolator = m_Interpolator, &totalChangedSlices](unsigned int threadIndex)
     {
       auto clonedPlaneGeometry = planeGeometry->Clone();
       auto origin = clonedPlaneGeometry->GetOrigin();
 
       //  Go through the sliced indices
       for (auto sliceIndex : sliceIndices[threadIndex])
       {
         slicedGeometry->WorldToIndex(origin, origin);
         origin[sliceDimension] = sliceIndex;
         slicedGeometry->IndexToWorld(origin, origin);
         clonedPlaneGeometry->SetOrigin(origin);
 
         auto interpolation = interpolator->Interpolate(sliceDimension, sliceIndex, clonedPlaneGeometry, timeStep, algorithm);
 
         if (interpolation.IsNotNull())
         {
           // Setting up the reslicing pipeline which allows us to write the interpolation results back into the image volume
           auto reslicer = vtkSmartPointer<mitkVtkImageOverwrite>::New();
 
           // Set overwrite mode to true to write back to the image volume
           reslicer->SetInputSlice(interpolation->GetSliceData()->GetVtkImageAccessor(interpolation)->GetVtkImageData());
           reslicer->SetOverwriteMode(true);
           reslicer->Modified();
 
           auto diffSliceWriter = mitk::ExtractSliceFilter::New(reslicer);
 
           diffSliceWriter->SetInput(diffImage);
           diffSliceWriter->SetTimeStep(0);
           diffSliceWriter->SetWorldGeometry(clonedPlaneGeometry);
           diffSliceWriter->SetVtkOutputRequest(true);
           diffSliceWriter->SetResliceTransformByGeometry(diffImage->GetTimeGeometry()->GetGeometryForTimeStep(0));
           diffSliceWriter->Modified();
           diffSliceWriter->Update();
 
           ++totalChangedSlices;
         }
 
         mitk::ProgressBar::GetInstance()->Progress();
       }
     };
     m_Interpolator->EnableSliceImageCache();
 
     //  Do the interpolation here.
     for (size_t threadIndex = 0; threadIndex < numThreads; ++threadIndex)
     {
       interpolate(threadIndex);
     }
 
     m_Interpolator->DisableSliceImageCache();
 
     const mitk::Label::PixelType newDestinationLabel = dynamic_cast<mitk::LabelSetImage *>(m_Segmentation)->GetActiveLabel()->GetValue();
 
     //  Do and Undo Operations
     if (totalChangedSlices > 0)
     {
       // Create do/undo operations
       auto* doOp = new mitk::ApplyDiffImageOperation(mitk::OpTEST, m_Segmentation, diffImage, timeStep);
 
       auto* undoOp = new mitk::ApplyDiffImageOperation(mitk::OpTEST, m_Segmentation, diffImage, timeStep);
       undoOp->SetFactor(-1.0);
 
       auto comment = "Confirm all interpolations (" + std::to_string(totalChangedSlices) + ")";
       auto* undoStackItem = new mitk::OperationEvent(mitk::DiffImageApplier::GetInstanceForUndo(), doOp, undoOp, comment);
 
       mitk::OperationEvent::IncCurrGroupEventId();
       mitk::OperationEvent::IncCurrObjectEventId();
       mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent(undoStackItem);
       mitk::DiffImageApplier::GetInstanceForUndo()->SetDestinationLabel(newDestinationLabel);
       // Apply the changes to the original image
       mitk::DiffImageApplier::GetInstanceForUndo()->ExecuteOperation(doOp);
     }
     m_FeedbackNode->SetData(nullptr);
   }
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::FinishInterpolation(mitk::SliceNavigationController *slicer)
 {
   // this redirect is for calling from outside
   if (slicer == nullptr)
     OnAcceptAllInterpolationsClicked();
   else
     AcceptAllInterpolations(slicer);
 }
 
 void QmitkSlicesInterpolator::OnAcceptAllInterpolationsClicked()
 {
   QMenu orientationPopup(this);
   for (auto it = m_ActionToSlicerMap.begin(); it != m_ActionToSlicerMap.end(); ++it)
   {
     orientationPopup.addAction(it->first);
   }
 
   connect(&orientationPopup, SIGNAL(triggered(QAction *)), this, SLOT(OnAcceptAllPopupActivated(QAction *)));
   orientationPopup.exec(QCursor::pos());
 }
 
 void QmitkSlicesInterpolator::OnAccept3DInterpolationClicked()
 {
   auto referenceImage = GetData<mitk::Image>(m_ToolManager->GetReferenceData(0));
 
   auto* segmentationDataNode = m_ToolManager->GetWorkingData(0);
 
   auto labelSetImage = dynamic_cast<mitk::LabelSetImage*>(segmentationDataNode->GetData());
   auto activeLabelColor = labelSetImage->GetActiveLabel()->GetColor();
   std::string activeLabelName = labelSetImage->GetActiveLabel()->GetName();
 
   auto segmentation = GetData<mitk::Image>(segmentationDataNode);
 
   if (referenceImage.IsNull() || segmentation.IsNull())
     return;
 
   const auto* segmentationGeometry = segmentation->GetTimeGeometry();
 
   if (!referenceImage->GetTimeGeometry()->IsValidTimePoint(m_TimePoint) ||
       !segmentationGeometry->IsValidTimePoint(m_TimePoint))
   {
     MITK_WARN << "Cannot accept interpolation. Current time point is not within the time bounds of the patient image and segmentation.";
     return;
   }
 
   auto interpolatedSurface = GetData<mitk::Surface>(m_InterpolatedSurfaceNode);
 
   if (interpolatedSurface.IsNull())
     return;
 
   auto surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
 
   surfaceToImageFilter->SetImage(referenceImage);
   surfaceToImageFilter->SetMakeOutputBinary(true);
   surfaceToImageFilter->SetUShortBinaryPixelType(itk::IOComponentEnum::USHORT == segmentation->GetPixelType().GetComponentType());
   surfaceToImageFilter->SetInput(interpolatedSurface);
   surfaceToImageFilter->Update();
 
   mitk::Image::Pointer interpolatedSegmentation = surfaceToImageFilter->GetOutput();
   auto timeStep = segmentationGeometry->TimePointToTimeStep(m_TimePoint);
   const mitk::Label::PixelType newDestinationLabel = labelSetImage->GetActiveLabel()->GetValue();
 
   TransferLabelContentAtTimeStep(
     interpolatedSegmentation,
     labelSetImage,
     labelSetImage->GetConstLabelsByValue(labelSetImage->GetLabelValuesByGroup(labelSetImage->GetActiveLayer())),
     timeStep,
     0,
     0,
     false,
     {{1, newDestinationLabel}},
     mitk::MultiLabelSegmentation::MergeStyle::Merge,
     mitk::MultiLabelSegmentation::OverwriteStyle::RegardLocks);
 
   this->Show3DInterpolationResult(false);
 
   std::string name = segmentationDataNode->GetName() + " 3D-interpolation - " + activeLabelName;
   mitk::TimeBounds timeBounds;
 
   if (1 < interpolatedSurface->GetTimeSteps())
   {
     name += "_t" + std::to_string(timeStep);
 
     auto* polyData = vtkPolyData::New();
     polyData->DeepCopy(interpolatedSurface->GetVtkPolyData(timeStep));
 
     auto surface = mitk::Surface::New();
     surface->SetVtkPolyData(polyData);
 
     interpolatedSurface = surface;
     timeBounds = segmentationGeometry->GetTimeBounds(timeStep);
   }
   else
   {
     timeBounds = segmentationGeometry->GetTimeBounds(0);
   }
 
   auto* surfaceGeometry = static_cast<mitk::ProportionalTimeGeometry*>(interpolatedSurface->GetTimeGeometry());
   surfaceGeometry->SetFirstTimePoint(timeBounds[0]);
   surfaceGeometry->SetStepDuration(timeBounds[1] - timeBounds[0]);
 
   // Typical file formats for surfaces do not save any time-related information. As a workaround at least for MITK scene files, we have the
   // possibility to seralize this information as properties.
 
   interpolatedSurface->SetProperty("ProportionalTimeGeometry.FirstTimePoint", mitk::FloatProperty::New(surfaceGeometry->GetFirstTimePoint()));
   interpolatedSurface->SetProperty("ProportionalTimeGeometry.StepDuration", mitk::FloatProperty::New(surfaceGeometry->GetStepDuration()));
 
   auto interpolatedSurfaceDataNode = mitk::DataNode::New();
 
   interpolatedSurfaceDataNode->SetData(interpolatedSurface);
   interpolatedSurfaceDataNode->SetName(name);
   interpolatedSurfaceDataNode->SetOpacity(0.7f);
 
   interpolatedSurfaceDataNode->SetColor(activeLabelColor);
   m_DataStorage->Add(interpolatedSurfaceDataNode, segmentationDataNode);
 }
 
 void QmitkSlicesInterpolator::OnReinit3DInterpolation()
 {
   //  Step 1. Load from the isContourPlaneGeometry nodes the contourNodes.
   mitk::NodePredicateProperty::Pointer pred =
     mitk::NodePredicateProperty::New("isContourPlaneGeometry", mitk::BoolProperty::New(true));
   mitk::DataStorage::SetOfObjects::ConstPointer contourNodes =
     m_DataStorage->GetDerivations(m_ToolManager->GetWorkingData(0), pred);
 
   if (contourNodes->Size() != 0)
   {
     if (m_ToolManager->GetWorkingData(0) != nullptr)
     {
       try
       {
         auto labelSetImage = dynamic_cast<mitk::LabelSetImage *>(m_ToolManager->GetWorkingData(0)->GetData());
         if (!labelSetImage->GetTimeGeometry()->IsValidTimePoint(m_TimePoint))
         {
           MITK_ERROR << "Invalid time point requested for interpolation pipeline.";
           return;
         }
 
         mitk::SurfaceInterpolationController::CPIVector newCPIs;
         //  Adding label and timeStep information for the contourNodes.
         for (auto it = contourNodes->Begin(); it != contourNodes->End(); ++it)
         {
           auto contourNode = it->Value();
           auto labelID = dynamic_cast<mitk::UShortProperty *>(contourNode->GetProperty("labelID"))->GetValue();
           auto timeStep = dynamic_cast<mitk::IntProperty *>(contourNode->GetProperty("timeStep"))->GetValue();
 
           auto planeGeometry = dynamic_cast<mitk::PlanarFigure *>(contourNode->GetData())->GetPlaneGeometry();
           auto groupID = labelSetImage->GetGroupIndexOfLabel(labelID);
           auto sliceImage = ExtractSliceFromImage(labelSetImage->GetGroupImage(groupID), planeGeometry, timeStep);
           mitk::ImageToContourFilter::Pointer contourExtractor = mitk::ImageToContourFilter::New();
           contourExtractor->SetInput(sliceImage);
           contourExtractor->SetContourValue(labelID);
           contourExtractor->Update();
           mitk::Surface::Pointer contour = contourExtractor->GetOutput();
 
           if (contour->GetVtkPolyData()->GetNumberOfPoints() == 0)
             continue;
 
           contour->DisconnectPipeline();
           newCPIs.emplace_back(contour, planeGeometry->Clone(),labelID,timeStep);
         }
         m_SurfaceInterpolator->CompleteReinitialization(newCPIs);
       }
       catch(const std::exception& e)
       {
         MITK_ERROR << "Exception thrown casting toolmanager working data to labelsetImage";
       }
     }
   }
   else
   {
     m_BtnApply3D->setEnabled(false);
     QMessageBox errorInfo;
     errorInfo.setWindowTitle("Reinitialize surface interpolation");
     errorInfo.setIcon(QMessageBox::Information);
     errorInfo.setText("No contours available for the selected segmentation!");
     errorInfo.exec();
   }
 }
 
 void QmitkSlicesInterpolator::OnAcceptAllPopupActivated(QAction *action)
 {
   try
   {
     auto iter = m_ActionToSlicerMap.find(action);
     if (iter != m_ActionToSlicerMap.end())
     {
       mitk::SliceNavigationController *slicer = iter->second;
       this->AcceptAllInterpolations(slicer);
     }
   }
   catch (...)
   {
     /* Showing message box with possible memory error */
     QMessageBox errorInfo;
     errorInfo.setWindowTitle("Interpolation Process");
     errorInfo.setIcon(QMessageBox::Critical);
     errorInfo.setText("An error occurred during interpolation. Possible cause: Not enough memory!");
     errorInfo.exec();
 
     std::cerr << "Ill construction in " __FILE__ " l. " << __LINE__ << std::endl;
   }
 }
 
 void QmitkSlicesInterpolator::OnInterpolationActivated(bool on)
 {
   m_2DInterpolationEnabled = on;
 
   try
   {
     if (m_DataStorage.IsNotNull())
     {
       if (on && !m_DataStorage->Exists(m_FeedbackNode))
       {
         m_DataStorage->Add(m_FeedbackNode);
       }
     }
   }
   catch (...)
   {
     // don't care (double add/remove)
   }
 
   if (m_ToolManager)
   {
     mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
     mitk::DataNode *referenceNode = m_ToolManager->GetReferenceData(0);
     QWidget::setEnabled(workingNode != nullptr);
 
     m_BtnApply2D->setEnabled(on);
     m_FeedbackNode->SetVisibility(on);
 
     if (!on)
     {
       mitk::RenderingManager::GetInstance()->RequestUpdateAll();
       return;
     }
 
     if (workingNode)
     {
       auto labelSetImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
       if (nullptr == labelSetImage)
       {
         MITK_ERROR << "NO LABELSETIMAGE IN WORKING NODE\n";
         mitk::RenderingManager::GetInstance()->RequestUpdateAll();
         return;
       }
 
       const auto* activeLabel = labelSetImage->GetActiveLabel();
       const auto* segmentation = dynamic_cast<mitk::Image*>(workingNode->GetData());
       if (nullptr != activeLabel && nullptr != segmentation)
       {
         auto activeLabelImage = labelSetImage->CreateLabelMask(activeLabel->GetValue());
         m_Interpolator->SetSegmentationVolume(activeLabelImage);
 
         if (referenceNode)
         {
           mitk::Image *referenceImage = dynamic_cast<mitk::Image *>(referenceNode->GetData());
           m_Interpolator->SetReferenceVolume(referenceImage); // may be nullptr
         }
       }
     }
   }
   this->UpdateVisibleSuggestion();
 }
 
 void QmitkSlicesInterpolator::Run3DInterpolation()
 {
   auto workingNode = m_ToolManager->GetWorkingData(0);
 
   if (workingNode == nullptr)
   {
     MITK_ERROR << "Run3DInterpolation triggered with no working data set.";
     return;
   }
 
   const auto segmentation = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData());
 
   if (segmentation == nullptr)
   {
     MITK_ERROR << "Run3DInterpolation triggered with no MultiLabelSegmentation as working data.";
     return;
   }
 
   m_SurfaceInterpolator->Interpolate(segmentation,m_CurrentActiveLabelValue,segmentation->GetTimeGeometry()->TimePointToTimeStep(m_TimePoint));
 }
 
 void QmitkSlicesInterpolator::StartUpdateInterpolationTimer()
 {
   m_Timer->start(500);
 }
 
 void QmitkSlicesInterpolator::StopUpdateInterpolationTimer()
 {
   if(m_ToolManager)
   {
     const auto* workingNode = m_ToolManager->GetWorkingData(0);
     const auto activeColor = dynamic_cast<mitk::LabelSetImage*>(workingNode->GetData())->GetActiveLabel()->GetColor();
     m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(activeColor));
   }
 
   m_Timer->stop();
 }
 
 void QmitkSlicesInterpolator::ChangeSurfaceColor()
 {
   float currentColor[3];
   m_InterpolatedSurfaceNode->GetColor(currentColor);
 
     m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
   m_InterpolatedSurfaceNode->Update();
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS);
 }
 
 void QmitkSlicesInterpolator::On3DInterpolationActivated(bool on)
 {
   m_3DInterpolationEnabled = on;
   try
   {
     // this->PrepareInputsFor3DInterpolation();
     m_SurfaceInterpolator->Modified();
   }
   catch (...)
   {
     MITK_ERROR << "Error with 3D surface interpolation!";
   }
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::EnableInterpolation(bool on)
 {
   // only to be called from the outside world
   // just a redirection to OnInterpolationActivated
   OnInterpolationActivated(on);
 }
 
 void QmitkSlicesInterpolator::Enable3DInterpolation(bool on)
 {
   // only to be called from the outside world
   // just a redirection to OnInterpolationActivated
   this->On3DInterpolationActivated(on);
 }
 
 void QmitkSlicesInterpolator::UpdateVisibleSuggestion()
 {
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::OnInterpolationInfoChanged(const itk::EventObject & /*e*/)
 {
   // something (e.g. undo) changed the interpolation info, we should refresh our display
   this->UpdateVisibleSuggestion();
 }
 
 void QmitkSlicesInterpolator::OnInterpolationAborted(const itk::EventObject& /*e*/)
 {
   m_CmbInterpolation->setCurrentIndex(0);
   m_FeedbackNode->SetData(nullptr);
 }
 
 void QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged(const itk::EventObject & /*e*/)
 {
   if (m_Watcher.isRunning())
     m_Watcher.waitForFinished();
 
   if (m_3DInterpolationEnabled)
   {
 
     m_InterpolatedSurfaceNode->SetData(nullptr);
     m_Future = QtConcurrent::run(&QmitkSlicesInterpolator::Run3DInterpolation, this);
     m_Watcher.setFuture(m_Future);
   }
 }
 
 void QmitkSlicesInterpolator::SetCurrentContourListID()
 {
   // New ContourList = hide current interpolation
   Show3DInterpolationResult(false);
 
   if (m_DataStorage.IsNotNull() && m_ToolManager && m_LastSNC)
   {
     mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
 
     if (workingNode)
     {
       QWidget::setEnabled(true);
 
-      // In case the time is not valid use 0 to access the time geometry of the working node
-      unsigned int time_position = 0;
       if (!workingNode->GetData()->GetTimeGeometry()->IsValidTimePoint(m_TimePoint))
       {
         MITK_WARN << "Cannot accept interpolation. Time point selected by SliceNavigationController is not within the time bounds of WorkingImage. Time point: " << m_TimePoint;
         return;
       }
 
       m_SurfaceInterpolator->SetDistanceImageVolume(50000);
 
       auto segmentationImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
       m_SurfaceInterpolator->SetCurrentInterpolationSession(segmentationImage);
     }
     else
     {
       QWidget::setEnabled(false);
     }
   }
 }
 
 void QmitkSlicesInterpolator::Show3DInterpolationResult(bool status)
 {
   if (m_InterpolatedSurfaceNode.IsNotNull())
     m_InterpolatedSurfaceNode->SetVisibility(status);
 
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkSlicesInterpolator::OnActiveLabelChanged(mitk::Label::PixelType)
 {
   m_FeedbackNode->SetData(nullptr);
   m_InterpolatedSurfaceNode->SetData(nullptr);
 
   if (m_Watcher.isRunning())
     m_Watcher.waitForFinished();
 
   if (m_3DInterpolationEnabled)
   {
     m_SurfaceInterpolator->Modified();
   }
 
   if (m_2DInterpolationEnabled)
   {
     m_FeedbackNode->SetData(nullptr);
     this->OnInterpolationActivated(true);
 
     m_LastSNC->SendSlice();
   }
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   this->UpdateVisibleSuggestion();
 }
 
 void QmitkSlicesInterpolator::CheckSupportedImageDimension()
 {
   if (m_ToolManager->GetWorkingData(0))
   {
     m_Segmentation = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());
 
     if (m_3DInterpolationEnabled && m_Segmentation && ((m_Segmentation->GetDimension() != 3) || (m_Segmentation->GetDimension() != 4)) )
     {
       QMessageBox info;
       info.setWindowTitle("3D Interpolation Process");
       info.setIcon(QMessageBox::Information);
       info.setText("3D Interpolation is only supported for 3D/4D images at the moment!");
       info.exec();
       m_CmbInterpolation->setCurrentIndex(0);
     }
   }
 }
 
 void QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted(const itk::Object *sender,
                                                                  const itk::EventObject & /*e*/)
 {
   // Don't know how to avoid const_cast here?!
   mitk::SliceNavigationController *slicer =
     dynamic_cast<mitk::SliceNavigationController *>(const_cast<itk::Object *>(sender));
   if (slicer)
   {
     m_ControllerToSliceObserverTag.remove(slicer);
     m_ControllerToDeleteObserverTag.remove(slicer);
   }
 }
 
 void QmitkSlicesInterpolator::WaitForFutures()
 {
   if (m_Watcher.isRunning())
   {
     m_Watcher.waitForFinished();
   }
 
   if (m_PlaneWatcher.isRunning())
   {
     m_PlaneWatcher.waitForFinished();
   }
 }
 
 void QmitkSlicesInterpolator::NodeRemoved(const mitk::DataNode* node)
 {
   if ((m_ToolManager && m_ToolManager->GetWorkingData(0) == node) ||
       node == m_FeedbackNode ||
       node == m_InterpolatedSurfaceNode)
   {
     WaitForFutures();
   }
 }
diff --git a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
index 9e534ddc76..d1f68616ec 100644
--- a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
+++ b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
@@ -1,876 +1,876 @@
 /*============================================================================
 
 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 <mitkSurfaceInterpolationController.h>
 
 #include <shared_mutex>
 
 #include <mitkCreateDistanceImageFromSurfaceFilter.h>
 #include <mitkComputeContourSetNormalsFilter.h>
 #include <mitkImageAccessByItk.h>
 #include <mitkImageTimeSelector.h>
 #include <mitkImageToSurfaceFilter.h>
 #include <mitkNodePredicateDataUID.h>
 #include <mitkNodePredicateProperty.h>
 #include <mitkNodePredicateAnd.h>
 #include <mitkPlanarCircle.h>
 #include <mitkPlaneGeometry.h>
 #include <mitkReduceContourSetFilter.h>
 
 struct CPICache
 {
   mitk::SurfaceInterpolationController::CPIVector cpis;
   itk::TimeStamp cpiTimeStamp;
   mitk::Surface::Pointer cachedSurface;
 };
 
 typedef std::map<mitk::TimeStepType, CPICache> CPITimeStepMap;
 typedef std::map<mitk::LabelSetImage::LabelValueType, CPITimeStepMap> CPITimeStepLabelMap;
 
 typedef std::map<const mitk::LabelSetImage*, CPITimeStepLabelMap> CPITimeStepLabelSegMap;
 
 CPITimeStepLabelSegMap cpiMap;
 std::shared_mutex cpiMutex;
 
 std::map<mitk::LabelSetImage*, unsigned long> segmentationObserverTags;
 std::map<mitk::LabelSetImage*, unsigned long> labelRemovedObserverTags;
 
 mitk::SurfaceInterpolationController::SurfaceInterpolationController()
   : m_DistanceImageVolume(50000),
     m_SelectedSegmentation(nullptr)
 {
 }
 
 mitk::SurfaceInterpolationController::~SurfaceInterpolationController()
 {
   this->RemoveObservers();
 }
 
 void mitk::SurfaceInterpolationController::RemoveObservers()
 {
   // Removing all observers
   while (segmentationObserverTags.size())
   {
     this->RemoveObserversInternal(segmentationObserverTags.begin()->first);
   }
 }
 
 mitk::SurfaceInterpolationController *mitk::SurfaceInterpolationController::GetInstance()
 {
   static mitk::SurfaceInterpolationController::Pointer m_Instance;
 
   if (m_Instance.IsNull())
   {
     m_Instance = SurfaceInterpolationController::New();
   }
   return m_Instance;
 }
 
 void mitk::SurfaceInterpolationController::AddNewContours(const std::vector<ContourPositionInformation>& newCPIs,
   bool reinitializationAction, bool silent)
 {
   auto selectedSegmentation = m_SelectedSegmentation.Lock();
   if (selectedSegmentation.IsNull()) return;
 
   for (auto cpi : newCPIs)
   {
     if (cpi.Contour->GetVtkPolyData()->GetNumberOfPoints() > 0)
     {
       this->AddToCPIMap(cpi, reinitializationAction);
     }
   }
   if (!silent) this->Modified();
 }
 
 
 mitk::DataNode* GetSegmentationImageNodeInternal(mitk::DataStorage* ds, const mitk::LabelSetImage* seg)
 {
   if (nullptr == ds) return nullptr;
   if (nullptr == seg) return nullptr;
 
   mitk::DataNode* segmentationNode = nullptr;
   mitk::NodePredicateDataUID::Pointer dataUIDPredicate = mitk::NodePredicateDataUID::New(seg->GetUID());
   auto dataNodeObjects = ds->GetSubset(dataUIDPredicate);
 
   if (dataNodeObjects->Size() != 0)
   {
     for (auto it = dataNodeObjects->Begin(); it != dataNodeObjects->End(); ++it)
     {
       segmentationNode = it->Value();
     }
   }
   else
   {
     MITK_ERROR << "Unable to find the labelSetImage with the desired UID.";
   }
   return segmentationNode;
 }
 
 mitk::DataNode* mitk::SurfaceInterpolationController::GetSegmentationImageNode() const
 {
   if (m_DataStorage.IsNull()) return nullptr;
   auto selectedSegmentation = m_SelectedSegmentation.Lock();
   if (selectedSegmentation.IsNull()) return nullptr;
   return GetSegmentationImageNodeInternal(this->m_DataStorage, selectedSegmentation);
 }
 
 mitk::DataStorage::SetOfObjects::ConstPointer mitk::SurfaceInterpolationController::GetPlaneGeometryNodeFromDataStorage(const DataNode* segNode, LabelSetImage::LabelValueType labelValue, TimeStepType timeStep) const
 {
   DataStorage::SetOfObjects::Pointer relevantNodes = DataStorage::SetOfObjects::New();
 
   if (m_DataStorage.IsNotNull())
   {
     //remove relevant plane nodes
     auto nodes = this->GetPlaneGeometryNodeFromDataStorage(segNode, labelValue);
 
     for (auto it = nodes->Begin(); it != nodes->End(); ++it)
     {
-      auto aTS = dynamic_cast<mitk::IntProperty*>(it->Value()->GetProperty("timeStep"))->GetValue();
+      auto aTS = static_cast<TimeStepType>(dynamic_cast<mitk::IntProperty*>(it->Value()->GetProperty("timeStep"))->GetValue());
       bool sameTS = (timeStep == aTS);
 
       if (sameTS)
       {
         relevantNodes->push_back(it->Value());
       }
     }
   }
   return relevantNodes;
 }
 
 mitk::DataStorage::SetOfObjects::ConstPointer mitk::SurfaceInterpolationController::GetPlaneGeometryNodeFromDataStorage(const DataNode* segNode, LabelSetImage::LabelValueType labelValue) const
 {
   auto isContourPlaneGeometry = NodePredicateProperty::New("isContourPlaneGeometry", mitk::BoolProperty::New(true));
   auto isCorrectLabel = NodePredicateProperty::New("labelID", mitk::UShortProperty::New(labelValue));
   auto searchPredicate = NodePredicateAnd::New(isContourPlaneGeometry, isCorrectLabel);
 
   mitk::DataStorage::SetOfObjects::ConstPointer result;
   if (m_DataStorage.IsNotNull()) result = m_DataStorage->GetDerivations(segNode, searchPredicate);
   return result;
 }
 
 mitk::DataStorage::SetOfObjects::ConstPointer mitk::SurfaceInterpolationController::GetPlaneGeometryNodeFromDataStorage(const DataNode* segNode) const
 {
   auto isContourPlaneGeometry = NodePredicateProperty::New("isContourPlaneGeometry", mitk::BoolProperty::New(true));
 
   mitk::DataStorage::SetOfObjects::ConstPointer result;
   if (m_DataStorage.IsNotNull()) result = m_DataStorage->GetDerivations(segNode, isContourPlaneGeometry);
   return result;
 }
 void mitk::SurfaceInterpolationController::AddPlaneGeometryNodeToDataStorage(const ContourPositionInformation& contourInfo) const
 {
   auto selectedSegmentation = m_SelectedSegmentation.Lock();
   if (selectedSegmentation.IsNull())
   {
     mitkThrow()<< "Cannot add plane geometries. No valid segmentation selected.";
   }
 
   if (!selectedSegmentation->GetTimeGeometry()->IsValidTimeStep(contourInfo.TimeStep))
   {
     MITK_ERROR << "Invalid time point requested in AddPlaneGeometryNodeToDataStorage.";
     return;
   }
 
   if (m_DataStorage.IsNull())
   {
     MITK_DEBUG << "Cannot add plane geometry nodes. No data storage is set.";
     return;
   }
 
   auto planeGeometry = contourInfo.Plane;
   if (planeGeometry)
   {
     auto segmentationNode = this->GetSegmentationImageNode();
     mitk::DataStorage::SetOfObjects::ConstPointer contourNodes = this->GetPlaneGeometryNodeFromDataStorage(segmentationNode, contourInfo.LabelValue, contourInfo.TimeStep);
 
     mitk::DataNode::Pointer contourPlaneGeometryDataNode;
 
     //  Go through the pre-existing contours and check if the contour position matches them.
     for (auto it = contourNodes->Begin(); it != contourNodes->End(); ++it)
     {
       auto planeData = dynamic_cast<mitk::PlanarFigure*>(it->Value()->GetData());
       if (nullptr == planeData) mitkThrow() << "Invalid ContourPlaneGeometry data node. Does not contion a planar figure as data.";
 
       bool samePlane = contourInfo.Plane->IsOnPlane(planeData->GetPlaneGeometry());
 
       if (samePlane)
       {
         contourPlaneGeometryDataNode = it->Value();
         break;
       }
     }
 
     //  Go through the contourPlaneGeometry Data and add the segmentationNode to it.
     if (contourPlaneGeometryDataNode.IsNull())
     {
       auto planeGeometryData = mitk::PlanarCircle::New();
       planeGeometryData->SetPlaneGeometry(planeGeometry->Clone());
       mitk::Point2D p1;
       planeGeometry->Map(planeGeometry->GetCenter(), p1);
       planeGeometryData->PlaceFigure(p1);
       planeGeometryData->SetCurrentControlPoint(p1);
       planeGeometryData->SetProperty("initiallyplaced", mitk::BoolProperty::New(true));
 
       std::string contourName = "contourPlane L " + std::to_string(contourInfo.LabelValue) + " T " + std::to_string(contourInfo.TimeStep);
 
       contourPlaneGeometryDataNode = mitk::DataNode::New();
       contourPlaneGeometryDataNode->SetData(planeGeometryData);
 
       //  No need to change properties
       contourPlaneGeometryDataNode->SetProperty("helper object", mitk::BoolProperty::New(false));
       contourPlaneGeometryDataNode->SetProperty("hidden object", mitk::BoolProperty::New(true));
       contourPlaneGeometryDataNode->SetProperty("isContourPlaneGeometry", mitk::BoolProperty::New(true));
       contourPlaneGeometryDataNode->SetVisibility(false);
 
       //  Need to change properties
       contourPlaneGeometryDataNode->SetProperty("name", mitk::StringProperty::New(contourName) );
       contourPlaneGeometryDataNode->SetProperty("labelID", mitk::UShortProperty::New(contourInfo.LabelValue));
       contourPlaneGeometryDataNode->SetProperty("timeStep", mitk::IntProperty::New(contourInfo.TimeStep));
 
       contourPlaneGeometryDataNode->SetData(planeGeometryData);
 
       m_DataStorage->Add(contourPlaneGeometryDataNode, segmentationNode);
     }
   }
 }
 
 void mitk::SurfaceInterpolationController::AddToCPIMap(ContourPositionInformation& contourInfo, bool reinitializationAction)
 {
   auto selectedSegmentation = m_SelectedSegmentation.Lock();
   if (selectedSegmentation.IsNull())
     return;
 
   if (!selectedSegmentation->GetTimeGeometry()->IsValidTimeStep(contourInfo.TimeStep))
   {
     MITK_ERROR << "Invalid time step requested for interpolation pipeline.";
     return;
   }
 
   if (contourInfo.Plane == nullptr)
   {
     MITK_ERROR << "contourInfo plane is null.";
     return;
   }
 
   if (contourInfo.Contour->GetVtkPolyData()->GetNumberOfPoints() == 0)
   {
     this->RemoveContour(contourInfo);
     MITK_DEBUG << "contourInfo contour is empty.";
     return;
   }
 
   {
     std::lock_guard<std::shared_mutex> guard(cpiMutex);
     const auto& currentTimeStep = contourInfo.TimeStep;
     const auto& currentLabelValue = contourInfo.LabelValue;
 
     auto& currentImageContours = cpiMap[selectedSegmentation];
     auto& currentLabelContours = currentImageContours[currentLabelValue];
     auto& currentCPICache = currentLabelContours[currentTimeStep];
     auto& currentContourList = currentCPICache.cpis;
 
     auto finding = std::find_if(currentContourList.begin(), currentContourList.end(), [contourInfo](const ContourPositionInformation& element) {return contourInfo.Plane->IsOnPlane(element.Plane); });
 
     if (finding != currentContourList.end())
     {
       MITK_DEBUG << "CPI already exists. CPI is updated. Label: "<< currentLabelValue << "; Time Step: " << currentTimeStep;
       *finding = contourInfo;
     }
     else
     {
       currentContourList.push_back(contourInfo);
     }
     currentCPICache.cpiTimeStamp.Modified();
   }
 
   if (!reinitializationAction)
   {
     this->AddPlaneGeometryNodeToDataStorage(contourInfo);
   }
 }
 
 bool mitk::SurfaceInterpolationController::RemoveContour(ContourPositionInformation contourInfo, bool keepPlaceholderForUndo)
 {
   auto selectedSegmentation = m_SelectedSegmentation.Lock();
   if (selectedSegmentation.IsNull())
   {
     return false;
   }
 
   if (!selectedSegmentation->GetTimeGeometry()->IsValidTimeStep(contourInfo.TimeStep))
   {
     return false;
   }
 
   bool removedIt = false;
 
   {
     std::lock_guard<std::shared_mutex> cpiGuard(cpiMutex);
 
     const auto currentTimeStep = contourInfo.TimeStep;
     const auto currentLabel = contourInfo.LabelValue;
     auto& cpiCache = cpiMap.at(selectedSegmentation).at(currentLabel).at(currentTimeStep);
     auto it = cpiCache.cpis.begin();
 
 
     while (it != cpiCache.cpis.end())
     {
       const ContourPositionInformation& currentContour = (*it);
       if (currentContour.Plane->IsOnPlane(contourInfo.Plane))
       {
         if (keepPlaceholderForUndo)
         {
           it->Contour = nullptr;
         }
         else
         {
           cpiCache.cpis.erase(it);
         }
         cpiCache.cpiTimeStamp.Modified();
         removedIt = true;
 
         if (m_DataStorage.IsNotNull())
         {
           mitk::DataNode::Pointer contourPlaneGeometryDataNode;
 
           auto contourNodes = this->GetPlaneGeometryNodeFromDataStorage(GetSegmentationImageNodeInternal(m_DataStorage, selectedSegmentation), currentLabel, currentTimeStep);
 
           //  Go through the nodes and check if the contour position matches them.
           for (auto it = contourNodes->Begin(); it != contourNodes->End(); ++it)
           {
             auto planeData = dynamic_cast<mitk::PlanarFigure*>(it->Value()->GetData());
             if (nullptr == planeData) mitkThrow() << "Invalid ContourPlaneGeometry data node. Does not contion a planar figure as data.";
 
             bool samePlane = contourInfo.Plane->IsOnPlane(planeData->GetPlaneGeometry());
 
             if (samePlane)
             {
               m_DataStorage->Remove(it->Value());
               break;
             }
           }
         }
         break;
       }
       ++it;
     }
   }
 
   return removedIt;
 }
 
 void mitk::SurfaceInterpolationController::AddActiveLabelContoursForInterpolation(ReduceContourSetFilter* reduceFilter, const LabelSetImage* segmentationImage, LabelSetImage::LabelValueType labelValue, TimeStepType timeStep)
 {
   const auto& currentImageContours = cpiMap.at(segmentationImage);
 
   auto finding = currentImageContours.find(labelValue);
   if (finding == currentImageContours.end())
   {
     MITK_INFO << "Contours for label don't exist. Label value: " << labelValue;
     return;
   }
 
   const auto& currentLabelContoursMap = finding->second;
 
   auto tsfinding = currentLabelContoursMap.find(timeStep);
   if (tsfinding == currentLabelContoursMap.end())
   {
     MITK_INFO << "Contours for current time step don't exist.";
     return;
   }
 
   const auto& currentContours = tsfinding->second.cpis;
 
   unsigned int index = 0;
   for (const auto&  cpi : currentContours)
   {
     if (!cpi.IsPlaceHolder())
     {
       reduceFilter->SetInput(index, cpi.Contour);
       ++index;
     }
   }
 }
 
 bool CPICacheIsOutdated(const mitk::LabelSetImage* segmentationImage, mitk::LabelSetImage::LabelValueType labelValue, mitk::TimeStepType timeStep)
 {
   const auto& currentImageContours = cpiMap.at(segmentationImage);
 
   auto finding = currentImageContours.find(labelValue);
   if (finding == currentImageContours.end())
   {
     return false;
   }
 
   const auto& currentLabelContoursMap = finding->second;
 
   auto tsfinding = currentLabelContoursMap.find(timeStep);
   if (tsfinding == currentLabelContoursMap.end())
   {
     return false;
   }
 
   bool result = tsfinding->second.cachedSurface.IsNull() || tsfinding->second.cachedSurface->GetMTime() < tsfinding->second.cpiTimeStamp.GetMTime();
   return result;
 }
 
 void SetCPICacheSurface(mitk::Surface* surface, const mitk::LabelSetImage* segmentationImage, mitk::LabelSetImage::LabelValueType labelValue, mitk::TimeStepType timeStep)
 {
   const auto& currentImageContours = cpiMap.at(segmentationImage);
 
   auto finding = currentImageContours.find(labelValue);
   if (finding == currentImageContours.end())
   {
     return;
   }
 
   const auto& currentLabelContoursMap = finding->second;
 
   auto tsfinding = currentLabelContoursMap.find(timeStep);
   if (tsfinding == currentLabelContoursMap.end())
   {
     return;
   }
 
   cpiMap[segmentationImage][labelValue][timeStep].cachedSurface = surface;
 }
 
 void mitk::SurfaceInterpolationController::Interpolate(const LabelSetImage* segmentationImage, LabelSetImage::LabelValueType labelValue, TimeStepType timeStep)
 {
   if (nullptr == segmentationImage)
   {
     mitkThrow() << "Cannot interpolate contours. No valid segmentation passed.";
   }
 
   std::lock_guard<std::shared_mutex> guard(cpiMutex);
   auto it = cpiMap.find(segmentationImage);
   if (it == cpiMap.end())
   {
     mitkThrow() << "Cannot interpolate contours. Passed segmentation is not registered at controller.";
   }
 
   if (!segmentationImage->ExistLabel(labelValue))
   {
     mitkThrow() << "Cannot interpolate contours. None existant label request. Invalid label:" << labelValue;
   }
 
   if (!segmentationImage->GetTimeGeometry()->IsValidTimeStep(timeStep))
   {
     mitkThrow() << "Cannot interpolate contours. No valid time step requested. Invalid time step:" << timeStep;
   }
 
   if (!CPICacheIsOutdated(segmentationImage, labelValue, timeStep)) return;
 
   mitk::Surface::Pointer interpolationResult = nullptr;
 
   auto reduceFilter = ReduceContourSetFilter::New();
   auto normalsFilter = ComputeContourSetNormalsFilter::New();
   auto interpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New();
 
   const auto spacing = segmentationImage->GetGeometry(timeStep)->GetSpacing();
   double minSpacing = 100;
   double maxSpacing = 0;
   for (int i = 0; i < 3; i++)
   {
     if (spacing[i] < minSpacing)
     {
       minSpacing = spacing[i];
     }
     if (spacing[i] > maxSpacing)
     {
       maxSpacing = spacing[i];
     }
   }
   reduceFilter->SetMinSpacing(minSpacing);
   reduceFilter->SetMaxSpacing(maxSpacing);
   normalsFilter->SetMaxSpacing(maxSpacing);
   interpolateSurfaceFilter->SetDistanceImageVolume(m_DistanceImageVolume);
 
   reduceFilter->SetUseProgressBar(false);
   normalsFilter->SetUseProgressBar(true);
   normalsFilter->SetProgressStepSize(1);
   interpolateSurfaceFilter->SetUseProgressBar(true);
   interpolateSurfaceFilter->SetProgressStepSize(7);
 
   //  Set reference image for interpolation surface filter
   itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New();
   mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
   timeSelector->SetInput(segmentationImage);
   timeSelector->SetTimeNr(timeStep);
   timeSelector->SetChannelNr(0);
   timeSelector->Update();
   mitk::Image::Pointer refSegImage = timeSelector->GetOutput();
   AccessFixedDimensionByItk_1(refSegImage, GetImageBase, 3, itkImage);
   interpolateSurfaceFilter->SetReferenceImage(itkImage.GetPointer());
 
   try
   {
     this->AddActiveLabelContoursForInterpolation(reduceFilter, segmentationImage, labelValue, timeStep);
     reduceFilter->Update();
     auto currentNumberOfReducedContours = reduceFilter->GetNumberOfOutputs();
 
     if (currentNumberOfReducedContours < 2)
     {
       // If no interpolation is possible reset the interpolation result
       MITK_INFO << "Interpolation impossible: not enough contours.";
     }
     else
     {
       normalsFilter->SetSegmentationBinaryImage(refSegImage);
 
       for (size_t i = 0; i < currentNumberOfReducedContours; ++i)
       {
         mitk::Surface::Pointer reducedContour = reduceFilter->GetOutput(i);
         reducedContour->DisconnectPipeline();
         normalsFilter->SetInput(i, reducedContour);
         interpolateSurfaceFilter->SetInput(i, normalsFilter->GetOutput(i));
       }
 
       // Setting up progress bar
       mitk::ProgressBar::GetInstance()->AddStepsToDo(10);
 
       // create a surface from the distance-image
       auto imageToSurfaceFilter = mitk::ImageToSurfaceFilter::New();
       imageToSurfaceFilter->SetInput(interpolateSurfaceFilter->GetOutput());
       imageToSurfaceFilter->SetThreshold(0);
       imageToSurfaceFilter->SetSmooth(true);
       imageToSurfaceFilter->SetSmoothIteration(1);
       imageToSurfaceFilter->Update();
 
       interpolationResult = mitk::Surface::New();
       interpolationResult->Expand(segmentationImage->GetTimeSteps());
 
       auto geometry = segmentationImage->GetTimeGeometry()->Clone();
       geometry->ReplaceTimeStepGeometries(mitk::Geometry3D::New());
       interpolationResult->SetTimeGeometry(geometry);
 
       interpolationResult->SetVtkPolyData(imageToSurfaceFilter->GetOutput()->GetVtkPolyData(), timeStep);
       interpolationResult->DisconnectPipeline();
 
       // Last progress step
       mitk::ProgressBar::GetInstance()->Progress(20);
 
     }
   }
   catch (const Exception& e)
   {
     MITK_ERROR << "Interpolation failed: " << e.what();
     interpolationResult = nullptr;
   }
 
   SetCPICacheSurface(interpolationResult, segmentationImage, labelValue, timeStep);
 }
 
 mitk::Surface::Pointer mitk::SurfaceInterpolationController::GetInterpolationResult(const LabelSetImage* segmentationImage, LabelSetImage::LabelValueType labelValue, TimeStepType timeStep)
 {
   if (nullptr == segmentationImage)
   {
     mitkThrow() << "Cannot interpolate contours. No valid segmentation passed.";
   }
 
   std::shared_lock<std::shared_mutex> guard(cpiMutex);
 
   if (cpiMap.find(segmentationImage) == cpiMap.end())
   {
     mitkThrow() << "Cannot interpolate contours. Passed segmentation is not registered at controller.";
   }
 
   if (!segmentationImage->ExistLabel(labelValue))
   {
     mitkThrow() << "Cannot interpolate contours. None existant label request. Invalid label:" << labelValue;
   }
 
   if (!segmentationImage->GetTimeGeometry()->IsValidTimeStep(timeStep))
   {
     mitkThrow() << "Cannot interpolate contours. No valid time step requested. Invalid time step:" << timeStep;
   }
 
   const auto& currentImageContours = cpiMap.at(segmentationImage);
 
   auto finding = currentImageContours.find(labelValue);
   if (finding == currentImageContours.end())
   {
     return nullptr;
   }
 
   const auto& currentLabelContoursMap = finding->second;
 
   auto tsfinding = currentLabelContoursMap.find(timeStep);
   if (tsfinding == currentLabelContoursMap.end())
   {
     return nullptr;
   }
 
   return tsfinding->second.cachedSurface;
 }
 
 void mitk::SurfaceInterpolationController::SetDataStorage(DataStorage::Pointer ds)
 {
   m_DataStorage = ds;
 }
 
 void mitk::SurfaceInterpolationController::SetDistanceImageVolume(unsigned int distImgVolume)
 {
   m_DistanceImageVolume = distImgVolume;
 }
 
 mitk::LabelSetImage* mitk::SurfaceInterpolationController::GetCurrentSegmentation()
 {
   return m_SelectedSegmentation.Lock();
 }
 
 unsigned int mitk::SurfaceInterpolationController::GetNumberOfInterpolationSessions()
 {
   return cpiMap.size();
 }
 
 template <typename TPixel, unsigned int VImageDimension>
 void mitk::SurfaceInterpolationController::GetImageBase(itk::Image<TPixel, VImageDimension> *input,
                                                         itk::ImageBase<3>::Pointer &result)
 {
   result->Graft(input);
 }
 
 void mitk::SurfaceInterpolationController::SetCurrentInterpolationSession(mitk::LabelSetImage* currentSegmentationImage)
 {
   auto selectedSegmentation = m_SelectedSegmentation.Lock();
 
   if (currentSegmentationImage == selectedSegmentation)
   {
     return;
   }
 
   m_SelectedSegmentation = currentSegmentationImage;
   selectedSegmentation = m_SelectedSegmentation.Lock();
 
   if (selectedSegmentation.IsNotNull())
   {
     std::lock_guard<std::shared_mutex> guard(cpiMutex);
 
     auto it = cpiMap.find(selectedSegmentation);
     if (it == cpiMap.end())
     {
       cpiMap[selectedSegmentation] = CPITimeStepLabelMap();
 
       auto command = itk::MemberCommand<SurfaceInterpolationController>::New();
       command->SetCallbackFunction(this, &SurfaceInterpolationController::OnSegmentationDeleted);
       segmentationObserverTags[selectedSegmentation] = selectedSegmentation->AddObserver(itk::DeleteEvent(), command);
       auto& controller = *this;
       const auto sender = selectedSegmentation.GetPointer();
       labelRemovedObserverTags[selectedSegmentation] = selectedSegmentation->AddObserver(mitk::LabelRemovedEvent(), [&controller, sender](const itk::EventObject& event)
         {
           controller.OnRemoveLabel(sender, event);
         });
     }
   }
 }
 
 void mitk::SurfaceInterpolationController::RemoveInterpolationSession(const mitk::LabelSetImage* segmentationImage)
 {
   if (nullptr != segmentationImage)
   {
     auto selectedSegmentation = m_SelectedSegmentation.Lock();
     if (selectedSegmentation == segmentationImage)
     {
       this->SetCurrentInterpolationSession(nullptr);
     }
 
     {
       std::lock_guard<std::shared_mutex> guard(cpiMutex);
       this->RemoveObserversInternal(segmentationImage);
       cpiMap.erase(segmentationImage);
       if (m_DataStorage.IsNotNull())
       {
         auto nodes = this->GetPlaneGeometryNodeFromDataStorage(GetSegmentationImageNodeInternal(this->m_DataStorage, segmentationImage));
         this->m_DataStorage->Remove(nodes);
       }
     }
 
   }
 }
 
 void mitk::SurfaceInterpolationController::RemoveObserversInternal(const mitk::LabelSetImage* segmentationImage)
 {
   auto pos = segmentationObserverTags.find(const_cast<mitk::LabelSetImage*>(segmentationImage));
   if (pos != segmentationObserverTags.end())
   {
     pos->first->RemoveObserver((*pos).second);
     segmentationObserverTags.erase(const_cast<mitk::LabelSetImage*>(segmentationImage));
   }
 
   auto pos2 = labelRemovedObserverTags.find(const_cast<mitk::LabelSetImage*>(segmentationImage));
   if (pos2 != labelRemovedObserverTags.end())
   {
     pos2->first->RemoveObserver((*pos2).second);
     labelRemovedObserverTags.erase(const_cast<mitk::LabelSetImage*>(segmentationImage));
   }
 }
 
 void mitk::SurfaceInterpolationController::RemoveAllInterpolationSessions()
 {
   while (!cpiMap.empty())
   {
     this->RemoveInterpolationSession(cpiMap.begin()->first);
   }
 }
 
 void mitk::SurfaceInterpolationController::RemoveContours(const LabelSetImage* segmentationImage,
   mitk::Label::PixelType label,
   TimeStepType timeStep)
 {
   if (nullptr == segmentationImage)
   {
     mitkThrow() << "Cannot remove contours. No valid segmentation passed.";
   }
 
   std::lock_guard<std::shared_mutex> guard(cpiMutex);
 
   auto segfinding = cpiMap.find(segmentationImage);
 
   if (segfinding != cpiMap.end())
   {
     auto& cpiLabelMap = cpiMap[segmentationImage];
     auto finding = cpiLabelMap.find(label);
 
     if (finding != cpiLabelMap.end())
     {
       cpiLabelMap[label].erase(timeStep);
     }
 
     if (m_DataStorage.IsNotNull())
     {
       //remove relevant plane nodes
       auto nodes = this->GetPlaneGeometryNodeFromDataStorage(GetSegmentationImageNodeInternal(this->m_DataStorage, segmentationImage), label, timeStep);
 
       this->m_DataStorage->Remove(nodes);
     }
     this->Modified();
   }
 }
 
 void mitk::SurfaceInterpolationController::RemoveContours(const LabelSetImage* segmentationImage,
   mitk::Label::PixelType label)
 {
   if (nullptr == segmentationImage)
   {
     mitkThrow() << "Cannot remove contours. No valid segmentation passed.";
   }
 
   std::lock_guard<std::shared_mutex> guard(cpiMutex);
 
   auto finding = cpiMap.find(segmentationImage);
   if (finding != cpiMap.end())
   {
     cpiMap[segmentationImage].erase(label);
 
     if (m_DataStorage.IsNotNull())
     {
       //remove relevant plane nodes
       auto nodes = this->GetPlaneGeometryNodeFromDataStorage(GetSegmentationImageNodeInternal(this->m_DataStorage, segmentationImage), label);
       this->m_DataStorage->Remove(nodes);
     }
     this->Modified();
   }
 }
 
 
 void mitk::SurfaceInterpolationController::OnSegmentationDeleted(const itk::Object *caller,
                                                                  const itk::EventObject & /*event*/)
 {
   auto tempImage = dynamic_cast<mitk::LabelSetImage *>(const_cast<itk::Object *>(caller));
   if (tempImage)
   {
     this->RemoveInterpolationSession(tempImage);
   }
 }
 
 void mitk::SurfaceInterpolationController::OnRemoveLabel(const itk::Object* caller, const itk::EventObject& event)
 {
   auto sendingSegmentation = dynamic_cast<const LabelSetImage*>(caller);
 
   auto removeEvent = dynamic_cast<const mitk::LabelRemovedEvent*>(&event);
 
   if (nullptr != sendingSegmentation && nullptr != removeEvent)
   {
     this->RemoveContours(sendingSegmentation, removeEvent->GetLabelValue());
   }
 }
 
 mitk::SurfaceInterpolationController::CPIVector* mitk::SurfaceInterpolationController::GetContours(LabelSetImage::LabelValueType labelValue, TimeStepType timeStep)
 {
   auto selectedSegmentation = m_SelectedSegmentation.Lock();
 
   if (selectedSegmentation == nullptr)
     return nullptr;
 
   std::shared_lock<std::shared_mutex> guard(cpiMutex);
 
   auto labelFinding = cpiMap[selectedSegmentation].find(labelValue);
 
   if (labelFinding != cpiMap[selectedSegmentation].end())
   {
     auto tsFinding = labelFinding->second.find(timeStep);
 
     if (tsFinding != labelFinding->second.end())
     {
       return &(tsFinding->second.cpis);
     }
   }
 
   return nullptr;
 }
 
 std::vector<mitk::LabelSetImage::LabelValueType> mitk::SurfaceInterpolationController::GetAffectedLabels(const LabelSetImage* seg, TimeStepType timeStep, const PlaneGeometry* plane) const
 {
   std::lock_guard<std::shared_mutex> guard(cpiMutex);
 
   std::vector<mitk::LabelSetImage::LabelValueType> result;
 
   auto finding = cpiMap.find(seg);
   if (finding == cpiMap.end()) return result;
   const auto& currentImageContours = cpiMap[seg];
 
   for (const auto& [label, contours] : currentImageContours)
   {
     auto tsFinding = contours.find(timeStep);
     if (tsFinding != contours.end())
     {
       const auto& cpis = contours.at(timeStep).cpis;
       auto finding = std::find_if(cpis.begin(), cpis.end(), [plane](const ContourPositionInformation& element) {return plane->IsOnPlane(element.Plane); });
 
       if (finding != cpis.end())
       {
         result.push_back(label);
       }
     }
   }
   return result;
 }
 
 
 void mitk::SurfaceInterpolationController::CompleteReinitialization(const std::vector<ContourPositionInformation>& newCPIs)
 {
   this->ClearInterpolationSession();
 
   //  Now the layers should be empty and the new layers can be added.
   this->AddNewContours(newCPIs, true);
 }
 
 void mitk::SurfaceInterpolationController::ClearInterpolationSession()
 {
   auto selectedSegmentation = m_SelectedSegmentation.Lock();
 
   if (selectedSegmentation != nullptr)
   {
     std::lock_guard<std::shared_mutex> guard(cpiMutex);
     cpiMap[selectedSegmentation].clear();
   }
 }