diff --git a/Modules/Multilabel/autoload/IO/files.cmake b/Modules/Multilabel/autoload/IO/files.cmake
index 71bd04bf86..09d98eca07 100644
--- a/Modules/Multilabel/autoload/IO/files.cmake
+++ b/Modules/Multilabel/autoload/IO/files.cmake
@@ -1,13 +1,15 @@
 set(CPP_FILES
-  mitkLabelSetImageIO.cpp
-  mitkLabelSetImageIO.h
-  mitkLabelSetImageSerializer.cpp
-  mitkLabelSetImageSerializer.h
+  mitkLegacyLabelSetImageIO.cpp
+  mitkLegacyLabelSetImageIO.h
+  mitkMultiLabelSegmentationIO.cpp
+  mitkMultiLabelSegmentationIO.h
+  mitkMultiLabelSegmentationSerializer.cpp
+  mitkMultiLabelSegmentationSerializer.h
   mitkMultilabelActivator.cpp
   mitkMultilabelIOMimeTypes.cpp
   mitkMultilabelIOMimeTypes.h
   mitkSegmentationTaskListIO.cpp
   mitkSegmentationTaskListIO.h
   mitkSegmentationTaskListSerializer.cpp
   mitkSegmentationTaskListSerializer.h
 )
diff --git a/Modules/Multilabel/autoload/IO/mitkLegacyLabelSetImageIO.cpp b/Modules/Multilabel/autoload/IO/mitkLegacyLabelSetImageIO.cpp
new file mode 100644
index 0000000000..9692c653a2
--- /dev/null
+++ b/Modules/Multilabel/autoload/IO/mitkLegacyLabelSetImageIO.cpp
@@ -0,0 +1,296 @@
+/*============================================================================
+
+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 __mitkLabelSetImageWriter__cpp
+#define __mitkLabelSetImageWriter__cpp
+
+#include "mitkLegacyLabelSetImageIO.h"
+#include "mitkBasePropertySerializer.h"
+#include "mitkMultilabelIOMimeTypes.h"
+#include "mitkImageAccessByItk.h"
+#include "mitkMultiLabelIOHelper.h"
+#include "mitkLabelSetImageConverter.h"
+#include <mitkLocaleSwitch.h>
+#include <mitkArbitraryTimeGeometry.h>
+#include <mitkIPropertyPersistence.h>
+#include <mitkCoreServices.h>
+#include <mitkItkImageIO.h>
+#include <mitkUIDManipulator.h>
+
+// itk
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+#include "itkMetaDataDictionary.h"
+#include "itkMetaDataObject.h"
+#include "itkNrrdImageIO.h"
+
+#include <tinyxml2.h>
+
+
+namespace mitk
+{
+
+  constexpr char* const OPTION_NAME_MULTI_LAYER = "Multi layer handling";
+  constexpr char* const OPTION_NAME_MULTI_LAYER_ADAPT = "Adapt label values";
+  constexpr char* const OPTION_NAME_MULTI_LAYER_SPLIT = "Split layers";
+
+  LegacyLabelSetImageIO::LegacyLabelSetImageIO()
+    : AbstractFileReader(MitkMultilabelIOMimeTypes::LEGACYLABELSET_MIMETYPE(), "MITK LabelSetImage (legacy)")
+  {
+    this->InitializeDefaultMetaDataKeys();
+    AbstractFileReader::SetRanking(10);
+
+    IFileIO::Options options;
+    std::vector<std::string> multiLayerStrategy;
+    multiLayerStrategy.push_back(OPTION_NAME_MULTI_LAYER_ADAPT);
+    multiLayerStrategy.push_back(OPTION_NAME_MULTI_LAYER_SPLIT);
+    options[OPTION_NAME_MULTI_LAYER] = multiLayerStrategy;
+    this->SetDefaultOptions(options);
+
+    this->RegisterService();
+  }
+
+
+  IFileIO::ConfidenceLevel LegacyLabelSetImageIO::GetConfidenceLevel() const
+  {
+    if (AbstractFileReader::GetConfidenceLevel() == Unsupported)
+      return Unsupported;
+    const std::string fileName = this->GetLocalFileName();
+    itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
+    io->SetFileName(fileName);
+    io->ReadImageInformation();
+
+    itk::MetaDataDictionary imgMetaDataDictionary = io->GetMetaDataDictionary();
+    std::string value("");
+    itk::ExposeMetaData<std::string>(imgMetaDataDictionary, "modality", value);
+    if (value.compare("org.mitk.image.multilabel") == 0)
+    {
+      return Supported;
+    }
+    else
+      return Unsupported;
+  }
+
+  std::vector<mitk::LabelSet::Pointer> ExtractLabelSetsFromMetaData(const itk::MetaDataDictionary& dictionary)
+  {
+    std::vector<mitk::LabelSet::Pointer> result;
+
+    // get labels and add them as properties to the image
+    char keybuffer[256];
+
+    unsigned int numberOfLayers = LegacyLabelSetImageIO::GetIntByKey(dictionary, "layers");
+    std::string _xmlStr;
+    mitk::Label::Pointer label;
+
+    for (unsigned int layerIdx = 0; layerIdx < numberOfLayers; layerIdx++)
+    {
+      sprintf(keybuffer, "layer_%03u", layerIdx);
+      int numberOfLabels = LegacyLabelSetImageIO::GetIntByKey(dictionary, keybuffer);
+
+      mitk::LabelSet::Pointer labelSet = mitk::LabelSet::New();
+
+      for (int labelIdx = 0; labelIdx < numberOfLabels; labelIdx++)
+      {
+        tinyxml2::XMLDocument doc;
+        sprintf(keybuffer, "label_%03u_%05d", layerIdx, labelIdx);
+        _xmlStr = LegacyLabelSetImageIO::GetStringByKey(dictionary, keybuffer);
+        doc.Parse(_xmlStr.c_str(), _xmlStr.size());
+
+        auto* labelElem = doc.FirstChildElement("Label");
+        if (labelElem == nullptr)
+          mitkThrow() << "Error parsing NRRD header for mitk::LabelSetImage IO";
+
+        label = mitk::MultiLabelIOHelper::LoadLabelFromXMLDocument(labelElem);
+
+        if (label->GetValue() != mitk::LabelSetImage::UnlabeledLabelValue)
+        {
+          labelSet->AddLabel(label);
+          labelSet->SetLayer(layerIdx);
+        }
+        else
+        {
+          MITK_INFO << "Multi label image contains a label specification for unlabeled pixels. This legacy information is ignored.";
+        }
+      }
+      result.push_back(labelSet);
+    }
+
+    return result;
+  }
+
+  std::vector<BaseData::Pointer> LegacyLabelSetImageIO::DoRead()
+  {
+    itk::NrrdImageIO::Pointer nrrdImageIO = itk::NrrdImageIO::New();
+
+    std::vector<BaseData::Pointer> result;
+
+    auto rawimage = ItkImageIO::LoadRawMitkImageFromImageIO(nrrdImageIO, this->GetLocalFileName());
+
+    const itk::MetaDataDictionary& dictionary = nrrdImageIO->GetMetaDataDictionary();
+
+    auto groupImages = SplitVectorImage(rawimage);
+    auto labelsets = ExtractLabelSetsFromMetaData(dictionary);
+
+    if (labelsets.size() != groupImages.size())
+    {
+      mitkThrow() << "Loaded data is in an invalid state. Number of extracted layer images and labels sets does not match. Found layer images: " << groupImages.size() << "; found labelsets: " << labelsets.size();
+    }
+
+    auto props = ItkImageIO::ExtractMetaDataAsPropertyList(nrrdImageIO->GetMetaDataDictionary(), this->GetMimeType()->GetName(), this->m_DefaultMetaDataKeys);
+
+    const Options userOptions = this->GetOptions();
+
+    const auto multiLayerStrategy = userOptions.find(OPTION_NAME_MULTI_LAYER)->second.ToString();
+
+    if (multiLayerStrategy == OPTION_NAME_MULTI_LAYER_SPLIT)
+    { //just split layers in different multi label images
+      auto labelSetIterator = labelsets.begin();
+      for (auto image : groupImages)
+      {
+        auto output = ConvertImageToLabelSetImage(image);
+        output->AddLabelSetToLayer(0, *labelSetIterator);
+
+        //meta data handling
+        for (auto& [name, prop] : *(props->GetMap()))
+        {
+          output->SetProperty(name, prop->Clone()); //need to clone to avoid that all outputs pointing to the same prop instances.
+        }
+        // Handle UID
+        //Remark if we split the legacy label set into distinct layer images, the outputs should have new IDs. So we don't get the old one.
+
+        result.push_back(output.GetPointer());
+        labelSetIterator++;
+      }
+    }
+    else
+    { //Avoid label id collision.
+      LabelSetImage::LabelValueType maxValue = LabelSetImage::UnlabeledLabelValue;
+      auto imageIterator = groupImages.begin();
+      std::vector<mitk::LabelSet::Pointer> adaptedLabelSets;
+
+      for (auto labelset : labelsets)
+      {
+        const auto setValues = labelset->GetUsedLabelValues();
+
+        //generate mapping table;
+        std::vector<std::pair<Label::PixelType, Label::PixelType> > labelMapping;
+        for (auto vIter = setValues.crbegin(); vIter != setValues.crend(); vIter++)
+        { //have to use reverse loop because TransferLabelContent (used to adapt content in the same image; see below)
+          //would potentially corrupt otherwise the content due to "value collision between old values still present
+          //and already adapted values. By going from highest value to lowest, we avoid that.
+          if (LabelSetImage::UnlabeledLabelValue != *vIter)
+            labelMapping.push_back({ *vIter, *vIter + maxValue });
+        }
+
+
+        if (LabelSetImage::UnlabeledLabelValue != maxValue)
+        {
+          //adapt labelset
+          auto mappedLabelSet = GenerateLabelSetWithMappedValues(labelset, labelMapping);
+          adaptedLabelSets.emplace_back(mappedLabelSet);
+
+          //adapt image (it is an inplace operation. the image instance stays the same.
+          TransferLabelContent(*imageIterator, *imageIterator, mappedLabelSet, LabelSetImage::UnlabeledLabelValue, LabelSetImage::UnlabeledLabelValue,
+            false, labelMapping, MultiLabelSegmentation::MergeStyle::Replace, MultiLabelSegmentation::OverwriteStyle::IgnoreLocks);
+        }
+        else
+        {
+          adaptedLabelSets.emplace_back(labelset);
+        }
+
+        const auto setMaxValue = *(std::max_element(setValues.begin(), setValues.end()));
+        maxValue += setMaxValue;
+        imageIterator++;
+      }
+
+      auto output = ConvertImageVectorToLabelSetImage(groupImages, rawimage->GetTimeGeometry());
+
+      LabelSetImage::SpatialGroupIndexType id = 0;
+      for (auto labelset : adaptedLabelSets)
+      {
+        output->AddLabelSetToLayer(id, labelset);
+        id++;
+      }
+
+      //meta data handling
+      for (auto& [name, prop] : *(props->GetMap()))
+      {
+        output->SetProperty(name, prop->Clone()); //need to clone to avoid that all outputs pointing to the same prop instances.
+      }
+
+      // Handle UID
+      if (dictionary.HasKey(PROPERTY_KEY_UID))
+      {
+        itk::MetaDataObject<std::string>::ConstPointer uidData = dynamic_cast<const itk::MetaDataObject<std::string>*>(dictionary.Get(PROPERTY_KEY_UID));
+        if (uidData.IsNotNull())
+        {
+          mitk::UIDManipulator uidManipulator(output);
+          uidManipulator.SetUID(uidData->GetMetaDataObjectValue());
+        }
+      }
+      result.push_back(output.GetPointer());
+    }
+
+    MITK_INFO << "...finished!";
+    return result;
+  }
+
+  int LegacyLabelSetImageIO::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 LegacyLabelSetImageIO::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;
+  }
+
+  LegacyLabelSetImageIO *LegacyLabelSetImageIO::Clone() const { return new LegacyLabelSetImageIO(*this); }
+
+  void LegacyLabelSetImageIO::InitializeDefaultMetaDataKeys()
+  {
+    this->m_DefaultMetaDataKeys.push_back("NRRD.space");
+    this->m_DefaultMetaDataKeys.push_back("NRRD.kinds");
+    this->m_DefaultMetaDataKeys.push_back(PROPERTY_NAME_TIMEGEOMETRY_TYPE);
+    this->m_DefaultMetaDataKeys.push_back(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS);
+    this->m_DefaultMetaDataKeys.push_back("ITK.InputFilterName");
+    this->m_DefaultMetaDataKeys.push_back("label.");
+    this->m_DefaultMetaDataKeys.push_back("layer.");
+    this->m_DefaultMetaDataKeys.push_back("layers");
+    this->m_DefaultMetaDataKeys.push_back("org.mitk.label.");
+  }
+
+} // namespace
+
+#endif //__mitkLabelSetImageWriter__cpp
diff --git a/Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.h b/Modules/Multilabel/autoload/IO/mitkLegacyLabelSetImageIO.h
similarity index 66%
copy from Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.h
copy to Modules/Multilabel/autoload/IO/mitkLegacyLabelSetImageIO.h
index 4e443688ec..063ca96a63 100644
--- a/Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.h
+++ b/Modules/Multilabel/autoload/IO/mitkLegacyLabelSetImageIO.h
@@ -1,69 +1,64 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
-#ifndef mitkLabelSetImageIO_h
-#define mitkLabelSetImageIO_h
+#ifndef mitkLegacyLabelSetImageIO_h
+#define mitkLegacyLabelSetImageIO_h
 
-#include <mitkAbstractFileIO.h>
+#include <mitkAbstractFileReader.h>
 #include <mitkLabelSetImage.h>
 
 namespace mitk
 {
   /**
   * Writes a LabelSetImage to a file.
   * mitk::Identifiable UID is supported and will be serialized.
   * @ingroup Process
   */
   // The export macro should be removed. Currently, the unit
   // tests directly instantiate this class.
