diff --git a/Modules/CEST/autoload/IO/CMakeLists.txt b/Modules/CEST/autoload/IO/CMakeLists.txt
index cb10fda5b5..0e9e46ddbb 100644
--- a/Modules/CEST/autoload/IO/CMakeLists.txt
+++ b/Modules/CEST/autoload/IO/CMakeLists.txt
@@ -1,6 +1,6 @@
 MITK_CREATE_MODULE( CESTIO
   DEPENDS MitkCEST MitkDICOMReader
   PACKAGE_DEPENDS
     PRIVATE ITK|ITKIOGDCM
-  AUTOLOAD_WITH MitkCore
+  AUTOLOAD_WITH MitkDICOMReader
 )
diff --git a/Modules/CEST/autoload/IO/mitkCESTGenericDICOMReaderService.cpp b/Modules/CEST/autoload/IO/mitkCESTGenericDICOMReaderService.cpp
index 7181193335..4c84f976c1 100644
--- a/Modules/CEST/autoload/IO/mitkCESTGenericDICOMReaderService.cpp
+++ b/Modules/CEST/autoload/IO/mitkCESTGenericDICOMReaderService.cpp
@@ -1,294 +1,397 @@
 /*============================================================================
 
 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 "mitkCESTGenericDICOMReaderService.h"
 
 #include "mitkIOMimeTypes.h"
 #include <mitkExtractCESTOffset.h>
 #include <mitkCustomTagParser.h>
 #include <mitkCESTPropertyHelper.h>
 #include <mitkDICOMDCMTKTagScanner.h>
 #include <mitkDICOMFileReaderSelector.h>
+#include <mitkDICOMProperty.h>
+
 #include "mitkCESTImageNormalizationFilter.h"
 
 #include "itksys/SystemTools.hxx"
 
 #include <usGetModuleContext.h>
 #include <usModuleContext.h>
 #include <usModuleResource.h>
 
 #include <boost/property_tree/json_parser.hpp>
 #include <boost/property_tree/ptree.hpp>
 
 namespace mitk
 {
+  DICOMTagPath DICOM_IMAGING_FREQUENCY_PATH()
+  {
+    return mitk::DICOMTagPath(0x0018, 0x0084);
+  }
+
+  std::string OPTION_NAME_B1()
+  {
+    return "B1 amplitude";
+  };
+  
+  std::string OPTION_NAME_PULSE()
+  {
+    return "Pulse duration [us]";
+  };
+  
+  std::string OPTION_NAME_DC()
+  {
+    return "Duty cycle [%]";
+  };
+  
+  std::string OPTION_NAME_NORMALIZE()
+  {
+    return "Normalize data";
+  };
+
+  std::string OPTION_NAME_NORMALIZE_AUTOMATIC()
+  {
+    return "Automatic";
+  };
+
+  std::string OPTION_NAME_NORMALIZE_NO()
+  {
+    return "No";
+  };
+
+  std::string OPTION_NAME_MERGE()
+  {
+    return "Merge all series";
+  };
+
+  std::string OPTION_NAME_MERGE_YES()
+  {
+    return "Yes";
+  };
+
+  std::string OPTION_NAME_MERGE_NO()
+  {
+    return "No";
+  };
+
   CESTDICOMManualReaderService::CESTDICOMManualReaderService(const CustomMimeType& mimeType, const std::string& description)
     : BaseDICOMReaderService(mimeType, description)
   {
     IFileIO::Options options;
-    options["B1 amplitude"] = 0.0;
-    options["CEST frequency [Hz]"] = 0.0;
-    options["Pulse duration [us]"] = 0.0;
-    options["Duty cycle [%]"] = 0.0;
+    options[OPTION_NAME_B1().c_str()] = 0.0;
+    options[OPTION_NAME_PULSE().c_str()] = 0.0;
+    options[OPTION_NAME_DC().c_str()] = 0.0;
     std::vector<std::string> normalizationStrategy;
-    normalizationStrategy.push_back("Automatic");
-    normalizationStrategy.push_back("No");
-    options["Normalize data"] = normalizationStrategy;
-
+    normalizationStrategy.push_back(OPTION_NAME_NORMALIZE_AUTOMATIC().c_str());
+    normalizationStrategy.push_back(OPTION_NAME_NORMALIZE_NO().c_str());
+    options[OPTION_NAME_NORMALIZE().c_str()] = normalizationStrategy;
+    std::vector<std::string> mergeStrategy;
+    mergeStrategy.push_back(OPTION_NAME_MERGE_NO().c_str());
+    mergeStrategy.push_back(OPTION_NAME_MERGE_YES().c_str());
+    options[OPTION_NAME_MERGE().c_str()] = mergeStrategy;
     this->SetDefaultOptions(options);
 
     this->RegisterService();
   }
 
   CESTDICOMManualReaderService::CESTDICOMManualReaderService(const mitk::CESTDICOMManualReaderService& other)
     : BaseDICOMReaderService(other)
   {
   }
 
   void ExtractOptionFromPropertyTree(const std::string& key, boost::property_tree::ptree& root, std::map<std::string, us::Any>& options)
   {
     auto finding = root.find(key);
     if (finding != root.not_found())
     {
-      options[key] = finding->second.get_value<double>();
+      try
+      {
+        options[key] = finding->second.get_value<double>();
+      }
+      catch (const boost::property_tree::ptree_bad_data & /*e*/)
+      {
+        options[key] = finding->second.get_value<std::string>();
+      }
     }
   }
 
   IFileIO::Options ExtractOptionsFromFile(const std::string& file)
   {
     boost::property_tree::ptree root;
 
     if (itksys::SystemTools::FileExists(file))
     {
       try
       {
         boost::property_tree::read_json(file, root, std::locale("C"));
       }
       catch (const boost::property_tree::json_parser_error & e)
       {
         MITK_WARN << "Could not parse CEST meta file. Fall back to default values. Error was:\n" << e.what();
       }
     }
     else
     {
       MITK_DEBUG << "CEST meta file does not exist. Fall back to default values. CEST meta file path: " << file;
     }
 
     IFileIO::Options options;
-    ExtractOptionFromPropertyTree(CEST_PROPERTY_NAME_FREQ(),root, options);
     ExtractOptionFromPropertyTree(CEST_PROPERTY_NAME_B1Amplitude(), root, options);
     ExtractOptionFromPropertyTree(CEST_PROPERTY_NAME_PULSEDURATION(), root, options);
     ExtractOptionFromPropertyTree(CEST_PROPERTY_NAME_DutyCycle(), root, options);
     ExtractOptionFromPropertyTree(CEST_PROPERTY_NAME_OFFSETS(), root, options);
     ExtractOptionFromPropertyTree(CEST_PROPERTY_NAME_TREC(), root, options);
+    ExtractOptionFromPropertyTree("CEST.MergeAllSeries", root, options);
 
     return options;
   }
 
   void TransferOption(const mitk::IFileIO::Options& sourceOptions, const std::string& sourceName, mitk::IFileIO::Options& options, const std::string& newName)
   {
     auto sourceFinding = sourceOptions.find(sourceName);
     auto finding = options.find(newName);
 
     bool replaceValue = finding == options.end();
     if (!replaceValue)
     {
       replaceValue = us::any_cast<double>(finding->second) == 0.;
     }
 
     if (sourceFinding != sourceOptions.end() && us::any_cast<double>(sourceFinding->second) != 0. && replaceValue)
     {
       options[newName] = sourceFinding->second;
     }
   }
   
