diff --git a/Modules/IGT/DataManagement/mitkNavigationDataSource.cpp b/Modules/IGT/DataManagement/mitkNavigationDataSource.cpp
index a8a56365c0..7ebe9b002c 100644
--- a/Modules/IGT/DataManagement/mitkNavigationDataSource.cpp
+++ b/Modules/IGT/DataManagement/mitkNavigationDataSource.cpp
@@ -1,156 +1,169 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center,
 Division of Medical and Biological Informatics.
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include "mitkNavigationDataSource.h"
 #include "mitkUIDGenerator.h"
 
 
 //Microservices
 #include <usGetModuleContext.h>
 #include <usModule.h>
 #include <usServiceProperties.h>
 #include <usModuleContext.h>
 
 const std::string mitk::NavigationDataSource::US_INTERFACE_NAME = "org.mitk.services.NavigationDataSource";
 const std::string mitk::NavigationDataSource::US_PROPKEY_DEVICENAME = US_INTERFACE_NAME + ".devicename";
 const std::string mitk::NavigationDataSource::US_PROPKEY_ID = US_INTERFACE_NAME + ".id";
 const std::string mitk::NavigationDataSource::US_PROPKEY_ISACTIVE = US_INTERFACE_NAME + ".isActive";
 
 mitk::NavigationDataSource::NavigationDataSource()
-: itk::ProcessObject(), m_Name("NavigationDataSource (no defined type)"), m_IsFrozen(false)
+: itk::ProcessObject(), m_Name("NavigationDataSource (no defined type)"), m_IsFrozen(false), m_ToolMetaDataCollection(mitk::NavigationToolStorage::New())
 {
 }
 
 mitk::NavigationDataSource::~NavigationDataSource()
 {
 }
 
 mitk::NavigationData* mitk::NavigationDataSource::GetOutput()
 {
   if (this->GetNumberOfIndexedOutputs() < 1)
     return nullptr;
 
   return static_cast<NavigationData*>(this->ProcessObject::GetPrimaryOutput());
 }
 
 mitk::NavigationData* mitk::NavigationDataSource::GetOutput(DataObjectPointerArraySizeType idx)
 {
   NavigationData* out = dynamic_cast<NavigationData*>( this->ProcessObject::GetOutput(idx) );
   if ( out == nullptr && this->ProcessObject::GetOutput(idx) != nullptr )
   {
     itkWarningMacro (<< "Unable to convert output number " << idx << " to type " <<  typeid( NavigationData ).name () );
   }
   return out;
 }
 
 mitk::NavigationData* mitk::NavigationDataSource::GetOutput(const std::string& navDataName)
 {
   DataObjectPointerArray outputs = this->GetOutputs();
   for (DataObjectPointerArray::iterator it = outputs.begin(); it != outputs.end(); ++it)
     if (navDataName == (static_cast<NavigationData*>(it->GetPointer()))->GetName())
       return static_cast<NavigationData*>(it->GetPointer());
   return nullptr;
 }
 
 itk::ProcessObject::DataObjectPointerArraySizeType mitk::NavigationDataSource::GetOutputIndex( std::string navDataName )
 {
   DataObjectPointerArray outputs = this->GetOutputs();
   for (DataObjectPointerArray::size_type i = 0; i < outputs.size(); ++i)
     if (navDataName == (static_cast<NavigationData*>(outputs.at(i).GetPointer()))->GetName())
       return i;
   throw std::invalid_argument("output name does not exist");
 }
 
 void mitk::NavigationDataSource::RegisterAsMicroservice(){
   // Get Context
   us::ModuleContext* context = us::GetModuleContext();
 
   // Define ServiceProps
   us::ServiceProperties props;
   mitk::UIDGenerator uidGen = mitk::UIDGenerator ("org.mitk.services.NavigationDataSource.id_", 16);
   props[ US_PROPKEY_ID ] = uidGen.GetUID();
   props[ US_PROPKEY_DEVICENAME ] = m_Name;
   m_ServiceRegistration = context->RegisterService(this, props);
 }
 
 void mitk::NavigationDataSource::UnRegisterMicroservice(){
   if (m_ServiceRegistration != nullptr) m_ServiceRegistration.Unregister();
   m_ServiceRegistration = 0;
 }
 
 std::string mitk::NavigationDataSource::GetMicroserviceID(){
   return this->m_ServiceRegistration.GetReference().GetProperty(US_PROPKEY_ID).ToString();
 }
 
 void mitk::NavigationDataSource::GraftOutput(itk::DataObject *graft)
 {
   this->GraftNthOutput(0, graft);
 }
 
 void mitk::NavigationDataSource::GraftNthOutput(unsigned int idx, itk::DataObject *graft)
 {
   if ( idx >= this->GetNumberOfIndexedOutputs() )
   {
     itkExceptionMacro(<<"Requested to graft output " << idx <<
       " but this filter only has " << this->GetNumberOfIndexedOutputs() << " Outputs.");
   }
 
   if ( !graft )
   {
     itkExceptionMacro(<<"Requested to graft output with a nullptr pointer object" );
   }
 
   itk::DataObject* output = this->GetOutput(idx);
   if ( !output )
   {
     itkExceptionMacro(<<"Requested to graft output that is a nullptr pointer" );
   }
   // Call Graft on NavigationData to copy member data
   output->Graft( graft );
 }
 
 itk::DataObject::Pointer mitk::NavigationDataSource::MakeOutput ( DataObjectPointerArraySizeType /*idx*/ )
 {
   return mitk::NavigationData::New().GetPointer();
 }
 
 itk::DataObject::Pointer mitk::NavigationDataSource::MakeOutput( const DataObjectIdentifierType & name )
 {
   itkDebugMacro("MakeOutput(" << name << ")");
   if( this->IsIndexedOutputName(name) )
   {
     return this->MakeOutput( this->MakeIndexFromOutputName(name) );
   }
   return static_cast<itk::DataObject *>(mitk::NavigationData::New().GetPointer());
 }
 
 mitk::PropertyList::ConstPointer mitk::NavigationDataSource::GetParameters() const
 {
   mitk::PropertyList::Pointer p = mitk::PropertyList::New();
   // add properties to p like this:
   //p->SetProperty("MyFilter_MyParameter", mitk::PropertyDataType::New(m_MyParameter));
   return mitk::PropertyList::ConstPointer(p);
 }
 
 void mitk::NavigationDataSource::Freeze()
 {
   m_IsFrozen = true;
 }
 
 void mitk::NavigationDataSource::UnFreeze()
 {
   m_IsFrozen = false;
 }