-  class LabelSetImageIO : public mitk::AbstractFileIO
+  class LegacyLabelSetImageIO : public mitk::AbstractFileReader
   {
   public:
     typedef mitk::LabelSetImage InputType;
 
-    LabelSetImageIO();
+    LegacyLabelSetImageIO();
 
     // -------------- AbstractFileReader -------------
 
     using AbstractFileReader::Read;
 
-    ConfidenceLevel GetReaderConfidenceLevel() const override;
+    ConfidenceLevel GetConfidenceLevel() const override;
 
-    // -------------- AbstractFileWriter -------------
+    // -------------- LegacyLabelSetImageIO specific functions -------------
 
-    void Write() override;
-    ConfidenceLevel GetWriterConfidenceLevel() const override;
-
-    // -------------- LabelSetImageIO specific functions -------------
-
-    int GetIntByKey(const itk::MetaDataDictionary &dic, const std::string &str);
-    std::string GetStringByKey(const itk::MetaDataDictionary &dic, const std::string &str);
+    static int GetIntByKey(const itk::MetaDataDictionary &dic, const std::string &str);
+    static std::string GetStringByKey(const itk::MetaDataDictionary &dic, const std::string &str);
 
   protected:
     /**
     * @brief Reads a number of mitk::LabelSetImages from the file system
     * @return a vector of mitk::LabelSetImages
     * @throws throws an mitk::Exception if an error ocurrs during parsing the nrrd header
     */
     std::vector<itk::SmartPointer<BaseData>> DoRead() override;
 
     // Fills the m_DefaultMetaDataKeys vector with default values
     virtual void InitializeDefaultMetaDataKeys();
 
   private:
-    LabelSetImageIO *IOClone() const override;
+    LegacyLabelSetImageIO *Clone() const override;
 
     std::vector<std::string> m_DefaultMetaDataKeys;
   };
 } // end of namespace mitk
 
 #endif