+  void TransferMergeOption(const mitk::IFileIO::Options& sourceOptions, const std::string& sourceName, mitk::IFileIO::Options& options, const std::string& newName)
+  {
+    auto sourceFinding = sourceOptions.find(sourceName);
+    auto finding = options.find(newName);
+
+    bool replaceValue = finding == options.end();
+    if (!replaceValue)
+    {
+      try
+      {
+        us::any_cast<std::string>(finding->second);
+      }
+      catch (const us::BadAnyCastException& /*e*/)
+      {
+        replaceValue = true;
+        //if we cannot cast in string the user has not make a selection yet
+      }
+    }
+
+    if (sourceFinding != sourceOptions.end() && us::any_cast<std::string>(sourceFinding->second) != OPTION_NAME_MERGE_NO() && replaceValue)
+    {
+      options[newName] = sourceFinding->second;
+    }
+  }
+
   std::string CESTDICOMManualReaderService::GetCESTMetaFilePath() const
   {
     auto dir = itksys::SystemTools::GetFilenamePath(this->GetInputLocation());
     std::string metafile = dir + "/" + "CEST_META.json";
     return metafile;
   }
 
   std::string CESTDICOMManualReaderService::GetTRECFilePath() const
   {
     auto dir = itksys::SystemTools::GetFilenamePath(this->GetInputLocation());
     std::string metafile = dir + "/" + "TREC.txt";
     return metafile;
   }
 
   std::string CESTDICOMManualReaderService::GetLISTFilePath() const
   {
     auto dir = itksys::SystemTools::GetFilenamePath(this->GetInputLocation());
     std::string metafile = dir + "/" + "LIST.txt";
     return metafile;
   }
 
 
   IFileIO::Options CESTDICOMManualReaderService::GetOptions() const
   {
     auto options = AbstractFileReader::GetOptions();
     if (!this->GetInputLocation().empty())
     {
       auto fileOptions = ExtractOptionsFromFile(this->GetCESTMetaFilePath());
 
-      TransferOption(fileOptions, CEST_PROPERTY_NAME_FREQ(), options, "CEST frequency [Hz]");
-      TransferOption(fileOptions, CEST_PROPERTY_NAME_B1Amplitude(), options, "B1 amplitude");
-      TransferOption(fileOptions, CEST_PROPERTY_NAME_PULSEDURATION(), options, "Pulse duration [us]");
-      TransferOption(fileOptions, CEST_PROPERTY_NAME_DutyCycle(), options, "Duty cycle [%]");
+      TransferOption(fileOptions, CEST_PROPERTY_NAME_B1Amplitude(), options, OPTION_NAME_B1());
+      TransferOption(fileOptions, CEST_PROPERTY_NAME_PULSEDURATION(), options, OPTION_NAME_PULSE());
+      TransferOption(fileOptions, CEST_PROPERTY_NAME_DutyCycle(), options, OPTION_NAME_DC());
+      TransferMergeOption(fileOptions, "CEST.MergeAllSeries", options, OPTION_NAME_MERGE());
     }
     return options;
   }
 
   us::Any CESTDICOMManualReaderService::GetOption(const std::string& name) const
   {
     this->GetOptions(); //ensure (default) options are set.
     return AbstractFileReader::GetOption(name);
   }
 
   DICOMFileReader::Pointer CESTDICOMManualReaderService::GetReader(const mitk::StringList& relevantFiles) const
   {
     mitk::DICOMFileReaderSelector::Pointer selector = mitk::DICOMFileReaderSelector::New();
 
+    const std::string mergeStrategy = this->GetOption(OPTION_NAME_MERGE()).ToString();
+
+    if (mergeStrategy == OPTION_NAME_MERGE_YES())
+    {
+      auto r = ::us::GetModuleContext()->GetModule()->GetResource("cest_DKFZ.xml");
+      selector->AddConfigFromResource(r);
+    }
+
     selector->LoadBuiltIn3DnTConfigs();
     selector->SetInputFiles(relevantFiles);
 
     mitk::DICOMFileReader::Pointer reader = selector->GetFirstReaderWithMinimumNumberOfOutputImages();
     if (reader.IsNotNull())
     {
       //reset tag cache to ensure that additional tags of interest
       //will be regarded by the reader if set later on.
       reader->SetTagCache(nullptr);
     }
 
     return reader;
   };
 
   std::vector<itk::SmartPointer<BaseData>> CESTDICOMManualReaderService::Read()
   {
+    const Options userOptions = this->GetOptions();
+
+    const std::string mergeStrategy = userOptions.find(OPTION_NAME_MERGE())->second.ToString();
+    this->SetOnlyRegardOwnSeries(mergeStrategy != OPTION_NAME_MERGE_YES());
+
     std::vector<BaseData::Pointer> result;
     std::vector<BaseData::Pointer> dicomResult = BaseDICOMReaderService::Read();
 
-    const Options userOptions = this->GetOptions();
-
-    const std::string normalizationStrategy = userOptions.find("Normalize data")->second.ToString();
+    const std::string normalizationStrategy = userOptions.find(OPTION_NAME_NORMALIZE())->second.ToString();
 
     for (auto &item : dicomResult)
     {
       auto fileOptions = ExtractOptionsFromFile(this->GetCESTMetaFilePath());
       IFileIO::Options options;
-      TransferOption(userOptions, "CEST frequency [Hz]", options, CEST_PROPERTY_NAME_FREQ());
-      TransferOption(userOptions, "B1 amplitude", options, CEST_PROPERTY_NAME_B1Amplitude());
-      TransferOption(userOptions, "Pulse duration [us]", options, CEST_PROPERTY_NAME_PULSEDURATION());
-      TransferOption(userOptions, "Duty cycle [%]", options, CEST_PROPERTY_NAME_DutyCycle());
-      TransferOption(fileOptions, CEST_PROPERTY_NAME_FREQ(), options, CEST_PROPERTY_NAME_FREQ());
+      TransferOption(userOptions, OPTION_NAME_B1(), options, CEST_PROPERTY_NAME_B1Amplitude());
+      TransferOption(userOptions, OPTION_NAME_PULSE(), options, CEST_PROPERTY_NAME_PULSEDURATION());
+      TransferOption(userOptions, OPTION_NAME_DC(), options, CEST_PROPERTY_NAME_DutyCycle());
       TransferOption(fileOptions, CEST_PROPERTY_NAME_B1Amplitude(), options, CEST_PROPERTY_NAME_B1Amplitude());
       TransferOption(fileOptions, CEST_PROPERTY_NAME_PULSEDURATION(), options, CEST_PROPERTY_NAME_PULSEDURATION());
       TransferOption(fileOptions, CEST_PROPERTY_NAME_DutyCycle(), options, CEST_PROPERTY_NAME_DutyCycle());
 
       TransferOption(fileOptions, CEST_PROPERTY_NAME_OFFSETS(), options, CEST_PROPERTY_NAME_OFFSETS());
       TransferOption(fileOptions, CEST_PROPERTY_NAME_TREC(), options, CEST_PROPERTY_NAME_TREC());
 
       auto trecValues = CustomTagParser::ReadListFromFile(this->GetTRECFilePath());
       auto offsetValues = CustomTagParser::ReadListFromFile(this->GetLISTFilePath());
 
       bool isCEST = !offsetValues.empty();
       bool isT1 = !trecValues.empty();
 
       if (!isCEST && !isT1)
       {//check if there are settings in the metafile
         auto finding = fileOptions.find(CEST_PROPERTY_NAME_OFFSETS());
         if (finding != fileOptions.end())
         {
           isCEST = true;
           offsetValues = finding->second.ToString();
         };
 
         finding = fileOptions.find(CEST_PROPERTY_NAME_TREC());
         if (finding != fileOptions.end())
         {
           isT1 = true;
           trecValues = finding->second.ToString();
         };
       }
 
       if (isCEST)
       {
         MITK_INFO << "CEST image detected due to LIST.txt or offset property in CEST_META.json";
         options[CEST_PROPERTY_NAME_OFFSETS()] = offsetValues;
       }
       else if (isT1)
       {
         MITK_INFO << "T1 image detected due to TREC.txt or trec property in CEST_META.json";
         options[CEST_PROPERTY_NAME_TREC()] = trecValues;
       }
       else
       {
         mitkThrow() << "Cannot load CEST/T1 file. No CEST offsets or T1 trec values specified. LIST.txt/TREC.txt or information in CEST_META.json is missing.";
       }
 
       for (const auto& option : options)
       {
         item->GetPropertyList()->SetStringProperty(option.first.c_str(), option.second.ToString().c_str());
       }
 
+      auto freqProp = item->GetProperty(mitk::DICOMTagPathToPropertyName(DICOM_IMAGING_FREQUENCY_PATH()).c_str());
+
+      if (freqProp.IsNull())
+      {
+        mitkThrow() << "Loaded image in invalid state. Does not contain the DICOM Imaging Frequency tag.";
+      }
+      SetCESTFrequencyMHz(item, mitk::ConvertDICOMStrToValue<double>(freqProp->GetValueAsString()));
+
       auto image = dynamic_cast<mitk::Image*>(item.GetPointer());
 
       if (isCEST)
       {
         try
         {
           auto offsets = ExtractCESTOffset(image);
         }
         catch (...)
         {
           mitkThrow() << "Cannot load CEST file. Number of CEST offsets do not equal the number of image time steps. Image time steps: " << image->GetTimeSteps() << "; offset values: " << offsetValues;
         }
       }
       else if (isT1)
       {
         try
         {
           auto t1s = ExtractCESTT1Time(image);
         }
         catch (...)
         {
           mitkThrow() << "Cannot load T1 file. Number of T1 times do not equal the number of image time steps. Image time steps: " << image->GetTimeSteps() << "; T1 values: " << trecValues;
         }
       }
 
-      if (normalizationStrategy == "Automatic" && mitk::IsNotNormalizedCESTImage(image))
+      if (normalizationStrategy == OPTION_NAME_NORMALIZE_AUTOMATIC() && mitk::IsNotNormalizedCESTImage(image))
       {
         MITK_INFO << "Unnormalized CEST image was loaded and will be normalized automatically.";
         auto normalizationFilter = mitk::CESTImageNormalizationFilter::New();
         normalizationFilter->SetInput(image);
         normalizationFilter->Update();
         auto normalizedImage = normalizationFilter->GetOutput();
 
         auto nameProp = item->GetProperty("name");
         if (!nameProp)
         {
           mitkThrow() << "Cannot load CEST file. Property \"name\" is missing after BaseDICOMReaderService::Read().";
         }
         normalizedImage->SetProperty("name", mitk::StringProperty::New(nameProp->GetValueAsString() + "_normalized"));
         result.push_back(normalizedImage);
       }
       else
       {
         result.push_back(item);
       }
     }
 
     return result;
   }
 
   CESTDICOMManualReaderService *CESTDICOMManualReaderService::Clone() const { return new CESTDICOMManualReaderService(*this); }
 }