+
+mitk::NavigationTool::Pointer mitk::NavigationDataSource::GetToolMetaData(DataObjectPointerArraySizeType idx)
+{
+  if (idx >= this->GetNumberOfIndexedOutputs()) { return mitk::NavigationTool::New(); }
+  else { return GetToolMetaData(this->GetOutput(idx)->GetName()); }
+}
+
+mitk::NavigationTool::Pointer mitk::NavigationDataSource::GetToolMetaData(const std::string& navDataName)
+{
+  mitk::NavigationTool::Pointer returnValue = m_ToolMetaDataCollection->GetToolByName(navDataName);
+  if (returnValue == nullptr) { returnValue = mitk::NavigationTool::New(); }
+  return returnValue;
+}
diff --git a/Modules/IGT/DataManagement/mitkNavigationDataSource.h b/Modules/IGT/DataManagement/mitkNavigationDataSource.h
index 206c544f2f..c1d8963286 100644
--- a/Modules/IGT/DataManagement/mitkNavigationDataSource.h
+++ b/Modules/IGT/DataManagement/mitkNavigationDataSource.h
@@ -1,186 +1,214 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center,
 Division of Medical and Biological Informatics.
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 
 #ifndef MITKNAVIGATIONDATASOURCE_H_HEADER_INCLUDED_
 #define MITKNAVIGATIONDATASOURCE_H_HEADER_INCLUDED_
 
 #include <itkProcessObject.h>
 #include "mitkNavigationData.h"