diff --git a/Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.cpp b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.cpp
similarity index 93%
rename from Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.cpp
rename to Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.cpp
index 669ebd7d79..1592ef01ba 100644
--- a/Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.cpp
+++ b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.cpp
@@ -1,662 +1,653 @@
 /*============================================================================
 
 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 __mitkLabelSetImageWriter__cpp
-#define __mitkLabelSetImageWriter__cpp
-
-#include "mitkLabelSetImageIO.h"
+#include "mitkMultiLabelSegmentationIO.h"
 #include "mitkBasePropertySerializer.h"
 #include "mitkIOMimeTypes.h"
 #include "mitkImageAccessByItk.h"
-#include "mitkLabelSetIOHelper.h"
+#include "mitkMultiLabelIOHelper.h"
 #include "mitkLabelSetImageConverter.h"
 #include <mitkLocaleSwitch.h>
 #include <mitkArbitraryTimeGeometry.h>
 #include <mitkIPropertyPersistence.h>
 #include <mitkCoreServices.h>
 #include <mitkItkImageIO.h>
 #include <mitkUIDManipulator.h>
 
 // itk
 #include "itkImageFileReader.h"
 #include "itkImageFileWriter.h"
 #include "itkMetaDataDictionary.h"
 #include "itkMetaDataObject.h"
 #include "itkNrrdImageIO.h"
 
 #include <tinyxml2.h>
 
 namespace mitk
 {
 
-  const char* const PROPERTY_NAME_TIMEGEOMETRY_TYPE = "org.mitk.timegeometry.type";
-  const char* const PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS = "org.mitk.timegeometry.timepoints";
-  const char* const PROPERTY_KEY_TIMEGEOMETRY_TYPE = "org_mitk_timegeometry_type";
-  const char* const PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS = "org_mitk_timegeometry_timepoints";
-  const char* const PROPERTY_KEY_UID = "org_mitk_uid";
+  constexpr char* const MULTILABEL_SEGMENTATION_MODALITY_VALUE = "org.mitk.image.multilabel.segmentation";
 
-  LabelSetImageIO::LabelSetImageIO()
+  MultiLabelSegmentationIO::MultiLabelSegmentationIO()
     : AbstractFileIO(LabelSetImage::GetStaticNameOfClass(), IOMimeTypes::NRRD_MIMETYPE(), "MITK Multilabel Image")
   {
     this->InitializeDefaultMetaDataKeys();
     AbstractFileWriter::SetRanking(10);
     AbstractFileReader::SetRanking(10);
     this->RegisterService();
   }
 
-  IFileIO::ConfidenceLevel LabelSetImageIO::GetWriterConfidenceLevel() const
+  IFileIO::ConfidenceLevel MultiLabelSegmentationIO::GetWriterConfidenceLevel() const
   {
     if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported)
       return Unsupported;
     const auto *input = static_cast<const LabelSetImage *>(this->GetInput());
     if (input)
       return Supported;
     else
       return Unsupported;
   }
 
-  void LabelSetImageIO::Write()
+  void MultiLabelSegmentationIO::Write()
   {
     ValidateOutputLocation();
 
     auto input = dynamic_cast<const LabelSetImage *>(this->GetInput());
 
     mitk::LocaleSwitch localeSwitch("C");
 
     mitk::Image::Pointer inputVector = mitk::ConvertLabelSetImageToImage(input);
 
     // image write
     if (inputVector.IsNull())
     {
       mitkThrow() << "Cannot write non-image data";
     }
 
     itk::NrrdImageIO::Pointer nrrdImageIo = itk::NrrdImageIO::New();
 
     // Clone the image geometry, because we might have to change it
     // for writing purposes
     BaseGeometry::Pointer geometry = inputVector->GetGeometry()->Clone();
 
     // Check if geometry information will be lost
     if (inputVector->GetDimension() == 2 && !geometry->Is2DConvertable())
     {
       MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might "
                    "consider using Convert2Dto3DImageFilter before saving.";
 
       // set matrix to identity
       mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New();
       affTrans->SetIdentity();
       mitk::Vector3D spacing = geometry->GetSpacing();
       mitk::Point3D origin = geometry->GetOrigin();
       geometry->SetIndexToWorldTransform(affTrans);
       geometry->SetSpacing(spacing);
       geometry->SetOrigin(origin);
     }
 
     LocalFile localFile(this);
     const std::string path = localFile.GetFileName();
 
     MITK_INFO << "Writing image: " << path << std::endl;
 
     try
     {
       // Implementation of writer using itkImageIO directly. This skips the use
       // of templated itkImageFileWriter, which saves the multiplexing on MITK side.
 
       const unsigned int dimension = inputVector->GetDimension();
       const unsigned int *const dimensions = inputVector->GetDimensions();
       const mitk::PixelType pixelType = inputVector->GetPixelType();
       const mitk::Vector3D mitkSpacing = geometry->GetSpacing();
       const mitk::Point3D mitkOrigin = geometry->GetOrigin();
 
       // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin,
       // though they are not supported in MITK
       itk::Vector<double, 4u> spacing4D;
       spacing4D[0] = mitkSpacing[0];
       spacing4D[1] = mitkSpacing[1];
       spacing4D[2] = mitkSpacing[2];
       spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have a valid value here
 
       itk::Vector<double, 4u> origin4D;
       origin4D[0] = mitkOrigin[0];
       origin4D[1] = mitkOrigin[1];
       origin4D[2] = mitkOrigin[2];
       origin4D[3] = 0; // There is no support for a 4D origin. However, we should have a valid value here
 
       // Set the necessary information for imageIO
       nrrdImageIo->SetNumberOfDimensions(dimension);
       nrrdImageIo->SetPixelType(pixelType.GetPixelType());
       nrrdImageIo->SetComponentType(static_cast<int>(pixelType.GetComponentType()) < PixelComponentUserType
                                       ? pixelType.GetComponentType()
                                       : itk::IOComponentEnum::UNKNOWNCOMPONENTTYPE);
       nrrdImageIo->SetNumberOfComponents(pixelType.GetNumberOfComponents());
 
       itk::ImageIORegion ioRegion(dimension);
 
       for (unsigned int i = 0; i < dimension; i++)
       {
         nrrdImageIo->SetDimensions(i, dimensions[i]);
         nrrdImageIo->SetSpacing(i, spacing4D[i]);
         nrrdImageIo->SetOrigin(i, origin4D[i]);
 
         mitk::Vector3D mitkDirection(0.0);
         mitkDirection.SetVnlVector(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i).as_ref());
         itk::Vector<double, 4u> direction4D;
         direction4D[0] = mitkDirection[0];
         direction4D[1] = mitkDirection[1];
         direction4D[2] = mitkDirection[2];
 
         // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must
         // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix.
         if (i == 3)
         {
           direction4D[3] = 1; // homogenous component
         }
         else
         {
           direction4D[3] = 0;
         }
         vnl_vector<double> axisDirection(dimension);
         for (unsigned int j = 0; j < dimension; j++)
         {
           axisDirection[j] = direction4D[j] / spacing4D[i];
         }
         nrrdImageIo->SetDirection(i, axisDirection);
 
         ioRegion.SetSize(i, inputVector->GetLargestPossibleRegion().GetSize(i));
         ioRegion.SetIndex(i, inputVector->GetLargestPossibleRegion().GetIndex(i));
       }
 
       // use compression if available
       nrrdImageIo->UseCompressionOn();
 
       nrrdImageIo->SetIORegion(ioRegion);
       nrrdImageIo->SetFileName(path);
 
       // label set specific meta data
       char keybuffer[512];
       char valbuffer[512];
 
       sprintf(keybuffer, "modality");
-      sprintf(valbuffer, "org.mitk.image.multilabel");
+      sprintf(valbuffer, MULTILABEL_SEGMENTATION_MODALITY_VALUE);
       itk::EncapsulateMetaData<std::string>(
         nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));
 
       sprintf(keybuffer, "layers");
       sprintf(valbuffer, "%1d", input->GetNumberOfLayers());
       itk::EncapsulateMetaData<std::string>(
         nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));
 
       for (unsigned int layerIdx = 0; layerIdx < input->GetNumberOfLayers(); layerIdx++)
       {
         sprintf(keybuffer, "layer_%03u", layerIdx);                    // layer idx
         sprintf(valbuffer, "%1u", input->GetNumberOfLabels(layerIdx)); // number of labels for the layer
         itk::EncapsulateMetaData<std::string>(
           nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));
 
         auto iter = input->GetLabelSet(layerIdx)->IteratorConstBegin();
         unsigned int count(0);
         while (iter != input->GetLabelSet(layerIdx)->IteratorConstEnd())
         {
           tinyxml2::XMLDocument document;
           document.InsertEndChild(document.NewDeclaration());
-          auto *labelElem = mitk::LabelSetIOHelper::GetLabelAsXMLElement(document, iter->second);
+          auto *labelElem = mitk::MultiLabelIOHelper::GetLabelAsXMLElement(document, iter->second);
           document.InsertEndChild(labelElem);
           tinyxml2::XMLPrinter printer;
           document.Print(&printer);
 
           sprintf(keybuffer, "org.mitk.label_%03u_%05u", layerIdx, count);
           itk::EncapsulateMetaData<std::string>(
             nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), printer.CStr());
           ++iter;
           ++count;
         }
       }
       // end label set specific meta data
 
       // Handle time geometry
       const auto* arbitraryTG = dynamic_cast<const ArbitraryTimeGeometry*>(input->GetTimeGeometry());
       if (arbitraryTG)
       {
         itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(),
           PROPERTY_KEY_TIMEGEOMETRY_TYPE,
           ArbitraryTimeGeometry::GetStaticNameOfClass());
 
 
         auto metaTimePoints = ConvertTimePointListToMetaDataObject(arbitraryTG);
         nrrdImageIo->GetMetaDataDictionary().Set(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS, metaTimePoints);
       }
 
       // Handle properties
       mitk::PropertyList::Pointer imagePropertyList = input->GetPropertyList();
       for (const auto& property : *imagePropertyList->GetMap())
       {
         mitk::CoreServicePointer<IPropertyPersistence> propPersistenceService(mitk::CoreServices::GetPropertyPersistence());
         IPropertyPersistence::InfoResultType infoList = propPersistenceService->GetInfo(property.first, GetMimeType()->GetName(), true);
 
         if (infoList.empty())
         {
           continue;
         }
 
         std::string value = infoList.front()->GetSerializationFunction()(property.second);
 
         if (value == mitk::BaseProperty::VALUE_CANNOT_BE_CONVERTED_TO_STRING)
         {
           continue;
         }
 
         std::string key = infoList.front()->GetKey();
 
         itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(), key, value);
       }
 
       // Handle UID
       itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(), PROPERTY_KEY_UID, input->GetUID());
 
       ImageReadAccessor imageAccess(inputVector);
       nrrdImageIo->Write(imageAccess.GetData());
     }
     catch (const std::exception &e)
     {
       mitkThrow() << e.what();
     }
     // end image write
   }
 
-  IFileIO::ConfidenceLevel LabelSetImageIO::GetReaderConfidenceLevel() const
+  IFileIO::ConfidenceLevel MultiLabelSegmentationIO::GetReaderConfidenceLevel() const
   {
     if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported)
       return Unsupported;
     const std::string fileName = this->GetLocalFileName();
     itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
     io->SetFileName(fileName);
     io->ReadImageInformation();
 
     itk::MetaDataDictionary imgMetaDataDictionary = io->GetMetaDataDictionary();
     std::string value("");
     itk::ExposeMetaData<std::string>(imgMetaDataDictionary, "modality", value);
-    if (value.compare("org.mitk.image.multilabel") == 0)
+    if (value.compare(MULTILABEL_SEGMENTATION_MODALITY_VALUE) == 0)
     {
       return Supported;
     }
     else
       return Unsupported;
   }
 
-  std::vector<BaseData::Pointer> LabelSetImageIO::DoRead()
+  std::vector<BaseData::Pointer> MultiLabelSegmentationIO::DoRead()
   {
     mitk::LocaleSwitch localeSwitch("C");
 
     // begin regular image loading, adapted from mitkItkImageIO
     itk::NrrdImageIO::Pointer nrrdImageIO = itk::NrrdImageIO::New();
     Image::Pointer image = Image::New();
 
     const unsigned int MINDIM = 2;
     const unsigned int MAXDIM = 4;
 
     const std::string path = this->GetLocalFileName();
 
     MITK_INFO << "loading " << path << " via itk::ImageIOFactory... " << std::endl;
 
     // Check to see if we can read the file given the name or prefix
     if (path.empty())
     {
       mitkThrow() << "Empty filename in mitk::ItkImageIO ";
     }
 
     // Got to allocate space for the image. Determine the characteristics of
     // the image.
     nrrdImageIO->SetFileName(path);
     nrrdImageIO->ReadImageInformation();
 
     unsigned int ndim = nrrdImageIO->GetNumberOfDimensions();
     if (ndim < MINDIM || ndim > MAXDIM)
     {
       MITK_WARN << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim
                 << " dimensions! Reading as 4D.";
       ndim = MAXDIM;
     }
 
     itk::ImageIORegion ioRegion(ndim);
     itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize();
     itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex();
 
     unsigned int dimensions[MAXDIM];
     dimensions[0] = 0;
     dimensions[1] = 0;
     dimensions[2] = 0;
     dimensions[3] = 0;
 
     ScalarType spacing[MAXDIM];
     spacing[0] = 1.0f;
     spacing[1] = 1.0f;
     spacing[2] = 1.0f;
     spacing[3] = 1.0f;
 
     Point3D origin;
     origin.Fill(0);
 
     unsigned int i;
     for (i = 0; i < ndim; ++i)
     {
       ioStart[i] = 0;
       ioSize[i] = nrrdImageIO->GetDimensions(i);
       if (i < MAXDIM)
       {
         dimensions[i] = nrrdImageIO->GetDimensions(i);
         spacing[i] = nrrdImageIO->GetSpacing(i);
         if (spacing[i] <= 0)
           spacing[i] = 1.0f;
       }
       if (i < 3)
       {
         origin[i] = nrrdImageIO->GetOrigin(i);
       }
     }
 
     ioRegion.SetSize(ioSize);
     ioRegion.SetIndex(ioStart);
 
     MITK_INFO << "ioRegion: " << ioRegion << std::endl;
     nrrdImageIO->SetIORegion(ioRegion);
     void *buffer = new unsigned char[nrrdImageIO->GetImageSizeInBytes()];
     nrrdImageIO->Read(buffer);
 
     image->Initialize(MakePixelType(nrrdImageIO), ndim, dimensions);
     image->SetImportChannel(buffer, 0, Image::ManageMemory);
 
     // access direction of itk::Image and include spacing
     mitk::Matrix3D matrix;
     matrix.SetIdentity();
     unsigned int j, itkDimMax3 = (ndim >= 3 ? 3 : ndim);
     for (i = 0; i < itkDimMax3; ++i)
       for (j = 0; j < itkDimMax3; ++j)
         matrix[i][j] = nrrdImageIO->GetDirection(j)[i];
 
     // re-initialize PlaneGeometry with origin and direction
     PlaneGeometry *planeGeometry = image->GetSlicedGeometry(0)->GetPlaneGeometry(0);
     planeGeometry->SetOrigin(origin);
     planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix);
 
     // re-initialize SlicedGeometry3D
     SlicedGeometry3D *slicedGeometry = image->GetSlicedGeometry(0);
     slicedGeometry->InitializeEvenlySpaced(planeGeometry, image->GetDimension(2));
     slicedGeometry->SetSpacing(spacing);
 
     MITK_INFO << slicedGeometry->GetCornerPoint(false, false, false);
     MITK_INFO << slicedGeometry->GetCornerPoint(true, true, true);
 
     // re-initialize TimeGeometry
     const itk::MetaDataDictionary& dictionary = nrrdImageIO->GetMetaDataDictionary();
     TimeGeometry::Pointer timeGeometry;
 
     if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TYPE) || dictionary.HasKey(PROPERTY_KEY_TIMEGEOMETRY_TYPE))
     { // also check for the name because of backwards compatibility. Past code version stored with the name and not with
       // the key
       itk::MetaDataObject<std::string>::ConstPointer timeGeometryTypeData;
       if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TYPE))
       {
         timeGeometryTypeData =
           dynamic_cast<const itk::MetaDataObject<std::string>*>(dictionary.Get(PROPERTY_NAME_TIMEGEOMETRY_TYPE));
       }
       else
       {
         timeGeometryTypeData =
           dynamic_cast<const itk::MetaDataObject<std::string>*>(dictionary.Get(PROPERTY_KEY_TIMEGEOMETRY_TYPE));
       }
 
       if (timeGeometryTypeData->GetMetaDataObjectValue() == ArbitraryTimeGeometry::GetStaticNameOfClass())
       {
         MITK_INFO << "used time geometry: " << ArbitraryTimeGeometry::GetStaticNameOfClass();
         typedef std::vector<TimePointType> TimePointVector;
         TimePointVector timePoints;
 
         if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS))
         {
           timePoints = ConvertMetaDataObjectToTimePointList(dictionary.Get(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS));
         }
         else if (dictionary.HasKey(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS))
         {
           timePoints = ConvertMetaDataObjectToTimePointList(dictionary.Get(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS));
         }
 
         if (timePoints.empty())
         {
           MITK_ERROR << "Stored timepoints are empty. Meta information seems to bee invalid. Switch to ProportionalTimeGeometry fallback";
         }
         else if (timePoints.size() - 1 != image->GetDimension(3))
         {
           MITK_ERROR << "Stored timepoints (" << timePoints.size() - 1 << ") and size of image time dimension ("
             << image->GetDimension(3) << ") do not match. Switch to ProportionalTimeGeometry fallback";
         }
         else
         {
           ArbitraryTimeGeometry::Pointer arbitraryTimeGeometry = ArbitraryTimeGeometry::New();
           TimePointVector::const_iterator pos = timePoints.begin();
           auto prePos = pos++;
 
           for (; pos != timePoints.end(); ++prePos, ++pos)
           {
             arbitraryTimeGeometry->AppendNewTimeStepClone(slicedGeometry, *prePos, *pos);
           }
 
           timeGeometry = arbitraryTimeGeometry;
         }
       }
     }
 
     if (timeGeometry.IsNull())
     { // Fallback. If no other valid time geometry has been created, create a ProportionalTimeGeometry
       MITK_INFO << "used time geometry: " << ProportionalTimeGeometry::GetStaticNameOfClass();
       ProportionalTimeGeometry::Pointer propTimeGeometry = ProportionalTimeGeometry::New();
       propTimeGeometry->Initialize(slicedGeometry, image->GetDimension(3));
       timeGeometry = propTimeGeometry;
     }
 
     image->SetTimeGeometry(timeGeometry);
 
     buffer = nullptr;
     MITK_INFO << "number of image components: " << image->GetPixelType().GetNumberOfComponents();
 
     // end regular image loading
 
     LabelSetImage::Pointer output = ConvertImageToLabelSetImage(image);
 
     // get labels and add them as properties to the image
     char keybuffer[256];
 
     unsigned int numberOfLayers = GetIntByKey(dictionary, "layers");
     std::string _xmlStr;
     mitk::Label::Pointer label;
 
     for (unsigned int layerIdx = 0; layerIdx < numberOfLayers; layerIdx++)
     {
       sprintf(keybuffer, "layer_%03u", layerIdx);
       int numberOfLabels = GetIntByKey(dictionary, keybuffer);
 
       mitk::LabelSet::Pointer labelSet = mitk::LabelSet::New();
 
       for (int labelIdx = 0; labelIdx < numberOfLabels; labelIdx++)
       {
         tinyxml2::XMLDocument doc;
         sprintf(keybuffer, "label_%03u_%05d", layerIdx, labelIdx);
         _xmlStr = GetStringByKey(dictionary, keybuffer);
         doc.Parse(_xmlStr.c_str(), _xmlStr.size());
 
         auto *labelElem = doc.FirstChildElement("Label");
         if (labelElem == nullptr)
           mitkThrow() << "Error parsing NRRD header for mitk::LabelSetImage IO";
 
-        label = mitk::LabelSetIOHelper::LoadLabelFromXMLDocument(labelElem);
+        label = mitk::MultiLabelIOHelper::LoadLabelFromXMLDocument(labelElem);
 
         if (label->GetValue() != mitk::LabelSetImage::UnlabeledLabelValue)
         {
           labelSet->AddLabel(label);
           labelSet->SetLayer(layerIdx);
         }
         else
         {
           MITK_INFO << "Multi label image contains a label specification for unlabeled pixels. This legacy information is ignored.";
         }
       }
       output->AddLabelSetToLayer(layerIdx, labelSet);
     }
 
     for (auto iter = dictionary.Begin(), iterEnd = dictionary.End(); iter != iterEnd;
       ++iter)
     {
       if (iter->second->GetMetaDataObjectTypeInfo() == typeid(std::string))
       {
         const std::string& key = iter->first;
         std::string assumedPropertyName = key;
         std::replace(assumedPropertyName.begin(), assumedPropertyName.end(), '_', '.');
 
         std::string mimeTypeName = GetMimeType()->GetName();
 
         // Check if there is already a info for the key and our mime type.
         mitk::CoreServicePointer<IPropertyPersistence> propPersistenceService(mitk::CoreServices::GetPropertyPersistence());
         IPropertyPersistence::InfoResultType infoList = propPersistenceService->GetInfoByKey(key);
 
         auto predicate = [&mimeTypeName](const PropertyPersistenceInfo::ConstPointer& x) {
           return x.IsNotNull() && x->GetMimeTypeName() == mimeTypeName;
         };
         auto finding = std::find_if(infoList.begin(), infoList.end(), predicate);
 
         if (finding == infoList.end())
         {
           auto predicateWild = [](const PropertyPersistenceInfo::ConstPointer& x) {
             return x.IsNotNull() && x->GetMimeTypeName() == PropertyPersistenceInfo::ANY_MIMETYPE_NAME();
           };
           finding = std::find_if(infoList.begin(), infoList.end(), predicateWild);
         }
 
         PropertyPersistenceInfo::ConstPointer info;
 
         if (finding != infoList.end())
         {
           assumedPropertyName = (*finding)->GetName();
           info = *finding;
         }
         else
         { // we have not found anything suitable so we generate our own info
           auto newInfo = PropertyPersistenceInfo::New();
           newInfo->SetNameAndKey(assumedPropertyName, key);
           newInfo->SetMimeTypeName(PropertyPersistenceInfo::ANY_MIMETYPE_NAME());
           info = newInfo;
         }
 
         std::string value =
           dynamic_cast<itk::MetaDataObject<std::string>*>(iter->second.GetPointer())->GetMetaDataObjectValue();
 
         mitk::BaseProperty::Pointer loadedProp = info->GetDeserializationFunction()(value);
 
         if (loadedProp.IsNull())
         {
           MITK_ERROR << "Property cannot be correctly deserialized and is skipped. Check if data format is valid. Problematic property value string: \"" << value << "\"; Property info used to deserialized: " << info;
           break;
         }
 
         output->SetProperty(assumedPropertyName.c_str(), loadedProp);
 
         // Read properties should be persisted unless they are default properties
         // which are written anyway
         bool isDefaultKey = false;
 
         for (const auto& defaultKey : m_DefaultMetaDataKeys)
         {
           if (defaultKey.length() <= assumedPropertyName.length())
           {
             // does the start match the default key
             if (assumedPropertyName.substr(0, defaultKey.length()).find(defaultKey) != std::string::npos)
             {
               isDefaultKey = true;
               break;
             }
           }
         }
 
         if (!isDefaultKey)
         {
           propPersistenceService->AddInfo(info);
         }
       }
     }
 
     // Handle UID
     if (dictionary.HasKey(PROPERTY_KEY_UID))
     {
       itk::MetaDataObject<std::string>::ConstPointer uidData = dynamic_cast<const itk::MetaDataObject<std::string>*>(dictionary.Get(PROPERTY_KEY_UID));
       if (uidData.IsNotNull())
       {
         mitk::UIDManipulator uidManipulator(output);
         uidManipulator.SetUID(uidData->GetMetaDataObjectValue());
       }
     }
 
     MITK_INFO << "...finished!";
 
     std::vector<BaseData::Pointer> result;
     result.push_back(output.GetPointer());
     return result;
   }
 
-  int LabelSetImageIO::GetIntByKey(const itk::MetaDataDictionary &dic, const std::string &str)
+  int MultiLabelSegmentationIO::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 LabelSetImageIO::GetStringByKey(const itk::MetaDataDictionary &dic, const std::string &str)
+  std::string MultiLabelSegmentationIO::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;
   }
 
-  LabelSetImageIO *LabelSetImageIO::IOClone() const { return new LabelSetImageIO(*this); }
+  MultiLabelSegmentationIO *MultiLabelSegmentationIO::IOClone() const { return new MultiLabelSegmentationIO(*this); }
 
-  void LabelSetImageIO::InitializeDefaultMetaDataKeys()
+  void MultiLabelSegmentationIO::InitializeDefaultMetaDataKeys()
   {
     this->m_DefaultMetaDataKeys.push_back("NRRD.space");
     this->m_DefaultMetaDataKeys.push_back("NRRD.kinds");
     this->m_DefaultMetaDataKeys.push_back(PROPERTY_NAME_TIMEGEOMETRY_TYPE);
     this->m_DefaultMetaDataKeys.push_back(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS);
     this->m_DefaultMetaDataKeys.push_back("ITK.InputFilterName");
     this->m_DefaultMetaDataKeys.push_back("label.");
     this->m_DefaultMetaDataKeys.push_back("layer.");
     this->m_DefaultMetaDataKeys.push_back("layers");
     this->m_DefaultMetaDataKeys.push_back("org.mitk.label.");
   }
 
 } // namespace
-
-#endif //__mitkLabelSetImageWriter__cpp
diff --git a/Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.h b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.h
similarity index 85%
rename from Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.h
rename to Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.h
index 4e443688ec..a60e0ed1c3 100644
--- a/Modules/Multilabel/autoload/IO/mitkLabelSetImageIO.h
+++ b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationIO.h
@@ -1,69 +1,69 @@
 /*============================================================================
 
 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 mitkLabelSetImageIO_h
-#define mitkLabelSetImageIO_h
+#ifndef mitkMultiLabelSegmentationIO_h
+#define mitkMultiLabelSegmentationIO_h
 
 #include <mitkAbstractFileIO.h>
 #include <mitkLabelSetImage.h>
 
 namespace mitk
 {
   /**
   * Writes a LabelSetImage to a file.
   * mitk::Identifiable UID is supported and will be serialized.
   * @ingroup Process
   */
   // The export macro should be removed. Currently, the unit
   // tests directly instantiate this class.