diff --git a/Modules/CEST/autoload/IO/mitkCESTGenericDICOMReaderService.h b/Modules/CEST/autoload/IO/mitkCESTGenericDICOMReaderService.h
index 46b2a6321f..33757deafe 100644
--- a/Modules/CEST/autoload/IO/mitkCESTGenericDICOMReaderService.h
+++ b/Modules/CEST/autoload/IO/mitkCESTGenericDICOMReaderService.h
@@ -1,51 +1,52 @@
 /*============================================================================
 
 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 MITKCESTGenericDICOMReaderService_H
 #define MITKCESTGenericDICOMReaderService_H
 
 #include <mitkBaseDICOMReaderService.h>
 
 namespace mitk {
 
   /**
   Service wrapper that auto selects (using the mitk::DICOMFileReaderSelector) the best DICOMFileReader from
   the DICOMReader module and loads the CEST relevant meta data from a provided cest_meta.json file or
   provided from the user as reader options.
   */
   class CESTDICOMManualReaderService : public BaseDICOMReaderService
   {
   public:
     CESTDICOMManualReaderService(const CustomMimeType& mimeType, const std::string& description);
     CESTDICOMManualReaderService(const mitk::CESTDICOMManualReaderService& other);
 
     /** Uses the AbstractFileReader Read function and add extra steps for CEST meta data */
     using AbstractFileReader::Read;
     std::vector<itk::SmartPointer<BaseData> > Read() override;
 
     Options GetOptions() const override;
     us::Any GetOption(const std::string& name) const override;
 
   protected:
     std::string GetCESTMetaFilePath() const;
     std::string GetTRECFilePath() const;
     std::string GetLISTFilePath() const;
 
     mitk::DICOMFileReader::Pointer GetReader(const mitk::StringList& relevantFiles) const override;
   private:
 
     CESTDICOMManualReaderService* Clone() const override;
   };
 
+  DICOMTagPath DICOM_IMAGING_FREQUENCY_PATH();
 }
 
 #endif // MITKCESTGenericDICOMReaderService_H