+#include <mitkNavigationTool.h>
+#include <mitkNavigationToolStorage.h>
 #include "mitkPropertyList.h"
 #include "MitkIGTExports.h"
 
 // Microservices
 #include <mitkServiceInterface.h>
 #include <usServiceRegistration.h>
 
 namespace mitk {
 
   /**Documentation
   * \brief Navigation Data source
   *
   * Base class for all navigation filters that produce NavigationData objects as output.
   * This class defines the output-interface for NavigationDataFilters.
   * \warning: if Update() is called on any output object, all NavigationData filters will
   * generate new output data for all outputs, not just the one on which Update() was called.
   *
   * \ingroup IGT
   */
   class MITKIGT_EXPORT NavigationDataSource : public itk::ProcessObject
   {
   public:
     mitkClassMacroItkParent(NavigationDataSource, itk::ProcessObject);
 
     /** @return Returns a human readable name of this source. There will be a default name,
       *         or you can set the name with the method SetName() if you want to change it.
       */
     itkGetMacro(Name,std::string);
 
     /** @brief Sets the human readable name of this source. There is also a default name,
       *        but you can use this method if you need to define it on your own.
       */
     itkSetMacro(Name,std::string);
 
     /**
     *\brief return the output (output with id 0) of the filter
     */
     NavigationData* GetOutput(void);
 
     /**
     *\brief return the output with id idx of the filter
     */
     NavigationData* GetOutput(DataObjectPointerArraySizeType idx);
 
     /**
     *\brief return the output with name navDataName of the filter
     */
     NavigationData* GetOutput(const std::string& navDataName);
 
+    /** @return Returns the metadata of the navigation tool at
+     *          the given idx. Returns an empty object if no
+     *          metadata is available.
+     */
+    NavigationTool::Pointer GetToolMetaData(DataObjectPointerArraySizeType idx);
+
+    /** @return Returns the metadata of the navigation tool with
+    *          the given name. Returns an empty object if no
+    *          metadata is available.
+    */
+    NavigationTool::Pointer GetToolMetaData(const std::string& navDataName);
+
+    /** @return Returns the metadata of all tools identified by the tool name.
+    *           There is no need to set the metadata of the tools, so not
+    *           every tool has metadata available. Returns an empty tool storage
+    *           if no metadata was set at all.*/
+    itkGetMacro(ToolMetaDataCollection, mitk::NavigationToolStorage::Pointer);
+
+    /** Sets the tool metadata as NavigationToolStorage object. */
+    itkSetMacro(ToolMetaDataCollection, mitk::NavigationToolStorage::Pointer);
+
     /**
     *\brief return the index of the output with name navDataName, -1 if no output with that name was found
     *
     * \warning if a subclass has outputs that have different data type than mitk::NavigationData, they have to overwrite this method
     */
     DataObjectPointerArraySizeType GetOutputIndex(std::string navDataName);
 
     /**
     *\brief Registers this object as a Microservice, making it available to every module and/or plugin.
     * To unregister, call UnregisterMicroservice().
     */
     virtual void RegisterAsMicroservice();
 
     /**
     *\brief Registers this object as a Microservice, making it available to every module and/or plugin.
     */
     virtual void UnRegisterMicroservice();
 
     /**
     *\brief Returns the id that this device is registered with. The id will only be valid, if the
     * NavigationDataSource has been registered using RegisterAsMicroservice().
     */
     std::string GetMicroserviceID();
 
     /**
     *\brief These Constants are used in conjunction with Microservices
     */
     static const std::string US_INTERFACE_NAME;
     static const std::string US_PROPKEY_DEVICENAME;
     static const std::string US_PROPKEY_ID;
     static const std::string US_PROPKEY_ISACTIVE; //NOT IMPLEMENTED YET!
 
     /**
     *\brief Graft the specified DataObject onto this ProcessObject's output.
     *
     * See itk::ImageSource::GraftNthOutput for details
     */
     virtual void GraftNthOutput(unsigned int idx, itk::DataObject *graft);
 
     /**
     * \brief Graft the specified DataObject onto this ProcessObject's output.
     *
     * See itk::ImageSource::Graft Output for details
     */
     virtual void GraftOutput(itk::DataObject *graft);
 
     /**
      * Allocates a new output object and returns it. Currently the
      * index idx is not evaluated.
      * @param idx the index of the output for which an object should be created
      * @returns the new object
      */
     itk::DataObject::Pointer MakeOutput ( DataObjectPointerArraySizeType idx ) override;
 
     /**
      * This is a default implementation to make sure we have something.
      * Once all the subclasses of ProcessObject provide an appopriate
      * MakeOutput(), then ProcessObject::MakeOutput() can be made pure
      * virtual.
      */
     itk::DataObject::Pointer MakeOutput(const DataObjectIdentifierType &name) override;
 
     /**
     * \brief Set all filter parameters as the PropertyList p
     *
     * This method allows to set all parameters of a filter with one
     * method call. For the names of the parameters, take a look at
     * the GetParameters method of the filter
     * This method has to be overwritten by each MITK-IGT filter.
     */
     virtual void SetParameters(const mitk::PropertyList*){};
 
     /**
     * \brief Get all filter parameters as a PropertyList
     *
     * This method allows to get all parameters of a filter with one
     * method call. The returned PropertyList must be assigned to a
     * SmartPointer immediately, or else it will get destroyed.
     * Every filter must overwrite this method to create a filter-specific
     * PropertyList. Note that property names must be unique over all
     * MITK-IGT filters. Therefore each filter should use its name as a prefix
     * for each property name.
     * Secondly, each filter should list the property names and data types
     * in the method documentation.
     */
     virtual mitk::PropertyList::ConstPointer GetParameters() const;
 
     /** Freezes the navigation data source which means the current state is frozen and the output
      *  navigation data stays at it is. Calling Update() does not have any effect until UnFreeze()
      *  is called. This also means that the data source is not updated any more. */
     virtual void Freeze();
 
     /** Unfreezes the data source. */
     virtual void UnFreeze();
 
     /** @return Returns whether the data source is currently frozen. */
     itkGetMacro(IsFrozen,bool);
 
 
   protected:
     NavigationDataSource();
     ~NavigationDataSource() override;
 
     std::string m_Name;
 
     bool m_IsFrozen;
 
+    /** Holds the metadata of all tools identified by the tool name. 
+     *  There is no need to set the metadata of the tools, so not 
+     *  every tool has metadata available. */
+    NavigationToolStorage::Pointer m_ToolMetaDataCollection;
+
 
   private:
     us::ServiceRegistration<Self> m_ServiceRegistration;
   };
 } // namespace mitk
 // This is the microservice declaration. Do not meddle!
 MITK_DECLARE_SERVICE_INTERFACE(mitk::NavigationDataSource, "org.mitk.services.NavigationDataSource")
 #endif /* MITKNAVIGATIONDATASOURCE_H_HEADER_INCLUDED_ */