-  class LabelSetImageIO : public mitk::AbstractFileIO
+  class MultiLabelSegmentationIO : public mitk::AbstractFileIO
   {
   public:
     typedef mitk::LabelSetImage InputType;
 
-    LabelSetImageIO();
+    MultiLabelSegmentationIO();
 
     // -------------- AbstractFileReader -------------
 
     using AbstractFileReader::Read;
 
     ConfidenceLevel GetReaderConfidenceLevel() const override;
 
     // -------------- AbstractFileWriter -------------
 
     void Write() override;
     ConfidenceLevel GetWriterConfidenceLevel() const override;
 
-    // -------------- LabelSetImageIO specific functions -------------
+    // -------------- MultiLabelSegmentationIO specific functions -------------
 
     int GetIntByKey(const itk::MetaDataDictionary &dic, const std::string &str);
     std::string GetStringByKey(const itk::MetaDataDictionary &dic, const std::string &str);
 
   protected:
     /**
     * @brief Reads a number of mitk::LabelSetImages from the file system
     * @return a vector of mitk::LabelSetImages
     * @throws throws an mitk::Exception if an error ocurrs during parsing the nrrd header
     */
     std::vector<itk::SmartPointer<BaseData>> DoRead() override;
 
     // Fills the m_DefaultMetaDataKeys vector with default values
     virtual void InitializeDefaultMetaDataKeys();
 
   private:
-    LabelSetImageIO *IOClone() const override;
+    MultiLabelSegmentationIO *IOClone() const override;
 
     std::vector<std::string> m_DefaultMetaDataKeys;
   };
 } // end of namespace mitk
 
 #endif