diff --git a/Modules/CEST/autoload/IO/mitkCESTIOActivator.cpp b/Modules/CEST/autoload/IO/mitkCESTIOActivator.cpp
index 78e7955706..fd293302d9 100644
--- a/Modules/CEST/autoload/IO/mitkCESTIOActivator.cpp
+++ b/Modules/CEST/autoload/IO/mitkCESTIOActivator.cpp
@@ -1,56 +1,103 @@
 /*============================================================================
 
 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 "mitkCESTIOActivator.h"
 
 #include "mitkCESTDICOMReaderService.h"
 #include "mitkCESTGenericDICOMReaderService.h"
 
 #include <usModuleContext.h>
+#include <mitkDICOMIOHelper.h>
 
 #include "mitkCESTIOMimeTypes.h"
 
+#include <mutex>
+
 namespace mitk
 {
   void CESTIOActivator::Load(us::ModuleContext *context)
   {
     us::ServiceProperties props;
     props[us::ServiceConstants::SERVICE_RANKING()] = 10;
 
     m_MimeTypes = mitk::MitkCESTIOMimeTypes::Get();
     for (auto& mimeType : m_MimeTypes)
     {
       if (mimeType->GetName() == mitk::MitkCESTIOMimeTypes::CEST_DICOM_WITHOUT_META_FILE_NAME())
       { // "w/o meta" mimetype should only registered with low priority.
         context->RegisterService(mimeType);
       }
       else
       {
         context->RegisterService(mimeType, props);
       }
     }
 
     m_CESTDICOMReader.reset(new CESTDICOMReaderService());
     m_CESTDICOMManualWithMetaFileReader.reset(new CESTDICOMManualReaderService(MitkCESTIOMimeTypes::CEST_DICOM_WITH_META_FILE_MIMETYPE(), "CEST DICOM Manual Reader"));
     m_CESTDICOMManualWithOutMetaFileReader.reset(new CESTDICOMManualReaderService(MitkCESTIOMimeTypes::CEST_DICOM_WITHOUT_META_FILE_MIMETYPE(), "CEST DICOM Manual Reader"));
+
+    m_Context = context;
+    {
+      std::lock_guard<std::mutex> lock(m_Mutex);
+      // Listen for events pertaining to dictionary services.
+      m_Context->AddServiceListener(this, &CESTIOActivator::DICOMTagsOfInterestServiceChanged,
+        std::string("(&(") + us::ServiceConstants::OBJECTCLASS() + "=" +
+        us_service_interface_iid<IDICOMTagsOfInterest>() + "))");
+      // Query for any service references matching any language.
+      std::vector<us::ServiceReference<IDICOMTagsOfInterest> > refs =
+        context->GetServiceReferences<IDICOMTagsOfInterest>();
+      if (!refs.empty())
+      {
+        for (auto ref : refs)
+        {
+          this->RegisterTagsOfInterest(m_Context->GetService(ref));
+          m_Context->UngetService(ref);
+        }
+      }
+    }
+
+    IDICOMTagsOfInterest* toiService = mitk::GetDicomTagsOfInterestService();
   }
 
   void CESTIOActivator::Unload(us::ModuleContext *)
   {
     for (auto& elem : m_MimeTypes)
     {
       delete elem;
     }
   }
+
+  void CESTIOActivator::RegisterTagsOfInterest(IDICOMTagsOfInterest* toiService) const
+  {
+    if (toiService != nullptr)
+    {
+      toiService->AddTagOfInterest(mitk::DICOM_IMAGING_FREQUENCY_PATH());
+    }
+  }
+
+  void CESTIOActivator::DICOMTagsOfInterestServiceChanged(const us::ServiceEvent event)
+  {
+    std::lock_guard<std::mutex> lock(m_Mutex);
+    // If a dictionary service was registered, see if we
+    // need one. If so, get a reference to it.
+    if (event.GetType() == us::ServiceEvent::REGISTERED)
+    {
+        // Get a reference to the service object.
+        us::ServiceReference<IDICOMTagsOfInterest> ref = event.GetServiceReference();
+        this->RegisterTagsOfInterest(m_Context->GetService(ref));
+        m_Context->UngetService(ref);
+    }
+  }
 }
 
 US_EXPORT_MODULE_ACTIVATOR(mitk::CESTIOActivator)
diff --git a/Modules/CEST/autoload/IO/mitkCESTIOActivator.h b/Modules/CEST/autoload/IO/mitkCESTIOActivator.h
index 4c34dc8a6c..5c19a699b0 100644
--- a/Modules/CEST/autoload/IO/mitkCESTIOActivator.h
+++ b/Modules/CEST/autoload/IO/mitkCESTIOActivator.h
@@ -1,42 +1,53 @@
 /*============================================================================
 
 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 MITKCESTIOActivator_H
 #define MITKCESTIOActivator_H
 
 #include <mitkCustomMimeType.h>
+#include <mitkIDICOMTagsOfInterest.h>
 
 #include <usModuleActivator.h>
 #include <usServiceEvent.h>
 
 #include <memory>
+#include <mutex>
 
 namespace mitk
 {
   struct IFileReader;
   class IDICOMTagsOfInterest;
 
   class CESTIOActivator : public us::ModuleActivator
   {
   public:
     void Load(us::ModuleContext *context) override;
     void Unload(us::ModuleContext *context) override;
 
+
   private:
+    void RegisterTagsOfInterest(IDICOMTagsOfInterest* toiService) const;
+    void DICOMTagsOfInterestServiceChanged(const us::ServiceEvent event);
+
     std::unique_ptr<IFileReader> m_CESTDICOMReader;
     std::unique_ptr<IFileReader> m_CESTDICOMManualWithMetaFileReader;
     std::unique_ptr<IFileReader> m_CESTDICOMManualWithOutMetaFileReader;
     std::vector<mitk::CustomMimeType *> m_MimeTypes;
+
+    // Module context
+    us::ModuleContext* m_Context;
+    /**mutex to guard the service listening */
+    std::mutex m_Mutex;
   };
 }
 
 #endif // MITKCESTIOActivator_H
diff --git a/Modules/CEST/include/mitkCESTPropertyHelper.h b/Modules/CEST/include/mitkCESTPropertyHelper.h
index bb7fba5d84..f23f9140b1 100644
--- a/Modules/CEST/include/mitkCESTPropertyHelper.h
+++ b/Modules/CEST/include/mitkCESTPropertyHelper.h
@@ -1,54 +1,60 @@
 /*============================================================================
 
 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 __CEST_PROERTY_HELPER_H
 #define __CEST_PROERTY_HELPER_H
 
 #include "mitkIPropertyProvider.h"
+#include "mitkIPropertyOwner.h"
 
 #include "MitkCESTExports.h"
 
 namespace mitk
 {
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_PREPERATIONTYPE();
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_RECOVERYMODE();
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_SPOILINGTYPE();
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_OFFSETS();
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_TREC();
 
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_FREQ();
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_PULSEDURATION();
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_B1Amplitude();
   const std::string MITKCEST_EXPORT CEST_PROPERTY_NAME_DutyCycle();
 
   /**Helper function that gets the CEST B1 amplitude property ("CEST.B1Amplitude") from the passed property provider.
   If it is not possible to generate/get the value an mitk::Exception will be thrown.*/
   double MITKCEST_EXPORT GetCESTB1Amplitude(const IPropertyProvider* provider);
 
   /**Helper function that gets the CEST frequency property ("CEST.FREQ") from the input image.
   If it is not possible to generate/get the value an mitk::Exception will be thrown.
   The value is returned in [MHz]. Normally in the property it is stored in [Hz].*/
   double MITKCEST_EXPORT GetCESTFrequency(const IPropertyProvider* provider);
 
+  /**Helper function that sets the CEST frequency property ("CEST.FREQ") in the passed owner.
+  If it owner is nullptr nothing will be done.
+  The value is passed in [MHz] and set in the property in [Hz].*/
+  void MITKCEST_EXPORT SetCESTFrequencyMHz(IPropertyOwner* owner, double freqInMHz);
+
   /**Helper function that gets the CEST pulse duration property ("CEST.PulseDuration") from the input image.
   If it is not possible to generate/get the value an mitk::Exception will be thrown.
   The value is returned in [s]. Normally in the property it is stored in micro secs.*/
   double MITKCEST_EXPORT GetCESTPulseDuration(const IPropertyProvider* provider);
 
   /**Helper function that gets the CEST duty cycle property ("CEST.DutyCycle") from the input image.
   If it is not possible to generate/get the value an mitk::Exception will be thrown.
   The value is returned as scaling factor (1 == 100%), in contrast to the porperty where it is stored as
   a percentage value (e.g. 56 %, so the function return will be 0.56).*/
   double MITKCEST_EXPORT GetCESTDutyCycle(const IPropertyProvider* provider);
 }
 
 #endif // __CEST_PROERTY_HELPER_H