diff --git a/Modules/IGTUI/Qmitk/QmitkNavigationDataSourceSelectionWidget.cpp b/Modules/IGTUI/Qmitk/QmitkNavigationDataSourceSelectionWidget.cpp
index 0419e4ca9e..d1adf13a79 100644
--- a/Modules/IGTUI/Qmitk/QmitkNavigationDataSourceSelectionWidget.cpp
+++ b/Modules/IGTUI/Qmitk/QmitkNavigationDataSourceSelectionWidget.cpp
@@ -1,137 +1,134 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center,
 Division of Medical and Biological Informatics.
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include "QmitkNavigationDataSourceSelectionWidget.h"
 
 //mitk headers
 #include <mitkNavigationDataSource.h>
 #include <usGetModuleContext.h>
 #include <usServiceReference.h>
 
 
 
 QmitkNavigationDataSourceSelectionWidget::QmitkNavigationDataSourceSelectionWidget(QWidget* parent, Qt::WindowFlags f)
 : QWidget(parent, f)
 {
   m_Controls = nullptr;
   CreateQtPartControl(this);
   CreateConnections();
 
 }
 
 
 QmitkNavigationDataSourceSelectionWidget::~QmitkNavigationDataSourceSelectionWidget()
 {
 
 }
 
 void QmitkNavigationDataSourceSelectionWidget::CreateQtPartControl(QWidget *parent)
 {
   if (!m_Controls)
   {
     // create GUI widgets
     m_Controls = new Ui::QmitkNavigationDataSourceSelectionWidgetControls;
     m_Controls->setupUi(parent);
 
     std::string empty = "";
     m_Controls->m_NavigationDataSourceWidget->Initialize<mitk::NavigationDataSource>(mitk::NavigationDataSource::US_PROPKEY_DEVICENAME,empty);
 
   }
 }
 
 void QmitkNavigationDataSourceSelectionWidget::CreateConnections()
 {
   if ( m_Controls )
   {
     connect( (QObject*)(m_Controls->m_NavigationDataSourceWidget), SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(NavigationDataSourceSelected(us::ServiceReferenceU)) );
     connect((QObject*)(m_Controls->m_ToolView), SIGNAL(currentRowChanged(int)), this, SLOT(NavigationToolSelected(int)));
 
   }
 }
 
 void QmitkNavigationDataSourceSelectionWidget::NavigationToolSelected(int selection)
 {
   emit NavigationToolSelected(this->m_CurrentStorage->GetTool(selection));
 }
 
 void QmitkNavigationDataSourceSelectionWidget::NavigationDataSourceSelected(us::ServiceReferenceU s)
   {
     if (!s) //no device selected
       {
         //reset everything
         m_CurrentSource = nullptr;
         m_CurrentStorage = nullptr;
         emit NavigationDataSourceSelected(m_CurrentSource);
         return;
       }
 
     // Get Source
     us::ModuleContext* context = us::GetModuleContext();
     m_CurrentSource = context->GetService<mitk::NavigationDataSource>(s);
 
     // clear tool list before filling it
     m_Controls->m_ToolView->clear();
     //Fill tool list
     MITK_INFO<<"no outputs: "<<m_CurrentSource->GetNumberOfOutputs();
     for(std::size_t i = 0; i < m_CurrentSource->GetNumberOfOutputs(); i++)
     {
       new QListWidgetItem(tr(m_CurrentSource->GetOutput(i)->GetName()), m_Controls->m_ToolView);
     }
 
-    // Get Storage
-    std::string filter = "(" + mitk::NavigationToolStorage::US_PROPKEY_SOURCE_ID + "=" + m_CurrentSource->GetMicroserviceID() + ")";
-    std::vector<us::ServiceReference<mitk::NavigationToolStorage> > refs = context->GetServiceReferences<mitk::NavigationToolStorage>(filter);
-    if (refs.empty()) return; //no storage was found
-    m_CurrentStorage = context->GetService(refs.front());
+    // Get corresponding tool storage
+    m_CurrentStorage = m_CurrentSource->GetToolMetaDataCollection();
 
     if (m_CurrentStorage.IsNull())
       {
       MITK_WARN << "Found an invalid storage object!";
       return;
       }
     if (m_CurrentStorage->GetToolCount() != m_CurrentSource->GetNumberOfOutputs()) //there is something wrong with the storage
       {
       MITK_WARN << "Found a tool storage, but it has not the same number of tools like the NavigationDataSource. This storage won't be used because it isn't the right one.";
       m_CurrentStorage = nullptr;
       }
 
     emit NavigationDataSourceSelected(m_CurrentSource);
   }
 
 mitk::NavigationDataSource::Pointer QmitkNavigationDataSourceSelectionWidget::GetSelectedNavigationDataSource()
   {
   return this->m_CurrentSource;
   }
 
 
 int QmitkNavigationDataSourceSelectionWidget::GetSelectedToolID()
   {
     return this->m_Controls->m_ToolView->currentIndex().row();
   }
 
 
 mitk::NavigationTool::Pointer QmitkNavigationDataSourceSelectionWidget::GetSelectedNavigationTool()
   {
     if (this->m_CurrentStorage.IsNull()) return nullptr;
     if ((m_Controls->m_ToolView->currentIndex().row() < 0) || (static_cast<unsigned int>(m_Controls->m_ToolView->currentIndex().row()) >= m_CurrentStorage->GetToolCount())) return nullptr;
     return this->m_CurrentStorage->GetTool(m_Controls->m_ToolView->currentIndex().row());
   }
 
 
 mitk::NavigationToolStorage::Pointer QmitkNavigationDataSourceSelectionWidget::GetNavigationToolStorageOfSource()
   {
     return this->m_CurrentStorage;
   }
diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxViewWorker.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxViewWorker.cpp
index dd91871bef..58a0bdbd51 100644
--- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxViewWorker.cpp
+++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxViewWorker.cpp
@@ -1,253 +1,254 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center,
 Division of Medical and Biological Informatics.
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 // Qmitk
 #include "QmitkMITKIGTTrackingToolboxViewWorker.h"
 
 #include <mitkTrackingDeviceSourceConfigurator.h>
 
 QmitkMITKIGTTrackingToolboxViewWorker::QmitkMITKIGTTrackingToolboxViewWorker()
 {
 }
 
 QmitkMITKIGTTrackingToolboxViewWorker::~QmitkMITKIGTTrackingToolboxViewWorker()
 {
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::SetWorkerMethod(WorkerMethod w)
 {
   m_WorkerMethod = w;
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::SetTrackingDevice(mitk::TrackingDevice::Pointer t)
 {
   m_TrackingDevice = t;
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::SetDataStorage(mitk::DataStorage::Pointer d)
 {
   m_DataStorage = d;
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::SetInverseMode(bool mode)
 {
   m_InverseMode = mode;
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::SetTrackingDeviceData(mitk::TrackingDeviceData d)
 {
   m_TrackingDeviceData = d;
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::SetNavigationToolStorage(mitk::NavigationToolStorage::Pointer n)
 {
   m_NavigationToolStorage = n;
 }
 
 //! [Thread 7]
 void QmitkMITKIGTTrackingToolboxViewWorker::ThreadFunc()
 {
   switch (m_WorkerMethod)
   {
   case eAutoDetectTools:
     this->AutoDetectTools();
     break;
   case eConnectDevice:
     this->ConnectDevice();
     break;
   case eStartTracking:
     this->StartTracking();
     break;
   case eStopTracking:
     this->StopTracking();
     break;
   case eDisconnectDevice:
     this->DisconnectDevice();
     break;
   default:
     MITK_WARN << "Undefined worker method was set ... something went wrong!";
     break;
   }
 }
 //! [Thread 7]
 
 void QmitkMITKIGTTrackingToolboxViewWorker::AutoDetectTools()
 {
   mitk::NavigationToolStorage::Pointer autoDetectedStorage = mitk::NavigationToolStorage::New(m_DataStorage);
   try
   {
     mitk::NavigationToolStorage::Pointer tempStorage = m_TrackingDevice->AutoDetectTools();
     for (unsigned int i = 0; i < tempStorage->GetToolCount(); i++) { autoDetectedStorage->AddTool(tempStorage->GetTool(i)); }
   }
   catch (mitk::Exception& e)
   {
     MITK_WARN << e.GetDescription();
     emit AutoDetectToolsFinished(false, e.GetDescription());
     return;
   }
   m_NavigationToolStorage = nullptr;
   m_NavigationToolStorage = autoDetectedStorage;
   emit AutoDetectToolsFinished(true, "");
   MITK_INFO << "AutoDetect Tools Finished.";
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::ConnectDevice()
 {
   std::string message = "";
 
   //build the IGT pipeline
   mitk::TrackingDevice::Pointer trackingDevice = m_TrackingDevice;
   trackingDevice->SetData(m_TrackingDeviceData);
 
   //set device to rotation mode transposed becaus we are working with VNL style quaternions
   if (m_InverseMode)
   {
     trackingDevice->SetRotationMode(mitk::TrackingDevice::RotationTransposed);
   }
 
   //Get Tracking Volume Data
   mitk::TrackingDeviceData data = m_TrackingDeviceData;
 
   //Create Navigation Data Source with the factory class
   mitk::TrackingDeviceSourceConfigurator::Pointer myTrackingDeviceSourceFactory = mitk::TrackingDeviceSourceConfigurator::New(m_NavigationToolStorage, trackingDevice);
 
   m_TrackingDeviceSource = myTrackingDeviceSourceFactory->CreateTrackingDeviceSource(m_ToolVisualizationFilter);
 
   if (m_TrackingDeviceSource.IsNull())
   {
     message = std::string("Cannot connect to device: ") + myTrackingDeviceSourceFactory->GetErrorMessage();
     emit ConnectDeviceFinished(false, QString(message.c_str()));
     return;
   }
 
   //set filter to rotation mode transposed becaus we are working with VNL style quaternions
   if (m_InverseMode)
     m_ToolVisualizationFilter->SetRotationMode(mitk::NavigationDataObjectVisualizationFilter::RotationTransposed);
 
   //First check if the created object is valid
   if (m_TrackingDeviceSource.IsNull())
   {
     message = myTrackingDeviceSourceFactory->GetErrorMessage();
     emit ConnectDeviceFinished(false, QString(message.c_str()));
     return;
   }
 
   MITK_INFO << "Connected device with " << m_TrackingDeviceSource->GetNumberOfOutputs() << " tools.";
 
   //connect to device
   try
   {
     m_TrackingDeviceSource->Connect();
     //Microservice registration:
+    m_TrackingDeviceSource->SetToolMetaDataCollection(m_NavigationToolStorage);
     m_TrackingDeviceSource->RegisterAsMicroservice();
-    m_NavigationToolStorage->SetSourceID(m_TrackingDeviceSource->GetMicroserviceID());
+    m_NavigationToolStorage->SetSourceID(m_TrackingDeviceSource->GetMicroserviceID()); //DEPRECATED / not needed anymore because NavigationDataSource now holds a member of its tool storage. Only left for backward compatibility.
     m_NavigationToolStorage->LockStorage();
   }
   catch (...) //todo: change to mitk::IGTException
   {
     message = "Error on connecting the tracking device.";
     emit ConnectDeviceFinished(false, QString(message.c_str()));
     return;
   }
   emit ConnectDeviceFinished(true, QString(message.c_str()));
 }
 
 mitk::TrackingDeviceSource::Pointer QmitkMITKIGTTrackingToolboxViewWorker::GetTrackingDeviceSource()
 {
   return this->m_TrackingDeviceSource;
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::StartTracking()
 {
   QString errorMessage = "";
   try
   {
     m_TrackingDeviceSource->StartTracking();
   }
   catch (...) //todo: change to mitk::IGTException
   {
     errorMessage += "Error while starting the tracking device!";
     emit StartTrackingFinished(false, errorMessage);
     return;
   }
   //remember the original colors of the tools
   m_OriginalColors = std::map<mitk::DataNode::Pointer, mitk::Color>();
   for (unsigned int i = 0; i < this->m_NavigationToolStorage->GetToolCount(); i++)
   {
     mitk::DataNode::Pointer currentToolNode = m_NavigationToolStorage->GetTool(i)->GetDataNode();
     float c[3];
     currentToolNode->GetColor(c);
     mitk::Color color;
     color.SetRed(c[0]);
     color.SetGreen(c[1]);
     color.SetBlue(c[2]);
     m_OriginalColors[currentToolNode] = color;
   }
 
   emit StartTrackingFinished(true, errorMessage);
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::StopTracking()
 {
   //stop tracking
   try
   {
     m_TrackingDeviceSource->StopTracking();
   }
   catch (mitk::Exception& e)
   {
     emit StopTrackingFinished(false, e.GetDescription());
   }
 
   //restore the original colors of the tools
   for (unsigned int i = 0; i < this->m_NavigationToolStorage->GetToolCount(); i++)
   {
     mitk::DataNode::Pointer currentToolNode = m_NavigationToolStorage->GetTool(i)->GetDataNode();
     if (m_OriginalColors.find(currentToolNode) == m_OriginalColors.end())
     {
       MITK_WARN << "Cannot restore original color of tool " << m_NavigationToolStorage->GetTool(i)->GetToolName();
     }
     else
     {
       currentToolNode->SetColor(m_OriginalColors[currentToolNode]);
     }
   }
 
   // clear map m_OriginalColors
   m_OriginalColors.clear();
 
   //emit signal
   emit StopTrackingFinished(true, "");
 }
 
 void QmitkMITKIGTTrackingToolboxViewWorker::DisconnectDevice()
 {
   try
   {
     if (m_TrackingDeviceSource->IsTracking()) { m_TrackingDeviceSource->StopTracking(); }
     m_TrackingDeviceSource->Disconnect();
     m_TrackingDeviceSource->UnRegisterMicroservice();
 
     m_NavigationToolStorage->UnLockStorage();
 
     m_TrackingDeviceSource = nullptr;
   }
   catch (mitk::Exception& e)
   {
     emit DisconnectDeviceFinished(false, e.GetDescription());
   }
   emit DisconnectDeviceFinished(true, "");
 }
diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp
index 6cc68441e8..e50832db81 100644
--- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp
+++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp
@@ -1,239 +1,240 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center,
 Division of Medical and Biological Informatics.
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 // Qmitk
 #include "QmitkNavigationDataPlayerView.h"
 
 // QT
 #include <QFileDialog>
 #include <QMessageBox>
 
 //mitk
 #include <mitkNavigationDataSet.h>
 #include <mitkNavigationDataReaderInterface.h>
 #include <mitkNavigationDataSequentialPlayer.h>
 #include <mitkNavigationDataPlayer.h>
 #include <mitkVirtualTrackingTool.h>
 #include <mitkIOUtil.h>
 
 // VTK
 #include <vtkSphereSource.h>
 
 const std::string QmitkNavigationDataPlayerView::VIEW_ID = "org.mitk.views.navigationdataplayer";
 
 QmitkNavigationDataPlayerView::QmitkNavigationDataPlayerView()
   : m_Controls( 0 )
 {
 }
 
 QmitkNavigationDataPlayerView::~QmitkNavigationDataPlayerView()
 {
 }
 
 void QmitkNavigationDataPlayerView::CreateQtPartControl( QWidget *parent )
 {
   // build up qt view, unless already done
   if ( !m_Controls )
   {
     // create GUI widgets from the Qt Designer's .ui file
     m_Controls = new Ui::QmitkNavigationDataPlayerViewControls;
     m_Controls->setupUi( parent );
 
     this->CreateConnections();
 
     // make deselected Player invisible
     m_Controls->m_TimedWidget->setVisible(false);
   }
 }
 
 void QmitkNavigationDataPlayerView::SetFocus()
 {
   if ( m_Controls )
   {
     m_Controls->m_grpbxControls->setFocus();
   }
 }
 
 void QmitkNavigationDataPlayerView::CreateConnections()
 {
   connect( m_Controls->m_RdbSequential, SIGNAL(released()), this, SLOT(OnSelectPlayer()) );
   connect( m_Controls->m_RdbTimeBased, SIGNAL(released()), this, SLOT(OnSelectPlayer()) );
   connect( m_Controls->m_BtnOpenFile, SIGNAL(released()), this, SLOT(OnOpenFile()) );
   connect( m_Controls->m_ChkDisplay, SIGNAL(released()), this, SLOT(OnSetDisplay()) );
   connect( m_Controls->m_chkRepeat, SIGNAL(stateChanged(int)), this, SLOT(OnSetRepeat(int)) );
   connect( m_Controls->m_ChkMicroservice, SIGNAL(released()), this, SLOT(OnSetMicroservice()) );
 
   connect( m_Controls->m_SequentialWidget, SIGNAL(SignalUpdate()), this, SLOT(OnUpdate()) );
   connect( m_Controls->m_TimedWidget, SIGNAL(SignalUpdate()), this, SLOT(OnUpdate()) );
 
   this->SetInteractionComponentsEnabledState(false);
 }
 
 void QmitkNavigationDataPlayerView::OnOpenFile()
 {
   mitk::NavigationDataReaderInterface::Pointer reader = nullptr;
 
   QString filter = tr("NavigationData File (*.csv *.xml)");
 
   QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open NavigationData Set"), "", filter);
 
   if ( fileName.isNull() ) { return; } // user pressed cancel
 
   try
   {
     m_Data = dynamic_cast<mitk::NavigationDataSet*> (mitk::IOUtil::Load(fileName.toStdString())[0].GetPointer());
   }
   catch ( const mitk::Exception &e )
   {
     MITK_WARN("NavigationDataPlayerView") << "could not open file " << fileName.toStdString();
     QMessageBox::critical(0, "Error Reading File", "The file '" + fileName
                           +"' could not be read.\n" + e.GetDescription() );
     return;
   }
 
   if (m_Controls->m_ChkConvertToPointSet->isChecked())
     m_Data->ConvertNavigationDataToPointSet();
 
   // Update Labels
   m_Controls->m_LblFilePath->setText(fileName);
   m_Controls->m_LblFrames->setText(QString::number(m_Data->Size()));
   m_Controls->m_LblTools->setText(QString::number(m_Data->GetNumberOfTools()));
 
   // Initialize Widgets and create Player
   this->OnSelectPlayer();
   this->SetInteractionComponentsEnabledState(true);
 }
 
 void QmitkNavigationDataPlayerView::OnSelectPlayer()
 {
   if (m_Controls->m_RdbSequential->isChecked())
   {
     m_Controls->m_SequentialWidget->setVisible(true);
     m_Controls->m_TimedWidget->setVisible(false);
     mitk::NavigationDataSequentialPlayer::Pointer seqPlayer = mitk::NavigationDataSequentialPlayer::New();
     seqPlayer->SetNavigationDataSet(m_Data);
     m_Controls->m_SequentialWidget->SetPlayer(seqPlayer);
     m_Player = seqPlayer;
   } else {
     m_Controls->m_SequentialWidget->setVisible(false);
     m_Controls->m_TimedWidget->setVisible(true);
     mitk::NavigationDataPlayer::Pointer timedPlayer = mitk::NavigationDataPlayer::New();
     timedPlayer->SetNavigationDataSet(m_Data);
     m_Controls->m_TimedWidget->SetPlayer(timedPlayer);
     m_Player = timedPlayer;
   }
 
   this->ConfigurePlayer();
 
   // SetupRenderingPipeline
   this->OnSetDisplay();
 }
 
 void QmitkNavigationDataPlayerView::ConfigurePlayer()
 {
   // set repeat mode according to the checkbox
   m_Player->SetRepeat( m_Controls->m_chkRepeat->isChecked() );
 }
 
 void QmitkNavigationDataPlayerView::OnSetRepeat(int checkState)
 {
   m_Player->SetRepeat(checkState != 0);
 }
 
 void QmitkNavigationDataPlayerView::OnSetMicroservice(){
   if(m_Controls->m_ChkMicroservice->isChecked())
   {
     m_ToolStorage = mitk::NavigationToolStorage::New();
     for (itk::ProcessObject::DataObjectPointerArraySizeType i = 0;
          i < m_Player->GetNumberOfIndexedOutputs(); i++)
     {
       mitk::NavigationTool::Pointer currentDummyTool = mitk::NavigationTool::New();
       mitk::VirtualTrackingTool::Pointer dummyTool = mitk::VirtualTrackingTool::New();
       std::stringstream name;
       name << "Virtual Tool " << i;
       dummyTool->SetToolName(name.str());
       currentDummyTool->SetDataNode(m_RenderingNodes.at(i));
       currentDummyTool->SetIdentifier(name.str());
       m_ToolStorage->AddTool(currentDummyTool);
     }
-    m_Player->RegisterAsMicroservice();
     m_ToolStorage->SetName("NavigationDataPlayer Tool Storage");
-    m_ToolStorage->SetSourceID(m_Player->GetMicroserviceID());
+    m_Player->SetToolMetaDataCollection(m_ToolStorage);
+    m_Player->RegisterAsMicroservice();
+    m_ToolStorage->SetSourceID(m_Player->GetMicroserviceID()); //DEPRECATED / not needed anymore because NavigationDataSource now holds a member of its tool storage. Only left for backward compatibility.
     m_ToolStorage->RegisterAsMicroservice();
   } else {
     if (m_ToolStorage.IsNotNull()) m_ToolStorage->UnRegisterMicroservice();
     m_ToolStorage = nullptr;
     m_Player->UnRegisterMicroservice();
   }
 }
 
 void QmitkNavigationDataPlayerView::OnUpdate(){
   if (m_VisFilter.IsNotNull())
   {
     m_VisFilter->Update();
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkNavigationDataPlayerView::OnSetDisplay(){
   DestroyPipeline();
   if ( (m_Controls->m_ChkDisplay->isChecked()) && ( m_Player.IsNotNull() ))
   {
     CreatePipeline();
   }
 }
 
 void QmitkNavigationDataPlayerView::CreatePipeline(){
   m_VisFilter = mitk::NavigationDataObjectVisualizationFilter::New();
   m_VisFilter->ConnectTo(m_Player);
 
   for (unsigned int i = 0 ; i < m_Player->GetNumberOfIndexedOutputs(); i++ ) {
     mitk::DataNode::Pointer node = mitk::DataNode::New();
     QString name = "Recorded Tool " + QString::number(i + 1);
     node->SetName(name.toStdString());
 
     //create small sphere and use it as surface
     mitk::Surface::Pointer mySphere = mitk::Surface::New();
     vtkSmartPointer<vtkSphereSource> vtkData = vtkSmartPointer<vtkSphereSource>::New();
     vtkData->SetRadius(5.0f);
     vtkData->SetCenter(0.0, 0.0, 0.0);
     vtkData->Update();
     mySphere->SetVtkPolyData(vtkData->GetOutput());
     node->SetData(mySphere);
     m_VisFilter->SetRepresentationObject(i, mySphere);
 
     // Add Node to DataStorageand to local list of Nodes
     GetDataStorage()->Add(node);
     m_RenderingNodes.push_back(node);
   }
   m_VisFilter->Update();
 
   mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(GetDataStorage());
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkNavigationDataPlayerView::DestroyPipeline(){
   m_VisFilter = nullptr;
   for (unsigned int i = 0; i < m_RenderingNodes.size(); i++){
     this->GetDataStorage()->Remove(m_RenderingNodes[i]);
   }
   m_RenderingNodes.clear();
 }
 
 void QmitkNavigationDataPlayerView::SetInteractionComponentsEnabledState(bool isActive){
   m_Controls->m_grpbxSettings->setEnabled(isActive);
   m_Controls->m_grpbxControls->setEnabled(isActive);
 }