diff --git a/Modules/Multilabel/autoload/IO/mitkLabelSetImageSerializer.cpp b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationSerializer.cpp
similarity index 82%
rename from Modules/Multilabel/autoload/IO/mitkLabelSetImageSerializer.cpp
rename to Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationSerializer.cpp
index 892c656dbd..9a05adcc3c 100644
--- a/Modules/Multilabel/autoload/IO/mitkLabelSetImageSerializer.cpp
+++ b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationSerializer.cpp
@@ -1,64 +1,64 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
-#include "mitkLabelSetImageSerializer.h"
+#include "mitkMultiLabelSegmentationSerializer.h"
 #include "mitkLabelSetImage.h"
 
 #include <itksys/SystemTools.hxx>
 
 #include <mitkIOUtil.h>
 
-MITK_REGISTER_SERIALIZER(LabelSetImageSerializer)
+MITK_REGISTER_SERIALIZER(MultiLabelSegmentationSerializer)
 
-mitk::LabelSetImageSerializer::LabelSetImageSerializer()
+mitk::MultiLabelSegmentationSerializer::MultiLabelSegmentationSerializer()
 {
 }
 
-mitk::LabelSetImageSerializer::~LabelSetImageSerializer()
+mitk::MultiLabelSegmentationSerializer::~MultiLabelSegmentationSerializer()
 {
 }
 