diff --git a/Modules/CEST/src/mitkCESTPropertyHelper.cpp b/Modules/CEST/src/mitkCESTPropertyHelper.cpp
index db92cbb338..f6c154afb4 100644
--- a/Modules/CEST/src/mitkCESTPropertyHelper.cpp
+++ b/Modules/CEST/src/mitkCESTPropertyHelper.cpp
@@ -1,137 +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 "mitkCESTPropertyHelper.h"
 
 #include "mitkDICOMProperty.h"
+#include "mitkStringProperty.h"
 
 const std::string mitk::CEST_PROPERTY_NAME_PREPERATIONTYPE()
 {
   return "CEST.PreparationType";
-};
+}
 
 const std::string mitk::CEST_PROPERTY_NAME_RECOVERYMODE()
 {
   return "CEST.RecoveryMode";
-};
+}
 
 const std::string mitk::CEST_PROPERTY_NAME_SPOILINGTYPE()
 {
   return "CEST.SpoilingType";
-};
+}
 
 const std::string mitk::CEST_PROPERTY_NAME_OFFSETS()
 {
   return "CEST.Offsets";
-};
+}
 
 const std::string mitk::CEST_PROPERTY_NAME_TREC()
 {
   return std::string("CEST.TREC");
 }
 
 const std::string mitk::CEST_PROPERTY_NAME_FREQ()
 {
   return std::string("CEST.FREQ");
 }
 
 const std::string mitk::CEST_PROPERTY_NAME_PULSEDURATION()
 {
   return std::string("CEST.PulseDuration");
 }
 
 const std::string mitk::CEST_PROPERTY_NAME_B1Amplitude()
 {
   return std::string("CEST.B1Amplitude");
 }
 
 const std::string mitk::CEST_PROPERTY_NAME_DutyCycle()
 {
   return std::string("CEST.DutyCycle");
 }
 
 
 double mitk::GetCESTB1Amplitude(const IPropertyProvider* provider)
 {
   if (!provider)
   {
     mitkThrow() << "Cannot determine B! amplitude. Passed property provider is invalid.";
   }
 
   double result = 0.0;
 
   auto prop = provider->GetConstProperty(CEST_PROPERTY_NAME_B1Amplitude().c_str());
   if (prop.IsNotNull())
   {
     result = mitk::ConvertDICOMStrToValue<double>(prop->GetValueAsString());
   }
   else mitkThrow() << "Cannot determine B! amplitude. Selected input has no property \"" << CEST_PROPERTY_NAME_B1Amplitude << "\"";
 
   return result;
 }
 
 double mitk::GetCESTFrequency(const IPropertyProvider* provider)
 {
   if (!provider)
   {
     mitkThrow() << "Cannot determine frequency. Passed property provider is invalid.";
   }
 
   double result = 0.0;
 
   auto prop = provider->GetConstProperty(CEST_PROPERTY_NAME_FREQ().c_str());
   if (prop.IsNotNull())
   {
     result = mitk::ConvertDICOMStrToValue<double>(prop->GetValueAsString()) * 0.000001;
   }
   else mitkThrow() << "Cannot determine frequency. Selected input has no property \"" << CEST_PROPERTY_NAME_FREQ << "\"";
 
   return result;
-};
+}
+
+void mitk::SetCESTFrequencyMHz(IPropertyOwner* owner, double freqInMHz)
+{
+  if (nullptr != owner)
+  {
+    owner->SetProperty(CEST_PROPERTY_NAME_FREQ().c_str(), mitk::StringProperty::New(ConvertValueToDICOMStr(freqInMHz * 1000000)));
+  }
+}
 
 double mitk::GetCESTPulseDuration(const IPropertyProvider* provider)
 {
   if (!provider)
   {
     mitkThrow() << "Cannot determine pulse duration. Passed property provider is invalid.";
   }
 
   double result = 0.0;
 
   auto prop = provider->GetConstProperty(CEST_PROPERTY_NAME_PULSEDURATION().c_str());
   if (prop.IsNotNull())
   {
     result = mitk::ConvertDICOMStrToValue<double>(prop->GetValueAsString()) * 0.000001;
   }
   else mitkThrow() << "Cannot determine pulse duration. Selected input has no property \"" << CEST_PROPERTY_NAME_PULSEDURATION << "\"";
 
   return result;
-};
+}
 
 double mitk::GetCESTDutyCycle(const IPropertyProvider* provider)
 {
   if (!provider)
   {
     mitkThrow() << "Cannot determine duty cycle. Passed property provider is invalid.";
   }
 
   double result = 0.0;
 
   auto prop = provider->GetConstProperty(CEST_PROPERTY_NAME_DutyCycle().c_str());
   if (prop.IsNotNull())
   {
     result = mitk::ConvertDICOMStrToValue<double>(prop->GetValueAsString()) * 0.01;
   }
   else mitkThrow() << "Cannot determine duty cycle. Selected input has no property \"" << CEST_PROPERTY_NAME_DutyCycle << "\"";
 
   return result;
-};
+}
diff --git a/Modules/Core/src/IO/mitkIOMimeTypes.cpp b/Modules/Core/src/IO/mitkIOMimeTypes.cpp
index 801bde5c04..ad668de0d3 100644
--- a/Modules/Core/src/IO/mitkIOMimeTypes.cpp
+++ b/Modules/Core/src/IO/mitkIOMimeTypes.cpp
@@ -1,363 +1,363 @@
 /*============================================================================
 
 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 "mitkIOMimeTypes.h"
 
 #include "mitkCustomMimeType.h"
 #include "mitkLogMacros.h"
 
 #include "itkGDCMImageIO.h"
 #include "itkMetaDataObject.h"
 
 #include <itksys/SystemTools.hxx>
 #include <itksys/Directory.hxx>
 
 namespace mitk
 {
   IOMimeTypes::BaseDicomMimeType::BaseDicomMimeType(const std::string& name) : CustomMimeType(name)
   {
     this->AddExtension("gdcm");
     this->AddExtension("dcm");
     this->AddExtension("DCM");
     this->AddExtension("dc3");
     this->AddExtension("DC3");
     this->AddExtension("ima");
     this->AddExtension("img");
 
     this->SetCategory(CATEGORY_IMAGES());
     this->SetComment("DICOM");
   }
 
   IOMimeTypes::BaseDicomMimeType::BaseDicomMimeType(const BaseDicomMimeType& other) : CustomMimeType(other.GetName())
   {
   }
 
   bool IOMimeTypes::BaseDicomMimeType::AppliesTo(const std::string &path) const
   {
     // check whether directory or file
     // if directory try to find first file within it instead
     bool pathIsDirectory = itksys::SystemTools::FileIsDirectory(path);
 
     std::string filepath = path;
 
     if (pathIsDirectory)
     {
       itksys::Directory input;
       input.Load(path.c_str());
 
       std::vector<std::string> files;
       for (unsigned long idx = 0; idx<input.GetNumberOfFiles(); idx++)
       {
         if (!itksys::SystemTools::FileIsDirectory(input.GetFile(idx)))
         {
           std::string fullpath = path + "/" + std::string(input.GetFile(idx));
           files.push_back(fullpath.c_str());
         }
       }
       filepath = files.front();
     }
 
     // Ask the GDCM ImageIO class directly
     itk::GDCMImageIO::Pointer gdcmIO = itk::GDCMImageIO::New();
     gdcmIO->SetFileName(filepath);
     try {
       gdcmIO->ReadImageInformation();
     }
     catch (const itk::ExceptionObject & /*err*/) {
       return false;
     }
 
     //DICOMRT modalities have specific reader, don't read with normal DICOM readers
     std::string modality;
     itk::MetaDataDictionary& dict = gdcmIO->GetMetaDataDictionary();
     itk::ExposeMetaData<std::string>(dict, "0008|0060", modality);
-    MITK_INFO << "DICOM Modality is " << modality;
+    MITK_DEBUG << "DICOM Modality detected by MimeType "<< this->GetName() << " is " << modality;
     if (modality == "RTSTRUCT" || modality == "RTDOSE" || modality == "RTPLAN") {
       return false;
     }
     else {
       return gdcmIO->CanReadFile(filepath.c_str());
     }
   }
 
   IOMimeTypes::BaseDicomMimeType*IOMimeTypes::BaseDicomMimeType::Clone() const { return new BaseDicomMimeType(*this); }
 
   IOMimeTypes::DicomMimeType::DicomMimeType() : BaseDicomMimeType(DICOM_MIMETYPE_NAME())
   {
   }
 
   IOMimeTypes::DicomMimeType* IOMimeTypes::DicomMimeType::Clone() const { return new DicomMimeType(*this); }
 
   std::vector<CustomMimeType *> IOMimeTypes::Get()
   {
     std::vector<CustomMimeType *> mimeTypes;
 
     // order matters here (descending rank for mime types)
 
     mimeTypes.push_back(NRRD_MIMETYPE().Clone());
     mimeTypes.push_back(NIFTI_MIMETYPE().Clone());
 
     mimeTypes.push_back(VTK_IMAGE_MIMETYPE().Clone());
     mimeTypes.push_back(VTK_PARALLEL_IMAGE_MIMETYPE().Clone());
     mimeTypes.push_back(VTK_IMAGE_LEGACY_MIMETYPE().Clone());
 
     mimeTypes.push_back(DICOM_MIMETYPE().Clone());
 
     mimeTypes.push_back(VTK_POLYDATA_MIMETYPE().Clone());
     mimeTypes.push_back(VTK_PARALLEL_POLYDATA_MIMETYPE().Clone());
     mimeTypes.push_back(VTK_POLYDATA_LEGACY_MIMETYPE().Clone());
 
     mimeTypes.push_back(STEREOLITHOGRAPHY_MIMETYPE().Clone());
     mimeTypes.push_back(WAVEFRONT_OBJ_MIMETYPE().Clone());
     mimeTypes.push_back(STANFORD_PLY_MIMETYPE().Clone());
 
     mimeTypes.push_back(RAW_MIMETYPE().Clone());
     mimeTypes.push_back(POINTSET_MIMETYPE().Clone());
     return mimeTypes;
   }
 
   CustomMimeType IOMimeTypes::VTK_IMAGE_MIMETYPE()
   {
     CustomMimeType mimeType(VTK_IMAGE_NAME());
     mimeType.AddExtension("vti");
     mimeType.SetCategory(CATEGORY_IMAGES());
     mimeType.SetComment("VTK Image");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::VTK_IMAGE_LEGACY_MIMETYPE()
   {
     CustomMimeType mimeType(VTK_IMAGE_LEGACY_NAME());
     mimeType.AddExtension("vtk");
     mimeType.SetCategory(CATEGORY_IMAGES());
     mimeType.SetComment("VTK Legacy Image");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::VTK_PARALLEL_IMAGE_MIMETYPE()
   {
     CustomMimeType mimeType(VTK_PARALLEL_IMAGE_NAME());
     mimeType.AddExtension("pvti");
     mimeType.SetCategory(CATEGORY_IMAGES());
     mimeType.SetComment("VTK Parallel Image");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::VTK_POLYDATA_MIMETYPE()
   {
     CustomMimeType mimeType(VTK_POLYDATA_NAME());
     mimeType.AddExtension("vtp");
     mimeType.SetCategory(CATEGORY_SURFACES());
     mimeType.SetComment("VTK PolyData");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::VTK_POLYDATA_LEGACY_MIMETYPE()
   {
     CustomMimeType mimeType(VTK_POLYDATA_LEGACY_NAME());
     mimeType.AddExtension("vtk");
     mimeType.SetCategory(CATEGORY_SURFACES());
     mimeType.SetComment("VTK Legacy PolyData");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::VTK_PARALLEL_POLYDATA_MIMETYPE()
   {
     CustomMimeType mimeType(VTK_PARALLEL_POLYDATA_NAME());
     mimeType.AddExtension("pvtp");
     mimeType.SetCategory(CATEGORY_SURFACES());
     mimeType.SetComment("VTK Parallel PolyData");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::STEREOLITHOGRAPHY_MIMETYPE()
   {
     CustomMimeType mimeType(STEREOLITHOGRAPHY_NAME());
     mimeType.AddExtension("stl");
     mimeType.SetCategory(CATEGORY_SURFACES());
     mimeType.SetComment("Stereolithography");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::WAVEFRONT_OBJ_MIMETYPE()
   {
     CustomMimeType mimeType(WAVEFRONT_OBJ_NAME());
     mimeType.AddExtension("obj");
     mimeType.SetCategory(CATEGORY_SURFACES());
     mimeType.SetComment("Wavefront OBJ");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::STANFORD_PLY_MIMETYPE()
   {
     CustomMimeType mimeType(STANFORD_PLY_NAME());
     mimeType.AddExtension("ply");
     mimeType.SetCategory(CATEGORY_SURFACES());
     mimeType.SetComment("Stanford PLY");
     return mimeType;
   }
 
   std::string IOMimeTypes::STEREOLITHOGRAPHY_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".stl";
     return name;
   }
 
   std::string IOMimeTypes::WAVEFRONT_OBJ_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".obj";
     return name;
   }
 
   std::string IOMimeTypes::STANFORD_PLY_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".ply";
     return name;
   }
 
   std::string IOMimeTypes::DEFAULT_BASE_NAME()
   {
     static std::string name = "application/vnd.mitk";
     return name;
   }
 
   std::string IOMimeTypes::CATEGORY_IMAGES()
   {
     static std::string cat = "Images";
     return cat;
   }
 
   std::string IOMimeTypes::CATEGORY_SURFACES()
   {
     static std::string cat = "Surfaces";
     return cat;
   }
 
   std::string IOMimeTypes::VTK_IMAGE_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".vtk.image";
     return name;
   }
 
   std::string IOMimeTypes::VTK_IMAGE_LEGACY_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".vtk.image.legacy";
     return name;
   }
 
   std::string IOMimeTypes::VTK_PARALLEL_IMAGE_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".vtk.parallel.image";
     return name;
   }
 
   std::string IOMimeTypes::VTK_POLYDATA_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".vtk.polydata";
     return name;
   }
 
   std::string IOMimeTypes::VTK_POLYDATA_LEGACY_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".vtk.polydata.legacy";
     return name;
   }
 
   std::string IOMimeTypes::VTK_PARALLEL_POLYDATA_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".vtk.parallel.polydata";
     return name;
   }
 
   CustomMimeType IOMimeTypes::NRRD_MIMETYPE()
   {
     CustomMimeType mimeType(NRRD_MIMETYPE_NAME());
     mimeType.AddExtension("nrrd");
     mimeType.AddExtension("nhdr");
     mimeType.SetCategory("Images");
     mimeType.SetComment("NRRD");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::NIFTI_MIMETYPE()
   {
     CustomMimeType mimeType(NIFTI_MIMETYPE_NAME());
     mimeType.AddExtension("nii");
     mimeType.AddExtension("nii.gz");
     mimeType.AddExtension("hdr");
     mimeType.AddExtension("hdr.gz");
     mimeType.AddExtension("img");
     mimeType.AddExtension("img.gz");
     mimeType.AddExtension("nia");
     mimeType.SetCategory("Images");
     mimeType.SetComment("Nifti");
     return mimeType;
   }
 
   CustomMimeType IOMimeTypes::RAW_MIMETYPE()
   {
     CustomMimeType mimeType(RAW_MIMETYPE_NAME());
     mimeType.AddExtension("raw");
     mimeType.SetCategory("Images");
     mimeType.SetComment("Raw data");
     return mimeType;
   }
 
   IOMimeTypes::DicomMimeType IOMimeTypes::DICOM_MIMETYPE() { return DicomMimeType(); }
   std::string IOMimeTypes::NRRD_MIMETYPE_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".image.nrrd";
     return name;
   }
 
   std::string IOMimeTypes::NIFTI_MIMETYPE_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".image.nifti";
     return name;
   }
 
   std::string IOMimeTypes::RAW_MIMETYPE_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".image.raw";
     return name;
   }
 
   std::string IOMimeTypes::DICOM_MIMETYPE_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".image.dicom";
     return name;
   }
 
   CustomMimeType IOMimeTypes::POINTSET_MIMETYPE()
   {
     CustomMimeType mimeType(POINTSET_MIMETYPE_NAME());
     mimeType.AddExtension("mps");
     mimeType.SetCategory("Point Sets");
     mimeType.SetComment("MITK Point Set");
     return mimeType;
   }
 
   std::string IOMimeTypes::POINTSET_MIMETYPE_NAME()
   {
     static std::string name = DEFAULT_BASE_NAME() + ".pointset";
     return name;
   }
 
   CustomMimeType IOMimeTypes::GEOMETRY_DATA_MIMETYPE()
   {
     mitk::CustomMimeType mimeType(DEFAULT_BASE_NAME() + ".geometrydata");
     mimeType.AddExtension("mitkgeometry");
     mimeType.SetCategory("Geometries");
     mimeType.SetComment("GeometryData object");
     return mimeType;
   }
 }