-std::string mitk::LabelSetImageSerializer::Serialize()
+std::string mitk::MultiLabelSegmentationSerializer::Serialize()
 {
   const auto *image = dynamic_cast<const LabelSetImage *>(m_Data.GetPointer());
   if (image == nullptr)
   {
     MITK_ERROR << " Object at " << (const void *)this->m_Data
                << " is not an mitk::LabelSetImage. Cannot serialize as LabelSetImage.";
     return "";
   }
 
   std::string filename(this->GetUniqueFilenameInWorkingDirectory());
   filename += "_";
   filename += m_FilenameHint;
   filename += ".nrrd";
 
   std::string fullname(m_WorkingDirectory);
   fullname += "/";
   fullname += itksys::SystemTools::ConvertToOutputPath(filename.c_str());
 
   try
   {
     mitk::IOUtil::Save(image, fullname);
     //    LabelSetImageWriter::Pointer writer = LabelSetImageWriter::New();
     //    writer->SetFileName(fullname);
     //    writer->SetInput(const_cast<LabelSetImage*>(image));
     //    writer->Write();
   }
   catch (std::exception &e)
   {
     MITK_ERROR << " Error serializing object at " << (const void *)this->m_Data << " to " << fullname << ": "
                << e.what();
     return "";
   }
   return filename;
 }