diff --git a/Modules/DICOMReader/include/mitkDICOMProperty.h b/Modules/DICOMReader/include/mitkDICOMProperty.h
index 895c9e8cda..20bd65cca6 100644
--- a/Modules/DICOMReader/include/mitkDICOMProperty.h
+++ b/Modules/DICOMReader/include/mitkDICOMProperty.h
@@ -1,65 +1,82 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #ifndef mitkDICOMProperty_h
 #define mitkDICOMProperty_h
 
 #include "mitkDICOMImageBlockDescriptor.h"
 #include "mitkTemporoSpatialStringProperty.h"
 #include "mitkDICOMTagPath.h"
 
 #include "MitkDICOMReaderExports.h"
 
 namespace mitk
 {
 
   typedef TemporoSpatialStringProperty DICOMProperty;
 
   /** Generation functor for DICOMFileReader classes to convert the collected tag values into DICOMProperty instances. */
   MITKDICOMREADER_EXPORT mitk::BaseProperty::Pointer GetDICOMPropertyForDICOMValuesFunctor(const DICOMCachedValueLookupTable& cacheLookupTable);
 
 
   class PropertyList;
   class BaseData;
 
   /** Helper function that searches for all properties in a given property list that matches the passed path.
    * The result will be the matching properties in a map*/
   MITKDICOMREADER_EXPORT std::map< std::string, BaseProperty::Pointer> GetPropertyByDICOMTagPath(const PropertyList* list, const DICOMTagPath& path);
   /** Helper function that searches for all properties in a given base data that matches the passed path.
   * The result will be the matching properties in a map*/
   MITKDICOMREADER_EXPORT std::map< std::string, BaseProperty::Pointer> GetPropertyByDICOMTagPath(const BaseData* data, const DICOMTagPath& path);
 
   /**Helper function that can be used to convert the content of a DICOM property
      into the given return type. The function makes the following assumptions:
      1. dcmValueString does only encode one number.
      2. The value is encoded compliant to locale "C".
      @pre dcmValueString must be convertibel into the return type.
      If this is not the case an exception will be thrown.
      */
   template<typename TNumericReturnType>
   TNumericReturnType ConvertDICOMStrToValue(const std::string& dcmValueString)
   {
     std::istringstream iss(dcmValueString);
     iss.imbue(std::locale("C"));
     TNumericReturnType d;
     if (!(iss >> d) || !(iss.eof()))
     {
       mitkThrow() << "Cannot convert string to value type. Type: " << typeid(TNumericReturnType).name() << "; String: " << dcmValueString;
     }
 
     return d;
   };
 
+  /**Helper function that can be used to convert a numeric value into content of a DICOM property.
+     @pre value must be convertibel into a string.
+     If this is not the case an exception will be thrown.
+     */
+  template<typename TNumericType>
+  std::string ConvertValueToDICOMStr(const TNumericType value)
+  {
+    std::ostringstream oss(value);
+    oss.imbue(std::locale("C"));
+    if (!(oss << value))
+    {
+      mitkThrow() << "Cannot convert value type to dicom string. Type: " << typeid(TNumericType).name() << "; value: " << value;
+    }
+
+    return oss.str();
+  };
+
 
 }
 
 #endif