diff --git a/Modules/Multilabel/autoload/IO/mitkLabelSetImageSerializer.h b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationSerializer.h
similarity index 66%
rename from Modules/Multilabel/autoload/IO/mitkLabelSetImageSerializer.h
rename to Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationSerializer.h
index 3b205dd51c..5c6fdab21d 100644
--- a/Modules/Multilabel/autoload/IO/mitkLabelSetImageSerializer.h
+++ b/Modules/Multilabel/autoload/IO/mitkMultiLabelSegmentationSerializer.h
@@ -1,37 +1,37 @@
 /*============================================================================
 
 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 mitkLabelSetImageSerializer_h
-#define mitkLabelSetImageSerializer_h
+#ifndef mitkMultiLabelSegmentationSerializer_h
+#define mitkMultiLabelSegmentationSerializer_h
 
 #include "mitkBaseDataSerializer.h"
 
 namespace mitk
 {
   /**
   \brief Serializes mitk::LabelSetImage for mitk::SceneIO
   */
-  class LabelSetImageSerializer : public BaseDataSerializer
+  class MultiLabelSegmentationSerializer : public BaseDataSerializer
   {
   public:
-    mitkClassMacro(LabelSetImageSerializer, BaseDataSerializer);
+    mitkClassMacro(MultiLabelSegmentationSerializer, BaseDataSerializer);
     itkFactorylessNewMacro(Self);
     itkCloneMacro(Self);
     std::string Serialize() override;
 
   protected:
-    LabelSetImageSerializer();
-    ~LabelSetImageSerializer() override;
+    MultiLabelSegmentationSerializer();
+    ~MultiLabelSegmentationSerializer() override;
   };
 } // namespace
 
 #endif
diff --git a/Modules/Multilabel/autoload/IO/mitkMultilabelActivator.cpp b/Modules/Multilabel/autoload/IO/mitkMultilabelActivator.cpp
index 58201f45c4..237c838341 100644
--- a/Modules/Multilabel/autoload/IO/mitkMultilabelActivator.cpp
+++ b/Modules/Multilabel/autoload/IO/mitkMultilabelActivator.cpp
@@ -1,55 +1,59 @@
 /*============================================================================
 
 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 <usGetModuleContext.h>
 #include <usModule.h>
 #include <usModuleActivator.h>
 #include <usModuleContext.h>
 
-#include "mitkLabelSetImageIO.h"
+#include "mitkLegacyLabelSetImageIO.h"
+#include "mitkMultiLabelSegmentationIO.h"
 #include "mitkMultilabelIOMimeTypes.h"
 #include "mitkSegmentationTaskListIO.h"
 
 namespace mitk
 {
   /**
   \brief Registers services for multilabel module.
   */
   class MultilabelIOModuleActivator : public us::ModuleActivator
   {
     std::vector<AbstractFileIO *> m_FileIOs;
+    std::unique_ptr<IFileReader> m_LegacyLabelSetImageIOReader;
 
   public:
     void Load(us::ModuleContext *context) override
     {
       auto mimeTypes = MitkMultilabelIOMimeTypes::Get();
 
       us::ServiceProperties props;
       props[us::ServiceConstants::SERVICE_RANKING()] = 10;
 
       for (const auto &mimeType : mimeTypes)
         context->RegisterService(mimeType, props);
 
-      m_FileIOs.push_back(new LabelSetImageIO());
+      m_LegacyLabelSetImageIOReader = std::make_unique<LegacyLabelSetImageIO>();
+
+      m_FileIOs.push_back(new MultiLabelSegmentationIO());
       m_FileIOs.push_back(new SegmentationTaskListIO);
     }
     void Unload(us::ModuleContext *) override
     {
       for (auto &elem : m_FileIOs)
       {
         delete elem;
       }
     }
   };
 }
 
 US_EXPORT_MODULE_ACTIVATOR(mitk::MultilabelIOModuleActivator)
diff --git a/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.cpp b/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.cpp
index 231f8d4aed..aee9aa0727 100644
--- a/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.cpp
+++ b/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.cpp
@@ -1,75 +1,146 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkMultilabelIOMimeTypes.h"
 #include <mitkIOMimeTypes.h>
-
+#include <mitkLogMacros.h>
 #include <filesystem>
 #include <fstream>
 
 #include <nlohmann/json.hpp>
 
+#include <itkNrrdImageIO.h>
+#include "itkMetaDataObject.h"
+
 mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType::MitkSegmentationTaskListMimeType()
   : CustomMimeType(SEGMENTATIONTASKLIST_MIMETYPE_NAME())
 {
   this->AddExtension("json");
   this->SetCategory("MITK Segmentation Task List");
   this->SetComment("MITK Segmentation Task List");
 }
 
 bool mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType::AppliesTo(const std::string& path) const
 {
   bool result = CustomMimeType::AppliesTo(path);
 
   if (!std::filesystem::exists(path)) // T18572
     return result;
 
   std::ifstream file(path);
 
   if (!file.is_open())
     return false;
 
   auto json = nlohmann::json::parse(file, nullptr, false);
 
   if (json.is_discarded() || !json.is_object())
     return false;
 
   if ("MITK Segmentation Task List" != json.value("FileFormat", ""))
     return false;
 
   if (1 != json.value<int>("Version", 0))
     return false;
 
   return true;
 }
 
 mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType* mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType::Clone() const
 {
   return new MitkSegmentationTaskListMimeType(*this);
 }
 
 mitk::MitkMultilabelIOMimeTypes::MitkSegmentationTaskListMimeType mitk::MitkMultilabelIOMimeTypes::SEGMENTATIONTASKLIST_MIMETYPE()
 {
   return MitkSegmentationTaskListMimeType();
 }
 
 std::string mitk::MitkMultilabelIOMimeTypes::SEGMENTATIONTASKLIST_MIMETYPE_NAME()
 {
   return IOMimeTypes::DEFAULT_BASE_NAME() + ".segmentationtasklist";
 }
 
+mitk::MitkMultilabelIOMimeTypes::LegacyLabelSetMimeType::LegacyLabelSetMimeType()
+  : CustomMimeType(LEGACYLABELSET_MIMETYPE_NAME())
+{
+  this->AddExtension("nrrd");
+  this->SetCategory("MITK LabelSetImage");
+  this->SetComment("MITK LabelSetImage (legacy format)");
+}
+
+bool mitk::MitkMultilabelIOMimeTypes::LegacyLabelSetMimeType::AppliesTo(const std::string& path) const
+{
+  bool canRead = CustomMimeType::AppliesTo(path);
+
+  if (!std::filesystem::exists(path)) // T18572
+    return canRead;
+
+  if (!canRead)
+  {
+    return false;
+  }
+
+  std::string value("");
+  try
+  {
+    std::ifstream file(path);
+
+    if (!file.is_open())
+      return false;
+
+    itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
+    io->SetFileName(path);
+    io->ReadImageInformation();
+
+    itk::MetaDataDictionary imgMetaDataDictionary = io->GetMetaDataDictionary();
+    itk::ExposeMetaData<std::string>(imgMetaDataDictionary, "modality", value);
+  }
+  catch(const std::exception& e)
+  {
+    MITK_DEBUG << "Error while try to anylize NRRD file for LegacyLabelSetMimeType. File: " << path <<"; Error: " << e.what();
+  }
+  catch(...)
+  {
+    MITK_DEBUG << "Unkown error while try to anylize NRRD file for LegacyLabelSetMimeType. File: " << path;
+  }
+
+  if (value.compare("org.mitk.image.multilabel") != 0)
+  {
+    return false;
+  }
+
+  return true;
+}
+
+mitk::MitkMultilabelIOMimeTypes::LegacyLabelSetMimeType* mitk::MitkMultilabelIOMimeTypes::LegacyLabelSetMimeType::Clone() const
+{
+  return new LegacyLabelSetMimeType(*this);
+}
+
+mitk::MitkMultilabelIOMimeTypes::LegacyLabelSetMimeType mitk::MitkMultilabelIOMimeTypes::LEGACYLABELSET_MIMETYPE()
+{
+  return LegacyLabelSetMimeType();
+}
+
+std::string mitk::MitkMultilabelIOMimeTypes::LEGACYLABELSET_MIMETYPE_NAME()
+{
+  return IOMimeTypes::DEFAULT_BASE_NAME() + ".legacylabelsetimage";
+}
+
 std::vector<mitk::CustomMimeType*> mitk::MitkMultilabelIOMimeTypes::Get()
 {
   std::vector<CustomMimeType*> mimeTypes;
   mimeTypes.push_back(SEGMENTATIONTASKLIST_MIMETYPE().Clone());
+  mimeTypes.push_back(LEGACYLABELSET_MIMETYPE().Clone());
   return mimeTypes;
 }
diff --git a/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.h b/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.h
index 7343895f13..1f92d4692a 100644
--- a/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.h
+++ b/Modules/Multilabel/autoload/IO/mitkMultilabelIOMimeTypes.h
@@ -1,39 +1,51 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkMultilabelIOMimeTypes_h
 #define mitkMultilabelIOMimeTypes_h
 
 #include <mitkCustomMimeType.h>
 #include <MitkMultilabelIOExports.h>
 
 namespace mitk
 {
   namespace MitkMultilabelIOMimeTypes
   {
     class MITKMULTILABELIO_EXPORT MitkSegmentationTaskListMimeType : public CustomMimeType
     {
     public:
       MitkSegmentationTaskListMimeType();
 
       bool AppliesTo(const std::string& path) const override;
       MitkSegmentationTaskListMimeType* Clone() const override;
     };
 
     MITKMULTILABELIO_EXPORT MitkSegmentationTaskListMimeType SEGMENTATIONTASKLIST_MIMETYPE();
     MITKMULTILABELIO_EXPORT std::string SEGMENTATIONTASKLIST_MIMETYPE_NAME();
 
+    class MITKMULTILABELIO_EXPORT LegacyLabelSetMimeType : public CustomMimeType
+    {
+    public:
+      LegacyLabelSetMimeType();
+
+      bool AppliesTo(const std::string& path) const override;
+      LegacyLabelSetMimeType* Clone() const override;
+    };
+
+    MITKMULTILABELIO_EXPORT LegacyLabelSetMimeType LEGACYLABELSET_MIMETYPE();
+    MITKMULTILABELIO_EXPORT std::string LEGACYLABELSET_MIMETYPE_NAME();
+
     MITKMULTILABELIO_EXPORT std::vector<CustomMimeType*> Get();
   }
 }
 
 #endif