diff --git a/Modules/DICOMReader/test/mitkDICOMPropertyTest.cpp b/Modules/DICOMReader/test/mitkDICOMPropertyTest.cpp
index cf891996ff..96218f9203 100644
--- a/Modules/DICOMReader/test/mitkDICOMPropertyTest.cpp
+++ b/Modules/DICOMReader/test/mitkDICOMPropertyTest.cpp
@@ -1,159 +1,166 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkDICOMProperty.h"
 
 #include "mitkImage.h"
 #include "mitkTestFixture.h"
 #include "mitkTestingMacros.h"
 
 class mitkDICOMPropertyTestSuite : public mitk::TestFixture
 {
   CPPUNIT_TEST_SUITE(mitkDICOMPropertyTestSuite);
 
   MITK_TEST(GetPropertyByDICOMTagPath);
   MITK_TEST(GetPropertyByDICOMTagPath_2);
   MITK_TEST(ConvertDICOMStrToValue);
+  MITK_TEST(ConvertValueToDICOMStr);
 
   CPPUNIT_TEST_SUITE_END();
 
 private:
 
   mitk::DICOMTagPath simplePath;
   mitk::DICOMTagPath deepPath;
   mitk::DICOMTagPath deepPath2;
   mitk::DICOMTagPath deepPath_withAnyElement;
   mitk::DICOMTagPath deepPath_withAnySelection;
   mitk::DICOMTagPath deepPath_withSelection;
   mitk::DICOMTagPath deepPath_withSelection2;
 
   mitk::DICOMTagPath emptyPath;
 
   mitk::Image::Pointer data;
 
   std::string simplePathStr;
   std::string deepPathStr;
   std::string deepPath2Str;
   std::string deepPath_withSelectionStr;
 
 public:
 
   void setUp() override
   {
     simplePath.AddElement(0x0010, 0x0010);
 
     deepPath.AddElement(0x0010, 0x0011).AddElement(0x0020, 0x0022).AddElement(0x0030, 0x0033);
 
     deepPath2.AddElement(0x0010, 0x0011).AddElement(0x0020, 0x0023).AddElement(0x0030, 0x0033);
 
     deepPath_withAnyElement.AddElement(0x0010, 0x0011).AddAnyElement().AddElement(0x0030, 0x0033);
 
     deepPath_withAnySelection.AddElement(0x0010, 0x0011).AddAnySelection(0x0020, 0x0024).AddElement(0x0030, 0x0033);
 
     deepPath_withSelection.AddElement(0x0010, 0x0011).AddSelection(0x0020, 0x0024, 1).AddElement(0x0030, 0x0033);
 
     deepPath_withSelection2.AddElement(0x0010, 0x0011).AddSelection(0x0020, 0x0024, 2).AddElement(0x0030, 0x0033);
 
     simplePathStr = mitk::DICOMTagPathToPropertyName(simplePath);
     deepPathStr = mitk::DICOMTagPathToPropertyName(deepPath);
     deepPath2Str = mitk::DICOMTagPathToPropertyName(deepPath2);
     deepPath_withSelectionStr = mitk::DICOMTagPathToPropertyName(deepPath_withSelection);
 
     data = mitk::Image::New();
     data->GetPropertyList()->SetStringProperty(simplePathStr.c_str(), "simplePath");
     data->GetPropertyList()->SetStringProperty(deepPathStr.c_str(), "deepPath");
     data->GetPropertyList()->SetStringProperty(deepPath2Str.c_str(), "deepPath2");
     data->GetPropertyList()->SetStringProperty(deepPath_withSelectionStr.c_str(), "deepPath_withSelection");
     data->GetPropertyList()->SetStringProperty("DICOM.0003.0003", "otherPath");
     data->GetPropertyList()->SetStringProperty("not_a_dicom_prop", "not_a_dicom_prop");
   }
 
   void tearDown() override
   {
   }
 
   void GetPropertyByDICOMTagPath()
   {
     std::map< std::string, mitk::BaseProperty::Pointer> result = mitk::GetPropertyByDICOMTagPath(data, simplePath);
     CPPUNIT_ASSERT(result.size() == 1);
     CPPUNIT_ASSERT_EQUAL(result.begin()->second->GetValueAsString(), std::string("simplePath"));
 
     result = mitk::GetPropertyByDICOMTagPath(data, deepPath);
     CPPUNIT_ASSERT(result.size() == 1);
     CPPUNIT_ASSERT_EQUAL(result.begin()->second->GetValueAsString(), std::string("deepPath"));
 
     result = mitk::GetPropertyByDICOMTagPath(data, deepPath2);
     CPPUNIT_ASSERT(result.size() == 1);
     CPPUNIT_ASSERT_EQUAL(result.begin()->second->GetValueAsString(), std::string("deepPath2"));
 
     result = mitk::GetPropertyByDICOMTagPath(data, deepPath_withAnyElement);
     CPPUNIT_ASSERT(result.size() == 3);
     CPPUNIT_ASSERT_EQUAL(result[deepPathStr]->GetValueAsString(), std::string("deepPath"));
     CPPUNIT_ASSERT_EQUAL(result[deepPath2Str]->GetValueAsString(), std::string("deepPath2"));
     CPPUNIT_ASSERT_EQUAL(result[deepPath_withSelectionStr]->GetValueAsString(), std::string("deepPath_withSelection"));
 
     result = mitk::GetPropertyByDICOMTagPath(data, deepPath_withSelection);
     CPPUNIT_ASSERT(result.size() == 1);
     CPPUNIT_ASSERT_EQUAL(result[deepPath_withSelectionStr]->GetValueAsString(), std::string("deepPath_withSelection"));
 
     result = mitk::GetPropertyByDICOMTagPath(data, deepPath_withSelection2);
     CPPUNIT_ASSERT(result.size() == 0);
 
     result = mitk::GetPropertyByDICOMTagPath(data, emptyPath);
     CPPUNIT_ASSERT(result.size() == 0);
   }
 
 
   void GetPropertyByDICOMTagPath_2()
   {
     std::map< std::string, mitk::BaseProperty::Pointer> result = mitk::GetPropertyByDICOMTagPath(data->GetPropertyList(), simplePath);
     CPPUNIT_ASSERT(result.size() == 1);
     CPPUNIT_ASSERT_EQUAL(result.begin()->second->GetValueAsString(), std::string("simplePath"));
 
     result = mitk::GetPropertyByDICOMTagPath(data->GetPropertyList(), deepPath);
     CPPUNIT_ASSERT(result.size() == 1);
     CPPUNIT_ASSERT_EQUAL(result.begin()->second->GetValueAsString(), std::string("deepPath"));
 
     result = mitk::GetPropertyByDICOMTagPath(data->GetPropertyList(), deepPath2);
     CPPUNIT_ASSERT(result.size() == 1);
     CPPUNIT_ASSERT_EQUAL(result.begin()->second->GetValueAsString(), std::string("deepPath2"));
 
     result = mitk::GetPropertyByDICOMTagPath(data->GetPropertyList(), deepPath_withAnyElement);
     CPPUNIT_ASSERT(result.size() == 3);
     CPPUNIT_ASSERT_EQUAL(result[deepPathStr]->GetValueAsString(), std::string("deepPath"));
     CPPUNIT_ASSERT_EQUAL(result[deepPath2Str]->GetValueAsString(), std::string("deepPath2"));
     CPPUNIT_ASSERT_EQUAL(result[deepPath_withSelectionStr]->GetValueAsString(), std::string("deepPath_withSelection"));
 
     result = mitk::GetPropertyByDICOMTagPath(data->GetPropertyList(), deepPath_withSelection);
     CPPUNIT_ASSERT(result.size() == 1);
     CPPUNIT_ASSERT_EQUAL(result[deepPath_withSelectionStr]->GetValueAsString(), std::string("deepPath_withSelection"));
 
     result = mitk::GetPropertyByDICOMTagPath(data->GetPropertyList(), deepPath_withSelection2);
     CPPUNIT_ASSERT(result.size() == 0);
 
     result = mitk::GetPropertyByDICOMTagPath(data->GetPropertyList(), emptyPath);
     CPPUNIT_ASSERT(result.size() == 0);
   }
 
   void ConvertDICOMStrToValue()
   {
     CPPUNIT_ASSERT_EQUAL(mitk::ConvertDICOMStrToValue<double>("1.35"), 1.35);
     CPPUNIT_ASSERT_EQUAL(mitk::ConvertDICOMStrToValue<double>("1"), 1.);
     CPPUNIT_ASSERT_THROW(mitk::ConvertDICOMStrToValue<int>("1.35"), mitk::Exception);
     CPPUNIT_ASSERT_EQUAL(mitk::ConvertDICOMStrToValue<int>("1"), 1);
     CPPUNIT_ASSERT_THROW(mitk::ConvertDICOMStrToValue<double>("1,35"), mitk::Exception);
     CPPUNIT_ASSERT_THROW(mitk::ConvertDICOMStrToValue<double>("nonumber"), mitk::Exception);
   }
 
+  void ConvertValueToDICOMStr()
+  {
+    CPPUNIT_ASSERT_EQUAL(mitk::ConvertValueToDICOMStr(1.35), std::string("1.35"));
+    CPPUNIT_ASSERT_EQUAL(mitk::ConvertValueToDICOMStr(1), std::string("1"));
+  }
+
 };
 
 MITK_TEST_SUITE_REGISTRATION(mitkDICOMProperty)