diff --git a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.cpp b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.cpp
index 9a79275109..0e9a4a23a8 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.cpp
@@ -1,522 +1,775 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include <QmitkMultiLabelInspector.h>
 
 // mitk
 #include <mitkRenderingManager.h>
+#include <mitkLabelSetImageHelper.h>
 
 // Qmitk
 #include <QmitkMultiLabelTreeModel.h>
 #include <QmitkLabelColorItemDelegate.h>
 #include <QmitkLabelToggleItemDelegate.h>
 #include <QmitkStyleManager.h>
 
 // Qt
 #include <QMenu>
 #include <QLabel>
 #include <QWidgetAction>
 #include <QMessageBox>
 
+#include "ui_QmitkMultiLabelInspectorControls.h"
+
 QmitkMultiLabelInspector::QmitkMultiLabelInspector(QWidget* parent/* = nullptr*/)
-  : QWidget(parent)
+  : QWidget(parent), m_Controls(new Ui::QmitkMultiLabelInspector)
 {
-  m_Controls.setupUi(this);
+  m_Controls->setupUi(this);
 
   m_Model = new QmitkMultiLabelTreeModel(this);
 
-  m_Controls.view->setModel(m_Model);
+  m_Controls->view->setModel(m_Model);
 
   m_ColorItemDelegate = new QmitkLabelColorItemDelegate(this);
 
   auto visibleIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/visible.svg"));
   auto invisibleIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/invisible.svg"));
   m_VisibilityItemDelegate = new QmitkLabelToggleItemDelegate(visibleIcon, invisibleIcon, this);
 
   auto lockIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/lock.svg"));
   auto unlockIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/unlock.svg"));
   m_LockItemDelegate = new QmitkLabelToggleItemDelegate(lockIcon, unlockIcon, this);
 
-  this->m_Controls.view->setItemDelegateForColumn(1, m_LockItemDelegate);
-  this->m_Controls.view->setItemDelegateForColumn(2, m_ColorItemDelegate);
-  this->m_Controls.view->setItemDelegateForColumn(3, m_VisibilityItemDelegate);
+  this->m_Controls->view->setItemDelegateForColumn(1, m_LockItemDelegate);
+  this->m_Controls->view->setItemDelegateForColumn(2, m_ColorItemDelegate);
+  this->m_Controls->view->setItemDelegateForColumn(3, m_VisibilityItemDelegate);
 
-  this->m_Controls.view->header()->setSectionResizeMode(0,QHeaderView::Stretch);
-  this->m_Controls.view->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
-  this->m_Controls.view->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
-  this->m_Controls.view->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
-  this->m_Controls.view->setContextMenuPolicy(Qt::CustomContextMenu);
+  this->m_Controls->view->header()->setSectionResizeMode(0,QHeaderView::Stretch);
+  this->m_Controls->view->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
+  this->m_Controls->view->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
+  this->m_Controls->view->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
+  this->m_Controls->view->setContextMenuPolicy(Qt::CustomContextMenu);
 
   connect(m_Model, &QAbstractItemModel::modelReset, this, &QmitkMultiLabelInspector::OnModelReset);
-  connect(m_Controls.view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), SLOT(ChangeModelSelection(const QItemSelection&, const QItemSelection&)));
-  connect(m_Controls.view, &QAbstractItemView::customContextMenuRequested, this, &QmitkMultiLabelInspector::OnContextMenuRequested);
-  connect(m_Controls.view, &QAbstractItemView::doubleClicked, this, &QmitkMultiLabelInspector::OnItemDoubleClicked);
+  connect(m_Controls->view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), SLOT(OnChangeModelSelection(const QItemSelection&, const QItemSelection&)));
+  connect(m_Controls->view, &QAbstractItemView::customContextMenuRequested, this, &QmitkMultiLabelInspector::OnContextMenuRequested);
+  connect(m_Controls->view, &QAbstractItemView::doubleClicked, this, &QmitkMultiLabelInspector::OnItemDoubleClicked);
+}
+
+QmitkMultiLabelInspector::~QmitkMultiLabelInspector()
+{
+  delete m_Controls;
 }
 
 void QmitkMultiLabelInspector::Initialize()
 {
   m_LastValidSelectedLabels = {};
+  m_ModelManipulationOngoing = false;
   m_Model->SetSegmentation(m_Segmentation);
-  m_Controls.view->expandAll();
+  m_Controls->view->expandAll();
 }
 
 void QmitkMultiLabelInspector::SetMultiSelectionMode(bool multiMode)
 {
   if (multiMode)
   {
-    m_Controls.view->setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);
+    m_Controls->view->setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);
   }
   else
   {
-    m_Controls.view->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
+    m_Controls->view->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
   }
 }
 
 bool QmitkMultiLabelInspector::GetMultiSelectionMode() const
 {
-  return QAbstractItemView::SelectionMode::MultiSelection == m_Controls.view->selectionMode();
+  return QAbstractItemView::SelectionMode::MultiSelection == m_Controls->view->selectionMode();
 }
 
 void QmitkMultiLabelInspector::SetAllowVisibilityModification(bool vmod)
 {
   m_AllowVisibilityModification = vmod;
+  this->m_Model->SetAllowVisibilityModification(vmod);
+}
+
+void QmitkMultiLabelInspector::SetAllowLabelModification(bool labelMod)
+{
+  m_AllowLabelModification = labelMod;
 }
 
 bool QmitkMultiLabelInspector::GetAllowVisibilityModification() const
 {
   return m_AllowVisibilityModification;
 }
 
 void QmitkMultiLabelInspector::SetAllowLockModification(bool lmod)
 {
   m_AllowLockModification = lmod;
+  this->m_Model->SetAllowLockModification(lmod);
 }
 
 bool QmitkMultiLabelInspector::GetAllowLockModification() const
 {
   return m_AllowLockModification;
 }
 
+bool QmitkMultiLabelInspector::GetAllowLabelModification() const
+{
+  return m_AllowLabelModification;
+}
+
+void QmitkMultiLabelInspector::SetDefaultLabelNaming(bool defaultLabelNaming)
+{
+  m_DefaultLabelNaming = defaultLabelNaming;
+}
+
 void QmitkMultiLabelInspector::SetMultiLabelSegmentation(mitk::LabelSetImage* segmentation)
 {
   if (segmentation != m_Segmentation)
   {
     m_Segmentation = segmentation;
     this->Initialize();
   }
 }
 
 void QmitkMultiLabelInspector::OnModelReset()
 {
   m_LastValidSelectedLabels = {};
+  m_ModelManipulationOngoing = false;
 }
 
 bool EqualLabelSelections(const QmitkMultiLabelInspector::LabelValueVectorType& selection1, const QmitkMultiLabelInspector::LabelValueVectorType& selection2)
 {
   if (selection1.size() == selection2.size())
   {
     // lambda to compare node pointer inside both lists
     auto lambda = [](mitk::LabelSetImage::LabelValueType lhs, mitk::LabelSetImage::LabelValueType rhs) { return lhs == rhs; };
     return std::is_permutation(selection1.begin(), selection1.end(), selection2.begin(), selection2.end(), lambda);
   }
 
   return false;
 }
 
 void QmitkMultiLabelInspector::SetSelectedLabels(const LabelValueVectorType& selectedLabels)
 {
   bool equal = EqualLabelSelections(this->GetSelectedLabels(), selectedLabels);
   if (equal)
   {
     return;
   }
 
   this->UpdateSelectionModel(selectedLabels);
   m_LastValidSelectedLabels = selectedLabels;
 }
 
 void QmitkMultiLabelInspector::UpdateSelectionModel(const LabelValueVectorType& selectedLabels)
 {
   // create new selection by retrieving the corresponding indices of the labels
   QItemSelection newCurrentSelection;
   for (const auto& labelID : selectedLabels)
   {
-    QModelIndexList matched = m_Model->match(m_Model->index(0, 0), QmitkMultiLabelTreeModel::ItemModelRole::LabelValueRole, QVariant(labelID), 1, Qt::MatchRecursive);
+    QModelIndexList matched = m_Model->match(m_Model->index(0, 0), QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole, QVariant(labelID), 1, Qt::MatchRecursive);
     if (!matched.empty())
     {
+      auto f = matched.front();
+      auto d = f.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelDataRole);
       newCurrentSelection.select(matched.front(), matched.front());
     }
   }
 
-  m_Controls.view->selectionModel()->select(newCurrentSelection, QItemSelectionModel::ClearAndSelect);
+  m_Controls->view->selectionModel()->select(newCurrentSelection, QItemSelectionModel::ClearAndSelect);
 }
 
 void QmitkMultiLabelInspector::SetSelectedLabel(mitk::LabelSetImage::LabelValueType selectedLabel)
 {
   this->SetSelectedLabels({ selectedLabel });
 }
 
 QmitkMultiLabelInspector::LabelValueVectorType QmitkMultiLabelInspector::GetSelectedLabelsFromSelectionModel() const
 {
   LabelValueVectorType result;
-  QModelIndexList selectedIndexes = m_Controls.view->selectionModel()->selectedIndexes();
+  QModelIndexList selectedIndexes = m_Controls->view->selectionModel()->selectedIndexes();
   for (const auto& index : qAsConst(selectedIndexes))
   {
-    QVariant qvariantDataNode = m_Model->data(index, QmitkMultiLabelTreeModel::ItemModelRole::LabelValueRole);
+    QVariant qvariantDataNode = m_Model->data(index, QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
     if (qvariantDataNode.canConvert<mitk::LabelSetImage::LabelValueType>())
     {
       result.push_back(qvariantDataNode.value<mitk::LabelSetImage::LabelValueType>());
     }
   }
   return result;
 }
 
 QmitkMultiLabelInspector::LabelValueVectorType QmitkMultiLabelInspector::GetSelectedLabels() const
 {
   return m_LastValidSelectedLabels;
 }
 
-void QmitkMultiLabelInspector::ChangeModelSelection(const QItemSelection& selected, const QItemSelection& deselected)
+mitk::Label* QmitkMultiLabelInspector::GetFirstSelectedLabelObject() const
 {
-  auto internalSelection = GetSelectedLabelsFromSelectionModel();
-  if (internalSelection.empty())
-  {
-    //empty selections are not allowed by UI interactions, there should always be at least on label selected.
-    //but selections are e.g. also cleared if the model is updated (e.g. due to addition of labels)
-    UpdateSelectionModel(m_LastValidSelectedLabels);
-  }
-  else
+  if (m_LastValidSelectedLabels.empty() || m_Segmentation.IsNull()) return nullptr;
+
+  return m_Segmentation->GetLabel(m_LastValidSelectedLabels.front());
+}
+
+void QmitkMultiLabelInspector::OnChangeModelSelection(const QItemSelection& selected, const QItemSelection& deselected)
+{
+  if (!m_ModelManipulationOngoing)
   {
-    m_LastValidSelectedLabels = internalSelection;
-    emit CurrentSelectionChanged(GetSelectedLabels());
+    auto internalSelection = GetSelectedLabelsFromSelectionModel();
+    if (internalSelection.empty())
+    {
+      //empty selections are not allowed by UI interactions, there should always be at least on label selected.
+      //but selections are e.g. also cleared if the model is updated (e.g. due to addition of labels)
+      UpdateSelectionModel(m_LastValidSelectedLabels);
+    }
+    else
+    {
+      m_LastValidSelectedLabels = internalSelection;
+      emit CurrentSelectionChanged(GetSelectedLabels());
+    }
   }
 }
 
 void QmitkMultiLabelInspector::WaitCursorOn() const
 {
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 }
 
 void QmitkMultiLabelInspector::WaitCursorOff() const
 {
   this->RestoreOverrideCursor();
 }
 
 void QmitkMultiLabelInspector::RestoreOverrideCursor() const
 {
   QApplication::restoreOverrideCursor();
 }
 
 mitk::Label* QmitkMultiLabelInspector::GetCurrentLabel() const
 {
-  auto currentIndex = this->m_Controls.view->currentIndex();
+  auto currentIndex = this->m_Controls->view->currentIndex();
   auto labelVariant = currentIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelDataRole);
   mitk::Label::Pointer currentIndexLabel = nullptr;
 
   if (labelVariant.isValid())
   {
     auto uncastedLabel = labelVariant.value<void*>();
     currentIndexLabel = static_cast<mitk::Label*>(uncastedLabel);
   }
   return currentIndexLabel;
 }
 
+mitk::Label* QmitkMultiLabelInspector::AddNewLabelInstance()
+{
+  if (!m_AllowLabelModification)
+    mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of AddNewLabelInstance.";
+
+  auto currentLabel = this->GetFirstSelectedLabelObject();
+  if (nullptr == currentLabel)
+    return nullptr;
+
+  auto groupID = m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
+  auto group = m_Segmentation->GetLabelSet(groupID);
+  m_ModelManipulationOngoing = true;
+  auto newLabel = group->AddLabel(currentLabel, true);
+  m_ModelManipulationOngoing = false;
+  this->SetSelectedLabel(newLabel->GetValue());
+
+  auto index = m_Model->indexOfLabel(newLabel->GetValue());
+  if (index.isValid())
+  {
+    m_Controls->view->expand(index.parent());
+  }
+  else
+  {
+    mitkThrow() << "Segmentation or QmitkMultiLabelTreeModel is in an invalid state. Label is not present in the model after adding it to the segmentation. Label value: " << newLabel->GetValue();
+  }
+
+  return newLabel;
+}
+
+mitk::Label* QmitkMultiLabelInspector::AddNewLabelInternal(const mitk::LabelSetImage::SpatialGroupIndexType& containingGroup)
+{
+  mitk::Label::Pointer newLabel = mitk::LabelSetImageHelper::CreateNewLabel(m_Segmentation);
+
+  if (!m_DefaultLabelNaming)
+  {
+    // TODO
+  }
+
+  auto group = m_Segmentation->GetLabelSet(containingGroup);
+  m_ModelManipulationOngoing = true;
+  group->AddLabel(newLabel, false);
+  m_ModelManipulationOngoing = false;
+  this->SetSelectedLabel(newLabel->GetValue());
+
+  auto index = m_Model->indexOfLabel(newLabel->GetValue());
+  if (index.isValid())
+  {
+    m_Controls->view->expand(index.parent());
+  }
+  else
+  {
+    mitkThrow() << "Segmentation or QmitkMultiLabelTreeModel is in an invalid state. Label is not present in the model after adding it to the segmentation. Label value: " << newLabel->GetValue();
+  }
+
+  return newLabel;
+}
+
+mitk::Label* QmitkMultiLabelInspector::AddNewLabel()
+{
+  //todo das sollte eigentlich weg gelassen werden k�nnen.
+  //Wenn beim Testen kein problem auff�llt, dann kann die Zeile wirklich raus.
+  //m_ToolManager->ActivateTool(-1);
+  if (!m_AllowLabelModification)
+    mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of AddNewLabel.";
+
+  if (m_Segmentation.IsNull())
+  {
+    return nullptr;
+  }
+
+  auto currentLabel = this->GetFirstSelectedLabelObject();
+  mitk::LabelSetImage::SpatialGroupIndexType groupID = nullptr == currentLabel ? 0 : m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
+
+  return AddNewLabelInternal(groupID);
+}
+
+void QmitkMultiLabelInspector::RemoveLabel()
+{
+  if (!m_AllowLabelModification)
+    mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of RemoveLabel.";
+
+  if (m_Segmentation.IsNull())
+  {
+    return;
+  }
+
+  auto currentLabel = GetFirstSelectedLabelObject();
+  QString question = "Do you really want to remove label \"";
+  question.append(
+    QString::fromStdString(currentLabel->GetName()));
+  question.append("\"?");
+
+  QMessageBox::StandardButton answerButton =
+    QMessageBox::question(this, "Remove label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
+
+  if (answerButton == QMessageBox::Yes)
+  {
+    auto currentIndex = m_Model->indexOfLabel(currentLabel->GetValue());
+    auto nextIndex = m_Model->ClosestLabelInstanceIndex(currentIndex);
+    auto labelVariant = nextIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
+
+    this->WaitCursorOn();
+    m_ModelManipulationOngoing = true;
+    m_Segmentation->RemoveLabel(currentLabel->GetValue());
+    m_ModelManipulationOngoing = false;
+    this->WaitCursorOff();
+
+    if (labelVariant.isValid())
+    {
+      auto newLabelValue = labelVariant.value<LabelValueType>();
+      this->SetSelectedLabel(newLabelValue);
+
+      auto index = m_Model->indexOfLabel(newLabelValue); //we have to get index again, because it could have changed due to remove operation.
+      if (index.isValid())
+      {
+        m_Controls->view->expand(index.parent());
+      }
+      else
+      {
+        mitkThrow() << "Segmentation or QmitkMultiLabelTreeModel is in an invalid state. Label is not present in the model after adding it to the segmentation. Label value: " << newLabelValue;
+      }
+    }
+
+    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+  }
+}
+
+mitk::Label* QmitkMultiLabelInspector::AddNewGroup()
+{
+  if (!m_AllowLabelModification)
+    mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of AddNewLabel.";
+
+  if (m_Segmentation.IsNull())
+  {
+    return nullptr;
+  }
+
+  mitk::LabelSetImage::SpatialGroupIndexType groupID = 0;
+  mitk::Label* newLabel = nullptr;
+  m_ModelManipulationOngoing = true;
+  try
+  {
+    this->WaitCursorOn();
+    groupID = m_Segmentation->AddLayer();
+    this->WaitCursorOff();
+    newLabel =  AddNewLabelInternal(groupID);
+  }
+  catch (mitk::Exception& e)
+  {
+    this->WaitCursorOff();
+    m_ModelManipulationOngoing = false;
+    MITK_ERROR << "Exception caught: " << e.GetDescription();
+    QMessageBox::information(
+      this, "Add layer", "Could not add a new layer. See error log for details.\n");
+  }
+  m_ModelManipulationOngoing = false;
+
+  return newLabel;
+}
+
+void QmitkMultiLabelInspector::RemoveGroup()
+{
+  if (!m_AllowLabelModification)
+    mitkThrow() << "QmitkMultiLabelInspector is configured incorrectly. Set AllowLabelModification to true to allow the usage of RemoveLabel.";
+
+  if (m_Segmentation.IsNull())
+  {
+    return;
+  }
+
+  QString question = "Do you really want to delete the current layer with all labels?";
+  QMessageBox::StandardButton answerButton = QMessageBox::question(
+    this, "Delete layer", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
+
+  if (answerButton != QMessageBox::Yes)
+  {
+    return;
+  }
+
+  auto currentLabel = GetFirstSelectedLabelObject();
+  const auto currentGroup = m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
+
+  auto currentIndex = m_Model->indexOfGroup(currentGroup);
+  auto nextIndex = m_Model->ClosestLabelInstanceIndex(currentIndex);
+  auto labelVariant = nextIndex.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
+
+  try
+  {
+    this->WaitCursorOn();
+    m_ModelManipulationOngoing = true;
+    m_Segmentation->RemoveSpatialGroup(currentGroup);
+    m_ModelManipulationOngoing = false;
+    this->WaitCursorOff();
+  }
+  catch (mitk::Exception& e)
+  {
+    m_ModelManipulationOngoing = false;
+    this->WaitCursorOff();
+    MITK_ERROR << "Exception caught: " << e.GetDescription();
+    QMessageBox::information(
+      this, "Delete layer", "Could not delete the currently active layer. See error log for details.\n");
+    return;
+  }
+
+  if (labelVariant.isValid())
+  {
+    auto newLabelValue = labelVariant.value<LabelValueType>();
+    this->SetSelectedLabel(newLabelValue);
+
+    auto index = m_Model->indexOfLabel(newLabelValue); //we have to get index again, because it could have changed due to remove operation.
+    if (index.isValid())
+    {
+      m_Controls->view->expand(index.parent());
+    }
+    else
+    {
+      mitkThrow() << "Segmentation or QmitkMultiLabelTreeModel is in an invalid state. Label is not present in the model after adding it to the segmentation. Label value: " << newLabelValue;
+    }
+  }
+
+  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+}
+
 void QmitkMultiLabelInspector::OnContextMenuRequested(const QPoint& pos)
 {
   auto selectedLabelValues = this->GetSelectedLabels();
-  auto currentLabel = this->GetCurrentLabel();
-  if (nullptr== currentLabel)
+  if (m_Segmentation.IsNull() || !this->isEnabled() || selectedLabelValues.empty())
     return;
 
   QMenu* menu = new QMenu(this);
 
   if (this->GetMultiSelectionMode() && selectedLabelValues.size()>1)
   {
     QAction* mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge selection on current label", this);
     mergeAction->setEnabled(true);
     QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabels(bool)));
     menu->addAction(mergeAction);
 
     QAction* removeLabelsAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove selected labels", this);
     removeLabelsAction->setEnabled(true);
     QObject::connect(removeLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabels(bool)));
     menu->addAction(removeLabelsAction);
 
     QAction* eraseLabelsAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase selected labels", this);
     eraseLabelsAction->setEnabled(true);
     QObject::connect(eraseLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabels(bool)));
     menu->addAction(eraseLabelsAction);
   }
   else
   {
     if (m_AllowLabelModification)
     {
+      QAction* addInstanceAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Add label instance...", this);
+      addInstanceAction->setEnabled(true);
+      QObject::connect(addInstanceAction, &QAction::triggered, this, &QmitkMultiLabelInspector::AddNewLabelInstance);
+      menu->addAction(addInstanceAction);
+
       QAction* renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Rename...", this);
       renameAction->setEnabled(true);
       QObject::connect(renameAction, SIGNAL(triggered(bool)), this, SLOT(OnRenameLabel(bool)));
       menu->addAction(renameAction);
 
       QAction* removeAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove...", this);
       removeAction->setEnabled(true);
-      QObject::connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabel(bool)));
+      QObject::connect(removeAction, &QAction::triggered, this, &QmitkMultiLabelInspector::RemoveLabel);
       menu->addAction(removeAction);
 
       QAction* eraseAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase...", this);
       eraseAction->setEnabled(true);
       QObject::connect(eraseAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabel(bool)));
       menu->addAction(eraseAction);
     }
 
     if (m_AllowLockModification)
     {
       QAction* lockAllAction = new QAction(QIcon(":/Qmitk/lock.png"), "Lock all", this);
       lockAllAction->setEnabled(true);
       QObject::connect(lockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnLockAllLabels(bool)));
       menu->addAction(lockAllAction);
 
       QAction* unlockAllAction = new QAction(QIcon(":/Qmitk/unlock.png"), "Unlock all", this);
       unlockAllAction->setEnabled(true);
       QObject::connect(unlockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnUnlockAllLabels(bool)));
       menu->addAction(unlockAllAction);
     }
 
     if (m_AllowVisibilityModification)
     {
       QAction* viewOnlyAction = new QAction(QIcon(":/Qmitk/visible.png"), "View only", this);
       viewOnlyAction->setEnabled(true);
       QObject::connect(viewOnlyAction, SIGNAL(triggered(bool)), this, SLOT(OnSetOnlyActiveLabelVisible(bool)));
       menu->addAction(viewOnlyAction);
 
       QAction* viewAllAction = new QAction(QIcon(":/Qmitk/visible.png"), "View all", this);
       viewAllAction->setEnabled(true);
       QObject::connect(viewAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsVisible(bool)));
       menu->addAction(viewAllAction);
 
       QAction* hideAllAction = new QAction(QIcon(":/Qmitk/invisible.png"), "Hide all", this);
       hideAllAction->setEnabled(true);
       QObject::connect(hideAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsInvisible(bool)));
       menu->addAction(hideAllAction);
 
       QSlider* opacitySlider = new QSlider;
       opacitySlider->setMinimum(0);
       opacitySlider->setMaximum(100);
       opacitySlider->setOrientation(Qt::Horizontal);
+      auto currentLabel = this->GetFirstSelectedLabelObject();
       auto opacity = currentLabel->GetOpacity();
       opacitySlider->setValue(static_cast<int>(opacity * 100));
       auto segmentation = m_Segmentation;
       QObject::connect(opacitySlider, &QSlider::valueChanged, this, [segmentation, currentLabel](const int value)
       {
         float opacity = static_cast<float>(value) / 100.0f;
         currentLabel->SetOpacity(opacity);
         auto groupID = segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
         auto group = segmentation->GetLabelSet(groupID);
         group->UpdateLookupTable(currentLabel->GetValue());
       }
       );
       QLabel* _OpacityLabel = new QLabel("Opacity: ");
       QVBoxLayout* _OpacityWidgetLayout = new QVBoxLayout;
       _OpacityWidgetLayout->setContentsMargins(4, 4, 4, 4);
       _OpacityWidgetLayout->addWidget(_OpacityLabel);
       _OpacityWidgetLayout->addWidget(opacitySlider);
       QWidget* _OpacityWidget = new QWidget;
       _OpacityWidget->setLayout(_OpacityWidgetLayout);
       QWidgetAction* OpacityAction = new QWidgetAction(this);
       OpacityAction->setDefaultWidget(_OpacityWidget);
       menu->addAction(OpacityAction);
     }
 
 
   }
   menu->popup(QCursor::pos());
 }
 
 void QmitkMultiLabelInspector::OnEraseLabels(bool /*value*/)
 {
   QString question = "Do you really want to erase the selected labels?";
 
   QMessageBox::StandardButton answerButton = QMessageBox::question(
     this, "Erase selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->WaitCursorOn();
     m_Segmentation->EraseLabels(this->GetSelectedLabels());
     this->WaitCursorOff();
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
 void QmitkMultiLabelInspector::OnRemoveLabels(bool /*value*/)
 {
   QString question = "Do you really want to remove the selected labels?";
   QMessageBox::StandardButton answerButton = QMessageBox::question(
     this, "Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->WaitCursorOn();
-    m_Segmentation->RemoveLabels(this->GetSelectedLabels(), m_Segmentation->GetActiveLayer());
+    m_Segmentation->RemoveLabels(this->GetSelectedLabels());
     this->WaitCursorOff();
   }
 }
 
 void QmitkMultiLabelInspector::OnMergeLabels(bool /*value*/)
 {
   auto currentLabel = GetCurrentLabel();
   QString question = "Do you really want to merge selected labels into \"";
   question.append(
     QString::fromStdString(currentLabel->GetName()));
   question.append("\"?");
 
   QMessageBox::StandardButton answerButton = QMessageBox::question(
     this, "Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->WaitCursorOn();
     m_Segmentation->MergeLabels(currentLabel->GetValue(), this->GetSelectedLabels(), m_Segmentation->GetActiveLayer());
     this->WaitCursorOff();
 
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
+void QmitkMultiLabelInspector::OnAddLabelInstance(bool /*value*/)
+{
+  this->AddNewLabelInstance();
+}
+
 void QmitkMultiLabelInspector::OnEraseLabel(bool /*value*/)
 {
-  auto currentLabel = GetCurrentLabel();
+  auto currentLabel = GetFirstSelectedLabelObject();
   QString question = "Do you really want to erase the contents of label \"";
   question.append(
     QString::fromStdString(currentLabel->GetName()));
   question.append("\"?");
 
   QMessageBox::StandardButton answerButton =
     QMessageBox::question(this, "Erase label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
 
   if (answerButton == QMessageBox::Yes)
   {
     this->WaitCursorOn();
     m_Segmentation->EraseLabel(currentLabel->GetValue());
     this->WaitCursorOff();
     mitk::RenderingManager::GetInstance()->RequestUpdateAll();
   }
 }
 
-void QmitkMultiLabelInspector::OnRemoveLabel(bool /*value*/)
-{
-  auto currentLabel = GetCurrentLabel();
-  QString question = "Do you really want to remove label \"";
-  question.append(
-    QString::fromStdString(currentLabel->GetName()));
-  question.append("\"?");
-
-  QMessageBox::StandardButton answerButton =
-    QMessageBox::question(this, "Remove label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
-
-  if (answerButton == QMessageBox::Yes)
-  {
-    this->WaitCursorOn();
-    m_Segmentation->RemoveLabel(currentLabel->GetValue(), m_Segmentation->GetActiveLayer());
-    this->WaitCursorOff();
-  }
-}
-
 void QmitkMultiLabelInspector::OnRenameLabel(bool /*value*/)
 {
  //TODO
 }
 
 void QmitkMultiLabelInspector::OnUnlockAllLabels(bool /*value*/)
 {
-  auto currentLabel = GetCurrentLabel();
+  auto currentLabel = GetFirstSelectedLabelObject();
 
   auto groupID = m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
   auto group = m_Segmentation->GetLabelSet(groupID);
   group->SetAllLabelsLocked(false);
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkMultiLabelInspector::OnLockAllLabels(bool /*value*/)
 {
-  auto currentLabel = GetCurrentLabel();
+  auto currentLabel = GetFirstSelectedLabelObject();
 
   auto groupID = m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
   auto group = m_Segmentation->GetLabelSet(groupID);
   group->SetAllLabelsLocked(true);
   mitk::RenderingManager::GetInstance()->RequestUpdateAll();
 }
 
 void QmitkMultiLabelInspector::OnSetAllLabelsVisible(bool /*value*/)
 {
-  auto currentLabel = GetCurrentLabel();
+  auto currentLabel = GetFirstSelectedLabelObject();
 
   auto groupID = m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
   auto group = m_Segmentation->GetLabelSet(groupID);
   group->SetAllLabelsVisible(true);
 }
 
 void QmitkMultiLabelInspector::OnSetAllLabelsInvisible(bool /*value*/)
 {
-  auto currentLabel = GetCurrentLabel();
+  auto currentLabel = GetFirstSelectedLabelObject();
 
   auto groupID = m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
   auto group = m_Segmentation->GetLabelSet(groupID);
   group->SetAllLabelsVisible(false);
 }
 
 void QmitkMultiLabelInspector::OnSetOnlyActiveLabelVisible(bool /*value*/)
 {
-  auto currentLabel = GetCurrentLabel();
+  auto currentLabel = GetFirstSelectedLabelObject();
   const auto labelID = currentLabel->GetValue();
   auto groupID = m_Segmentation->GetGroupIndexOfLabel(currentLabel->GetValue());
   auto group = m_Segmentation->GetLabelSet(groupID);
   group->SetAllLabelsVisible(false);
   currentLabel->SetVisible(true);
 
   group->UpdateLookupTable(labelID);
 
   this->PrepareGoToLabel(labelID);
 }
 
 void QmitkMultiLabelInspector::OnItemDoubleClicked(const QModelIndex& index)
 {
   if (!index.isValid()) return;
+  if (index.column() > 0) return;
 
-  auto labelVariant = index.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelValueRole);
+  auto labelVariant = index.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
 
   if (!labelVariant.isValid()) return;
 
   const auto labelID = labelVariant.value<mitk::Label::PixelType>();
 
   if (QApplication::queryKeyboardModifiers().testFlag(Qt::AltModifier))
   {
-    this->OnRemoveLabel(false);
-//  t  this->OnRenameLabelShortcutActivated();
+    this->OnRenameLabel(false);
     return;
   }
 
   this->PrepareGoToLabel(labelID);
 }
 
 void QmitkMultiLabelInspector::PrepareGoToLabel(mitk::Label::PixelType labelID) const
 {
   this->WaitCursorOn();
   m_Segmentation->UpdateCenterOfMass(labelID);
   const auto currentLabel = m_Segmentation->GetLabel(labelID);
   const mitk::Point3D& pos = currentLabel->GetCenterOfMassCoordinates();
   this->WaitCursorOff();
 
   if (pos.GetVnlVector().max_value() > 0.0)
   {
     emit GoToLabel(currentLabel->GetValue(), pos);
   }
 }
 
diff --git a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.h b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.h
index 10d9e1fc0a..ddf55e1f08 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelInspector.h
@@ -1,153 +1,211 @@
 /*============================================================================
 
 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 QMITKMULTILABELSEGMENTATIONINSPECTOR_H
 #define QMITKMULTILABELSEGMENTATIONINSPECTOR_H
 
 #include <MitkSegmentationUIExports.h>
 #include <mitkWeakPointer.h>
 
 #include <QWidget>
 #include <QmitkMultiLabelTreeModel.h>
 #include "ui_QmitkMultiLabelInspectorControls.h"
 
 class QmitkMultiLabelTreeModel;
 class QStyledItemDelegate;
 
+namespace Ui
+{
+  class QmitkMultiLabelInspector;
+}
+
 /*
 * @brief This is an inspector that offers a simple list view on a data storage.
 */
 class MITKSEGMENTATIONUI_EXPORT QmitkMultiLabelInspector : public QWidget
 {
   Q_OBJECT
 
 public:
   QmitkMultiLabelInspector(QWidget* parent = nullptr);
+  ~QmitkMultiLabelInspector();
 
   bool GetMultiSelectionMode() const;
 
   bool GetAllowVisibilityModification() const;
   bool GetAllowLockModification() const;
+  bool GetAllowLabelModification() const;
 
+  using LabelValueType = mitk::LabelSetImage::LabelValueType;
   using LabelValueVectorType = mitk::LabelSetImage::LabelValueVectorType;
 
   /**
   * @brief Retrieve the currently selected labels (equals the last CurrentSelectionChanged values).
   */
   LabelValueVectorType GetSelectedLabels() const;
 
   /** Returns the label that currently has the focus in the tree view (indicated by QTreeView::currentIndex,
   thus the mouse is over it and it has a dashed border line).
   The current label must not equal the seleted label(s). If the mouse
   is not over a label (instance item), the method will return a null pointer.*/
   mitk::Label* GetCurrentLabel() const;
 
+
 Q_SIGNALS:
   /**
   * @brief A signal that will be emitted if the selected labels change.
   *
   * @param labels A list of label values that are now selected.
   */
   void CurrentSelectionChanged(LabelValueVectorType labels) const;
 
-  void GoToLabel(mitk::LabelSetImage::LabelValueType label, const mitk::Point3D&) const;
+  void GoToLabel(LabelValueType label, const mitk::Point3D&) const;
 
 public Q_SLOTS:
 
   /**
-  * @brief Transform a list label values into a model selection and set this as a new selection of the view
-  *
-  * @param selectedNodes A list of data nodes that should be newly selected.
+  * @brief Transform a list label values into the new selection of the inspector.
+  * @param selectedNodes A list of selected label values.
+  * @remark Using this method to select labels will not trigger the CurrentSelectionChanged signal. Observers
+  * should regard that to avoid signal loops.
   */
   void SetSelectedLabels(const LabelValueVectorType& selectedLabels);
+  /**
+  * @brief The passed label will be used as new selection in the widget
+  * @param selectedLabel Value of the selected label.
+  * @remark Using this method to select labels will not trigger the CurrentSelectionChanged signal. Observers
+  * should regard that to avoid signal loops.
+  */
   void SetSelectedLabel(mitk::LabelSetImage::LabelValueType selectedLabel);
 
   /**
   * @brief Sets the segmentation that will be used /monitored by the widget.
   *
   * @param segmentation      A pointer to the segmentation to set.
   */
   void SetMultiLabelSegmentation(mitk::LabelSetImage* segmentation);
 
   void SetMultiSelectionMode(bool multiMode);
 
   void SetAllowVisibilityModification(bool vmod);
   void SetAllowLockModification(bool lmod);
+  void SetAllowLabelModification(bool labelMod);
+
+  void SetDefaultLabelNaming(bool defaultLabelNaming);
+
+  /** Adds an instance of the same label/class like the label instance
+  * returned by GetCurrentLabel() to the segmentation. This new label
+  * instance is returned by the function. If the inspector has no current label,
+  * no new instance will be generated and nullptr will be returned.
+  * @remark The new label instance is a clone of current label instance. Therefore
+  * all properties but the LabelValue will be the same.
+  * @pre AllowLabeModification must be set to true.*/
+  mitk::Label* AddNewLabelInstance();
+
+  /** Adds a new label to the segmentation. Depending on the settings the name of
+  * the label will be either default generated or the rename delegate will be used.
+  * @pre AllowLabeModification must be set to true.*/
+  mitk::Label* AddNewLabel();
+
+  /** Removes the first currently selected label of the segmentation. If no label is selected
+  * nothing will happen.
+  * @pre AllowLabeModification must be set to true.*/
+  void RemoveLabel();
+
+  /** Adds a new group with a new label to segmentation.
+  * @pre AllowLabeModification must be set to true.*/
+  mitk::Label* AddNewGroup();
+
+  /** Removes the group of the first currently selected label of the segmentation. If no label is selected
+  * nothing will happen.
+  * @pre AllowLabeModification must be set to true.*/
+  void RemoveGroup();
+
 
 protected:
   void Initialize();
   void OnModelReset();
 
   QmitkMultiLabelTreeModel* m_Model;
   mitk::LabelSetImage::Pointer m_Segmentation;
 
   LabelValueVectorType m_LastValidSelectedLabels;
   QStyledItemDelegate* m_LockItemDelegate;
   QStyledItemDelegate* m_ColorItemDelegate;
   QStyledItemDelegate* m_VisibilityItemDelegate;
 
-  Ui_QmitkMultiLabelInspector m_Controls;
+  Ui::QmitkMultiLabelInspector* m_Controls;
 
   LabelValueVectorType GetSelectedLabelsFromSelectionModel() const;
   void UpdateSelectionModel(const LabelValueVectorType& selectedLabels);
 
-  bool m_ShowVisibility = true;
-  bool m_ShowLock = true;
-  bool m_ShowOther = false;
+  /** Helper that returns the label object (if multiple labels are selected the first).*/
+  mitk::Label* GetFirstSelectedLabelObject() const;
+
+  mitk::Label* AddNewLabelInternal(const mitk::LabelSetImage::SpatialGroupIndexType& containingGroup);
 
-  /** Indicates if the context menu allows changes in visiblity.
-      Visiblity includes also color*/
-  bool m_AllowVisibilityModification = true;
-  bool m_AllowLockModification = true;
-  bool m_AllowLabelModification = false;
 
 private Q_SLOTS:
   /**
   * @brief Transform a labels selection into a data node list and emit the 'CurrentSelectionChanged'-signal.
   *
   *   The function adds the selected nodes from the original selection that could not be modified, if
   *   'm_SelectOnlyVisibleNodes' is false.
   *   This slot is internally connected to the 'selectionChanged'-signal of the selection model of the private member item view.
   *
   * @param selected	The newly selected items.
   * @param deselected	The newly deselected items.
   */
-  void ChangeModelSelection(const QItemSelection& selected, const QItemSelection& deselected);
+  void OnChangeModelSelection(const QItemSelection& selected, const QItemSelection& deselected);
 
   void OnContextMenuRequested(const QPoint&);
 
+  void OnAddLabelInstance(bool);
   void OnRemoveLabels(bool);
   void OnEraseLabels(bool);
   void OnMergeLabels(bool);
 
-  void OnRemoveLabel(bool);
   void OnRenameLabel(bool);
   void OnEraseLabel(bool);
 
   void OnUnlockAllLabels(bool);
   void OnLockAllLabels(bool);
 
   void OnSetAllLabelsVisible(bool);
   void OnSetAllLabelsInvisible(bool);
   void OnSetOnlyActiveLabelVisible(bool);
 
   void OnItemDoubleClicked(const QModelIndex& index);
 
   void WaitCursorOn() const;
   void WaitCursorOff() const;
   void RestoreOverrideCursor() const;
 
-  void PrepareGoToLabel(mitk::Label::PixelType labelID) const;
+  void PrepareGoToLabel(LabelValueType labelID) const;
+
+private:
+  bool m_ShowVisibility = true;
+  bool m_ShowLock = true;
+  bool m_ShowOther = false;
+
+  /** Indicates if the context menu allows changes in visiblity.
+      Visiblity includes also color*/
+  bool m_AllowVisibilityModification = true;
+  bool m_AllowLockModification = true;
+  bool m_AllowLabelModification = false;
+
+  bool m_DefaultLabelNaming = true;
 
+  bool m_ModelManipulationOngoing = false;
 };
 
 #endif // QMITKDATASTORAGELISTINSPECTOR_H
diff --git a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.cpp b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.cpp
index 36c36d230b..c008040ffe 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.cpp
@@ -1,733 +1,896 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "QmitkMultiLabelTreeModel.h"
 
 #include "mitkImageStatisticsContainerManager.h"
 #include "mitkProportionalTimeGeometry.h"
 #include "mitkStatisticsToImageRelationRule.h"
 #include "mitkStatisticsToMaskRelationRule.h"
 
 #include "QmitkStyleManager.h"
 
 
 class QmitkMultiLabelSegTreeItem
 {
 public:
   enum class ItemType
   {
     Group,
     Label,
     Instance
   };
 
   QmitkMultiLabelSegTreeItem()
   {
   };
 
   explicit QmitkMultiLabelSegTreeItem(ItemType type, QmitkMultiLabelSegTreeItem* parentItem,
     mitk::Label* label = nullptr, std::string className = ""): m_ItemType(type), m_Label(label), m_parentItem(parentItem), m_ClassName(className)
   {
   };
 
   ~QmitkMultiLabelSegTreeItem()
   {
     for (auto item : m_childItems)
     {
       delete item;
     }
   };
 
   void AppendChild(QmitkMultiLabelSegTreeItem* child)
   {
       m_childItems.push_back(child);
   };
 
   void RemoveChild(std::size_t row)
   {
     if (row < m_childItems.size())
     {
       delete m_childItems[row];
       m_childItems.erase(m_childItems.begin() + row);
     }
   };
 
   int Row() const
   {
     if (m_parentItem)
     {
       auto finding = std::find(m_parentItem->m_childItems.begin(), m_parentItem->m_childItems.end(), this);
       if (finding != m_parentItem->m_childItems.end())
       {
         return std::distance(m_parentItem->m_childItems.begin(), finding);
       }
     }
 
     return 0;
   };
 
   QmitkMultiLabelSegTreeItem* ParentItem()
   {
     return m_parentItem;
   };
 
+  const QmitkMultiLabelSegTreeItem* ParentItem() const
+  {
+    return m_parentItem;
+  };
+
+  const QmitkMultiLabelSegTreeItem* NextSibblingItem() const
+  {
+    if (m_parentItem)
+    {
+      const auto row = this->Row()+1;
+      if (row < m_parentItem->m_childItems.size())
+        return m_parentItem->m_childItems[row];
+    }
+
+    return nullptr;
+  };
+
+  const QmitkMultiLabelSegTreeItem* PrevSibblingItem() const
+  {
+    if (m_parentItem)
+    {
+      const auto row = this->Row();
+      if (row > 0)
+        return m_parentItem->m_childItems[row-1];
+    }
+
+    return nullptr;
+  };
+
   const QmitkMultiLabelSegTreeItem* RootItem() const
   {
     auto item = this;
     while (item->m_parentItem != nullptr)
     {
       item = item->m_parentItem;
     }
     return item;
   };
 
   std::size_t GetGroupID() const
   {
     auto root = this->RootItem();
     auto item = this;
     if (root == this) return 0;
 
     while (root != item->m_parentItem)
     {
       item = item->m_parentItem;
     }
 
     auto iter = std::find(root->m_childItems.begin(), root->m_childItems.end(), item);
 
-    if (root->m_childItems.end() == iter) mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Root does not have an item as child that has root as parent.";
+    if (root->m_childItems.end() == iter) mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Root does not have an currentItem as child that has root as parent.";
 
     return std::distance(root->m_childItems.begin(), iter);
   }
 
   bool HandleAsInstance() const
   {
     return (ItemType::Instance == m_ItemType) || ((ItemType::Label == m_ItemType) && (m_childItems.size() == 1));
   }
 
   mitk::Label* GetLabel() const
   {
     if (ItemType::Instance == m_ItemType)
     {
       return m_Label;
     }
     if (ItemType::Label == m_ItemType)
     {
-      if (m_childItems.empty()) mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Internal label item has no instance item.";
+      if (m_childItems.empty()) mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Internal label currentItem has no instance currentItem.";
       return m_childItems[0]->GetLabel();
     }
 
     return nullptr;
   };
 
   mitk::LabelSetImage::LabelValueType GetLabelValue() const
   {
     auto label = this->GetLabel();
 
     if (nullptr == label)
     {
-      mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Called GetLabelValue on an group item.";
+      mitkThrow() << "Invalid internal state of QmitkMultiLabelTreeModel. Called GetLabelValue on an group currentItem.";
     }
 
     return label->GetValue();
   };
 
   QmitkMultiLabelSegTreeItem* m_parentItem = nullptr;
   std::vector<QmitkMultiLabelSegTreeItem*> m_childItems;
   ItemType m_ItemType = ItemType::Group;
   mitk::Label::Pointer m_Label;
   std::string m_ClassName;
 };
 
 
+
+QModelIndex GetIndexByItem(const QmitkMultiLabelSegTreeItem* start, const QmitkMultiLabelTreeModel* model)
+{
+  QModelIndex parentIndex = QModelIndex();
+  if (nullptr != start->m_parentItem)
+  {
+    parentIndex = GetIndexByItem(start->m_parentItem, model);
+  }
+  else
+  {
+    return parentIndex;
+  }
+
+  return model->index(start->Row(), 0, parentIndex);
+}
+
+QmitkMultiLabelSegTreeItem* GetGroupItem(QmitkMultiLabelTreeModel::SpatialGroupIndexType groupIndex, QmitkMultiLabelSegTreeItem* root)
+{
+  if (nullptr != root && groupIndex < root->m_childItems.size())
+  {
+    return root->m_childItems[groupIndex];
+  }
+
+  return nullptr;
+}
+
+QmitkMultiLabelSegTreeItem* GetInstanceItem(QmitkMultiLabelTreeModel::LabelValueType labelValue, QmitkMultiLabelSegTreeItem* root)
+{
+  QmitkMultiLabelSegTreeItem* result = nullptr;
+
+  for (auto item : root->m_childItems)
+  {
+    result = GetInstanceItem(labelValue, item);
+    if (nullptr != result) return result;
+  }
+
+  if (root->m_ItemType == QmitkMultiLabelSegTreeItem::ItemType::Instance && root->GetLabelValue() == labelValue)
+  {
+    return root;
+  }
+
+  return nullptr;
+}
+
+const QmitkMultiLabelSegTreeItem* GetFirstInstanceLikeItem(const QmitkMultiLabelSegTreeItem* startItem)
+{
+  const QmitkMultiLabelSegTreeItem* result = nullptr;
+
+  if (nullptr != startItem)
+  {
+    if (startItem->HandleAsInstance())
+    {
+      result = startItem;
+    }
+    else if (!startItem->m_childItems.empty())
+    {
+      result = GetFirstInstanceLikeItem(startItem->m_childItems.front());
+    }
+  }
+
+  return result;
+}
+
+QmitkMultiLabelSegTreeItem* GetLabelItemInGroup(const std::string& labelName, QmitkMultiLabelSegTreeItem* group)
+{
+  if (nullptr != group)
+  {
+    auto predicate = [labelName](const QmitkMultiLabelSegTreeItem* item) { return labelName == item->m_ClassName; };
+    auto finding = std::find_if(group->m_childItems.begin(), group->m_childItems.end(), predicate);
+    if (group->m_childItems.end() != finding)
+    {
+      return *finding;
+    }
+  }
+
+  return nullptr;
+}
+
 QmitkMultiLabelTreeModel::QmitkMultiLabelTreeModel(QObject *parent) : QAbstractItemModel(parent)
 , m_Observed(false)
 {
   m_RootItem = std::make_unique<QmitkMultiLabelSegTreeItem>();
 }
 
 QmitkMultiLabelTreeModel ::~QmitkMultiLabelTreeModel()
 {
   this->SetSegmentation(nullptr);
 };
 
 int QmitkMultiLabelTreeModel::columnCount(const QModelIndex& /*parent*/) const
 {
   return 4;
 }
 
 int QmitkMultiLabelTreeModel::rowCount(const QModelIndex &parent) const
 {
   if (parent.column() > 0)
     return 0;
 
   if (m_Segmentation.IsNull())
     return 0;
 
   QmitkMultiLabelSegTreeItem* parentItem = m_RootItem.get();
 
   if (parent.isValid())
     parentItem = static_cast<QmitkMultiLabelSegTreeItem *>(parent.internalPointer());
 
   if (parentItem->HandleAsInstance())
   {
     return 0;
   }
 
   return parentItem->m_childItems.size();
 }
 
 QVariant QmitkMultiLabelTreeModel::data(const QModelIndex &index, int role) const
 {
   if (!index.isValid())
     return QVariant();
 
   auto item = static_cast<QmitkMultiLabelSegTreeItem*>(index.internalPointer());
 
   if (!item)
     return QVariant();
 
   if (role == Qt::DisplayRole||role == Qt::EditRole)
   {
     if (TableColumns::NAME_COL == index.column())
     {
       switch (item->m_ItemType)
       {
         case QmitkMultiLabelSegTreeItem::ItemType::Group:
           return QVariant(QString("Group ")+QString::number(item->GetGroupID()));
         case QmitkMultiLabelSegTreeItem::ItemType::Label:
         {
           auto label = item->GetLabel();
-          if (nullptr == label) mitkThrow() << "Invalid internal state. QmitkMultiLabelTreeModel item is refering to a label that does not exist.";
+          if (nullptr == label) mitkThrow() << "Invalid internal state. QmitkMultiLabelTreeModel currentItem is refering to a label that does not exist.";
           return QVariant(QString::fromStdString(label->GetName()));
         }
         case QmitkMultiLabelSegTreeItem::ItemType::Instance:
           return QVariant(QString("Instance #") + QString::number(item->GetLabelValue()));
       }
     }
     else
     {
       if (item->HandleAsInstance())
       {
         auto label = item->GetLabel();
 
         if (TableColumns::LOCKED_COL == index.column())
         {
           return QVariant(label->GetLocked());
         }
         else if (TableColumns::COLOR_COL == index.column())
         {
           return QVariant(QColor(label->GetColor().GetRed() * 255, label->GetColor().GetGreen() * 255, label->GetColor().GetBlue() * 255));
         }
         else if (TableColumns::VISIBLE_COL == index.column())
         {
           return QVariant(label->GetVisible());
         }
       }
       else
       {
 
       }
     }
   }
   else if (role == ItemModelRole::LabelDataRole)
+  {
+    auto label = item->GetLabel();
+    if (nullptr!=label)  return QVariant::fromValue<void*>(label);
+  }
+  else if (role == ItemModelRole::LabelValueRole)
+  {
+    auto label = item->GetLabel();
+    if (nullptr != label)  return QVariant(label->GetValue());
+  }
+  else if (role == ItemModelRole::LabelInstanceDataRole)
   {
     if (item->HandleAsInstance())
     {
       auto label = item->GetLabel();
       return QVariant::fromValue<void*>(label);
     }
   }
-  else if (role == ItemModelRole::LabelValueRole)
+  else if (role == ItemModelRole::LabelInstanceValueRole)
   {
     if (item->HandleAsInstance())
     {
       auto label = item->GetLabel();
       return QVariant(label->GetValue());
     }
   }
+
   return QVariant();
 }
 
 mitk::Color QtToMitk(const QColor& color)
 {
   mitk::Color mitkColor;
 
   mitkColor.SetRed(color.red() / 255.0f);
   mitkColor.SetGreen(color.green() / 255.0f);
   mitkColor.SetBlue(color.blue() / 255.0f);
 
   return mitkColor;
 }
 
 bool QmitkMultiLabelTreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
 {
   if (!index.isValid())
     return false;
 
   auto item = static_cast<QmitkMultiLabelSegTreeItem*>(index.internalPointer());
 
   if (!item)
     return false;
 
   if (role == Qt::EditRole)
   {
     if (TableColumns::NAME_COL != index.column())
     {
       if (item->HandleAsInstance())
       {
         auto label = item->GetLabel();
 
         if (TableColumns::LOCKED_COL == index.column())
         {
           label->SetLocked(value.toBool());
         }
         else if (TableColumns::COLOR_COL == index.column())
         {
           label->SetColor(QtToMitk(value.value<QColor>()));
         }
         else if (TableColumns::VISIBLE_COL == index.column())
         {
           label->SetVisible(value.toBool());
         }
         auto groupID = m_Segmentation->GetGroupIndexOfLabel(label->GetValue());
         m_Segmentation->GetLabelSet(groupID)->UpdateLookupTable(label->GetValue());
       }
       else
       {
 
       }
       return true;
     }
   }
   return false;
 }
 
 QModelIndex QmitkMultiLabelTreeModel::index(int row, int column, const QModelIndex &parent) const
 {
   if (!hasIndex(row, column, parent))
     return QModelIndex();
 
   auto parentItem = m_RootItem.get();
 
   if (parent.isValid())
     parentItem = static_cast<QmitkMultiLabelSegTreeItem *>(parent.internalPointer());
 
   QmitkMultiLabelSegTreeItem *childItem = parentItem->m_childItems[row];
   if (childItem)
     return createIndex(row, column, childItem);
   else
     return QModelIndex();
 }
 
+QModelIndex QmitkMultiLabelTreeModel::indexOfLabel(mitk::Label::PixelType labelValue) const
+{
+  if (labelValue == mitk::LabelSetImage::UnlabeledLabelValue) return QModelIndex();
+  auto relevantItem = GetInstanceItem(labelValue, this->m_RootItem.get());
+
+  if (nullptr == relevantItem) QModelIndex();
+
+  auto labelItem = relevantItem->ParentItem();
+
+  if (labelItem->m_childItems.size() == 1)
+  { //was the only instance of the label, therefor return the label item instat.
+    relevantItem = labelItem;
+  }
+
+  return GetIndexByItem(relevantItem, this);
+}
+
+QModelIndex QmitkMultiLabelTreeModel::indexOfGroup(mitk::LabelSetImage::SpatialGroupIndexType groupIndex) const
+{
+  auto relevantItem = GetGroupItem(groupIndex, this->m_RootItem.get());
+
+  if (nullptr == relevantItem) QModelIndex();
+
+  return GetIndexByItem(relevantItem, this);
+}
+
 QModelIndex QmitkMultiLabelTreeModel::parent(const QModelIndex &child) const
 {
   if (!child.isValid())
     return QModelIndex();
 
   QmitkMultiLabelSegTreeItem *childItem = static_cast<QmitkMultiLabelSegTreeItem *>(child.internalPointer());
   QmitkMultiLabelSegTreeItem *parentItem = childItem->ParentItem();
 
   if (parentItem == m_RootItem.get())
     return QModelIndex();
 
   return createIndex(parentItem->Row(), 0, parentItem);
 }
 
-QModelIndex GetIndexByItem(QmitkMultiLabelSegTreeItem* start, QmitkMultiLabelTreeModel* model)
+QModelIndex QmitkMultiLabelTreeModel::ClosestLabelInstanceIndex(const QModelIndex& currentIndex) const
 {
-  QModelIndex parentIndex = QModelIndex();
-  if (nullptr != start->m_parentItem)
-  {
-    parentIndex = GetIndexByItem(start->m_parentItem, model);
-  }
-  else
-  {
-    return parentIndex;
-  }
+  if (!currentIndex.isValid()) return QModelIndex();
 
-  return model->index(start->Row(), 0, parentIndex);
-}
-
-QmitkMultiLabelSegTreeItem* GetGroupItem(QmitkMultiLabelTreeModel::SpatialGroupIndexType groupIndex, QmitkMultiLabelSegTreeItem* root)
-{
-  if (nullptr != root && groupIndex < root->m_childItems.size())
-  {
-    return root->m_childItems[groupIndex];
-  }
+  auto currentItem = static_cast<const QmitkMultiLabelSegTreeItem*>(currentIndex.internalPointer());
+  if (!currentItem) return QModelIndex();
 
-  return nullptr;
-}
+  if (currentItem->RootItem() != this->m_RootItem.get()) mitkThrow() << "Invalid call. Passed currentIndex does not seem to be a valid index of this model. It is either outdated or from another model.";
 
-QmitkMultiLabelSegTreeItem* GetInstanceItem(QmitkMultiLabelTreeModel::LabelValueType labelValue, QmitkMultiLabelSegTreeItem* root)
-{
-  QmitkMultiLabelSegTreeItem* result = nullptr;
+  const QmitkMultiLabelSegTreeItem* resultItem = nullptr;
+  auto searchItem = currentItem;
+  const auto rootItem = currentItem->RootItem();
 
-  for (auto item : root->m_childItems)
+  while (searchItem != rootItem)
   {
-    result = GetInstanceItem(labelValue, item);
-    if (nullptr != result) return result;
-  }
+    resultItem = GetFirstInstanceLikeItem(searchItem->NextSibblingItem());
+    if (nullptr != resultItem) break;
 
-  if (root->m_ItemType == QmitkMultiLabelSegTreeItem::ItemType::Instance && root->GetLabelValue() == labelValue)
-  {
-    return root;
+    //no next closest label instance on this level -> check for closest before
+    resultItem = GetFirstInstanceLikeItem(searchItem->PrevSibblingItem());
+    if (nullptr != resultItem) break;
+
+    //no closest label instance before current on this level -> moeve one level up
+    searchItem = searchItem->ParentItem();
   }
 
-  return nullptr;
+  if (nullptr == resultItem)
+    return QModelIndex();
+
+  return GetIndexByItem(resultItem, this);
 }
 
-QmitkMultiLabelSegTreeItem* GetLabelItemInGroup(const std::string& labelName, QmitkMultiLabelSegTreeItem * group)
-{
-  if (nullptr != group)
-  {
-    auto predicate = [labelName](const QmitkMultiLabelSegTreeItem* item) { return labelName == item->m_ClassName; };
-    auto finding = std::find_if(group->m_childItems.begin(), group->m_childItems.end(), predicate);
-    if (group->m_childItems.end() != finding)
-    {
-      return *finding;
-    }
-  }
+///** Returns the index to the next node in the tree that behaves like an instance (label node with only one instance
+//or instance node). If current index is at the end, an invalid index is returned.*/
+//QModelIndex QmitkMultiLabelTreeModel::PrevLabelInstanceIndex(const QModelIndex& currentIndex) const;
 
-  return nullptr;
-}
 
 Qt::ItemFlags QmitkMultiLabelTreeModel::flags(const QModelIndex &index) const
 {
   if (!index.isValid())
     return Qt::NoItemFlags;
 
   if (!index.isValid())
     return Qt::NoItemFlags;
 
   auto item = static_cast<QmitkMultiLabelSegTreeItem*>(index.internalPointer());
 
   if (!item)
     return Qt::NoItemFlags;
 
   if (TableColumns::NAME_COL != index.column())
   {
-    if (item->HandleAsInstance())
+    if (item->HandleAsInstance() &&
+      ((TableColumns::VISIBLE_COL == index.column() && m_AllowVisibilityModification) ||
+       (TableColumns::LOCKED_COL == index.column() && m_AllowLockModification)))
     {
       return Qt::ItemIsEnabled | Qt::ItemIsEditable;
     }
     else
     {
       return Qt::ItemIsEnabled;
     }
     return true;
   }
   else
   {
     if (item->HandleAsInstance())
     {
       return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
     }
     else
     {
       return Qt::ItemIsEnabled;
     }
     return true;
   }
 
   return Qt::NoItemFlags;
 }
 
 QVariant QmitkMultiLabelTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
 {
   if ((Qt::DisplayRole == role) && (Qt::Horizontal == orientation))
   {
     if (TableColumns::NAME_COL == section)
     {
       return "Name";
     }
     else if (TableColumns::LOCKED_COL == section)
     {
       return "Locked";
     }
     else if (TableColumns::COLOR_COL == section)
     {
       return "Color";
     }
     else if (TableColumns::VISIBLE_COL == section)
     {
       return "Visibility";
     }
   }
   return QVariant();
 }
 
 const mitk::LabelSetImage* QmitkMultiLabelTreeModel::GetSegmentation() const
 {
   return m_Segmentation;
 }
 
 
 void QmitkMultiLabelTreeModel::SetSegmentation(mitk::LabelSetImage* segmentation)
 {
   if (m_Segmentation != segmentation)
   {
     this->RemoveObserver();
     this->m_Segmentation = segmentation;
     this->AddObserver();
 
     this->UpdateInternalTree();
   }
 }
 
 
 /**Helper function that adds a labek into the item tree. Passes back the new created instance iten*/
 QmitkMultiLabelSegTreeItem* AddLabelToGroupTree(mitk::Label* label, QmitkMultiLabelSegTreeItem* groupItem, bool& newLabelItemCreated)
 {
   if (nullptr == groupItem) return nullptr;
   if (nullptr == label) return nullptr;
 
   newLabelItemCreated = false;
 
   std::set<std::string> labelNames;
   for (auto labelItem : groupItem->m_childItems)
   {
     labelNames.emplace(labelItem->GetLabel()->GetName());
   }
 
   QmitkMultiLabelSegTreeItem* labelItem = nullptr;
   auto finding = labelNames.find(label->GetName());
   if (finding != labelNames.end())
   { //other label with same name exists
     labelItem = groupItem->m_childItems[std::distance(labelNames.begin(), finding)];
   }
   else
   {
     newLabelItemCreated = true;
     labelItem = new QmitkMultiLabelSegTreeItem(QmitkMultiLabelSegTreeItem::ItemType::Label, groupItem, nullptr, label->GetName());
 
     auto predicate = [label](const std::string& name) { return name > label->GetName(); };
     auto insertFinding = std::find_if(labelNames.begin(), labelNames.end(), predicate);
 
     groupItem->m_childItems.insert(groupItem->m_childItems.begin() + std::distance(labelNames.begin(), insertFinding), labelItem);
   }
 
   auto instanceItem = new QmitkMultiLabelSegTreeItem(QmitkMultiLabelSegTreeItem::ItemType::Instance, labelItem, label);
 
   auto predicate = [label](const QmitkMultiLabelSegTreeItem* item) { return item->GetLabelValue() > label->GetValue(); };
   auto insertFinding = std::find_if(labelItem->m_childItems.begin(), labelItem->m_childItems.end(), predicate);
   labelItem->m_childItems.insert(labelItem->m_childItems.begin() + std::distance(labelItem->m_childItems.begin(), insertFinding), instanceItem);
 
   return instanceItem;
 }
 
 void QmitkMultiLabelTreeModel::GenerateInternalGroupTree(unsigned int groupID, QmitkMultiLabelSegTreeItem* groupItem)
 {
   auto labelSet = m_Segmentation->GetLabelSet(groupID);
 
   for (auto lIter = labelSet->IteratorConstBegin(); lIter != labelSet->IteratorConstEnd(); lIter++)
   {
     if (lIter->first== mitk::LabelSetImage::UnlabeledLabelValue || lIter->second == m_Segmentation->GetExteriorLabel()) continue;
 
     bool newItemCreated = false;
     AddLabelToGroupTree(lIter->second, groupItem, newItemCreated);
   }
 }
 
 QmitkMultiLabelSegTreeItem* QmitkMultiLabelTreeModel::GenerateInternalTree()
 {
   auto rootItem = new QmitkMultiLabelSegTreeItem();
 
   if (m_Segmentation.IsNotNull())
   {
     for (unsigned int groupID = 0; groupID < m_Segmentation->GetNumberOfLayers(); ++groupID)
     {
       auto groupItem = new QmitkMultiLabelSegTreeItem(QmitkMultiLabelSegTreeItem::ItemType::Group, rootItem);
       rootItem->AppendChild(groupItem);
 
       GenerateInternalGroupTree(groupID, groupItem);
     }
   }
 
   return rootItem;
 }
 
 void QmitkMultiLabelTreeModel::UpdateInternalTree()
 {
   emit beginResetModel();
   auto newTree = this->GenerateInternalTree();
   this->m_RootItem.reset(newTree);
   emit endResetModel();
   emit modelChanged();
 }
 
 void QmitkMultiLabelTreeModel::AddObserver()
 {
   if (this->m_Segmentation.IsNotNull())
   {
     if (m_Observed)
     {
       MITK_DEBUG << "Invalid observer state in QmitkMultiLabelTreeModel. There is already a registered observer. Internal logic is not correct. May be an old observer was not removed.";
     }
 
     this->m_Segmentation->AddLabelAddedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, LabelValueType>(
       this, &QmitkMultiLabelTreeModel::OnLabelAdded));
     this->m_Segmentation->AddLabelModifiedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, LabelValueType>(
       this, &QmitkMultiLabelTreeModel::OnLabelModified));
     this->m_Segmentation->AddLabelRemovedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, LabelValueType>(
       this, &QmitkMultiLabelTreeModel::OnLabelRemoved));
     this->m_Segmentation->AddGroupAddedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, SpatialGroupIndexType>(
       this, &QmitkMultiLabelTreeModel::OnGroupAdded));
     this->m_Segmentation->AddGroupModifiedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, SpatialGroupIndexType>(
       this, &QmitkMultiLabelTreeModel::OnGroupModified));
     this->m_Segmentation->AddGroupRemovedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, SpatialGroupIndexType>(
       this, &QmitkMultiLabelTreeModel::OnGroupRemoved));
     m_Observed = true;
   }
 }
 
 void QmitkMultiLabelTreeModel::RemoveObserver()
 {
   if (this->m_Segmentation.IsNotNull())
   {
     this->m_Segmentation->RemoveLabelAddedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, LabelValueType>(
       this, &QmitkMultiLabelTreeModel::OnLabelAdded));
     this->m_Segmentation->RemoveLabelModifiedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, LabelValueType>(
       this, &QmitkMultiLabelTreeModel::OnLabelModified));
     this->m_Segmentation->RemoveLabelRemovedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, LabelValueType>(
       this, &QmitkMultiLabelTreeModel::OnLabelRemoved));
     this->m_Segmentation->RemoveGroupAddedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, SpatialGroupIndexType>(
       this, &QmitkMultiLabelTreeModel::OnGroupAdded));
     this->m_Segmentation->RemoveGroupModifiedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, SpatialGroupIndexType>(
       this, &QmitkMultiLabelTreeModel::OnGroupModified));
     this->m_Segmentation->RemoveGroupRemovedListener(mitk::MessageDelegate1<QmitkMultiLabelTreeModel, SpatialGroupIndexType>(
       this, &QmitkMultiLabelTreeModel::OnGroupRemoved));
   }
   m_Observed = false;
 }
 
 void QmitkMultiLabelTreeModel::OnLabelAdded(LabelValueType labelValue)
 {
   SpatialGroupIndexType groupIndex = 0;
   if (m_Segmentation->IsLabeInGroup(labelValue, groupIndex))
   {
     auto label = m_Segmentation->GetLabel(labelValue);
     if (nullptr == label) mitkThrow() << "Invalid internal state. Segmentation signaled the addition of an label that does not exist in the segmentation. Invalid label value:" << labelValue;
     if (label == m_Segmentation->GetExteriorLabel()) return;
 
     auto groupItem = GetGroupItem(groupIndex, this->m_RootItem.get());
 
     bool newLabelCreated = false;
     auto instanceItem = AddLabelToGroupTree(label, groupItem, newLabelCreated);
 
     if (newLabelCreated)
     {
       if (groupItem->m_childItems.size() == 1)
       { //first label added
         auto groupIndex = GetIndexByItem(groupItem, this);
         emit dataChanged(groupIndex, groupIndex);
       }
       else
       { //whole new label level added to group item
         auto groupIndex = GetIndexByItem(groupItem, this);
         this->beginInsertRows(groupIndex, instanceItem->ParentItem()->Row(), instanceItem->ParentItem()->Row());
         this->endInsertRows();
       }
     }
     else
-    { // instance item was added to existing label item
-      auto labelIndex = GetIndexByItem(instanceItem->ParentItem(), this);
-      this->beginInsertRows(labelIndex, instanceItem->Row(), instanceItem->Row());
-      this->endInsertRows();
+    {
+      if (instanceItem->ParentItem()->m_childItems.size() < 3)
+      { //second instance item was added, so label item will now able to colapse
+        // -> the whole label node has to be updated.
+        auto labelIndex = GetIndexByItem(instanceItem->ParentItem(), this);
+        emit dataChanged(labelIndex, labelIndex);
+      }
+      else
+      {
+        // instance item was added to existing label item with multiple instances
+        //-> just notify the row insertion
+        auto labelIndex = GetIndexByItem(instanceItem->ParentItem(), this);
+        this->beginInsertRows(labelIndex, instanceItem->Row(), instanceItem->Row());
+        this->endInsertRows();
+      }
     }
   }
   else
   {
     mitkThrow() << "Group less labels are not supported in the current implementation.";
   }
 }
 
 void QmitkMultiLabelTreeModel::OnLabelModified(LabelValueType labelValue)
 {
   if (labelValue == m_Segmentation->GetExteriorLabel()->GetValue()) return;
 
   auto instanceItem = GetInstanceItem(labelValue, this->m_RootItem.get());
 
   if (nullptr == instanceItem)
   {
     mitkThrow() << "Internal invalid state. QmitkMultiLabelTreeModel recieved a LabelModified signal for a label that is not represented in the model. Invalid label: " << labelValue;
   }
 
   auto labelItem = instanceItem->ParentItem();
 
   if (labelItem->m_ClassName == instanceItem->GetLabel()->GetName())
   { //only the state of the label changed, but not its position in the model tree.
 
     auto index = GetIndexByItem(labelItem, this);
     emit dataChanged(index, index);
   }
   else
   { //the name of the label changed and thus its place in the model tree, delete the current item and add a new one
     this->OnLabelRemoved(labelValue);
     this->OnLabelAdded(labelValue);
   }
 }
 
 void QmitkMultiLabelTreeModel::OnLabelRemoved(LabelValueType labelValue)
 {
   if (labelValue == m_Segmentation->GetExteriorLabel()->GetValue()) return;
   auto instanceItem = GetInstanceItem(labelValue, this->m_RootItem.get());
 
   if (nullptr == instanceItem) mitkThrow() << "Internal invalid state. QmitkMultiLabelTreeModel recieved a LabelRemoved signal for a label that is not represented in the model. Invalid label: " << labelValue;
 
   auto labelItem = instanceItem->ParentItem();
 
-  if (labelItem->m_childItems.size() > 1)
+  if (labelItem->m_childItems.size() > 2)
   {
     auto labelIndex = GetIndexByItem(labelItem, this);
     this->beginRemoveRows(labelIndex, instanceItem->Row(), instanceItem->Row());
     labelItem->RemoveChild(instanceItem->Row());
     this->endRemoveRows();
   }
+  else if (labelItem->m_childItems.size() == 2)
+  { //After removal only one label is left -> the whole label node is about to be changed (no instances are shown any more).
+    auto labelIndex = GetIndexByItem(labelItem, this);
+    this->beginRemoveRows(labelIndex, instanceItem->Row(), instanceItem->Row());
+    labelItem->RemoveChild(instanceItem->Row());
+    this->endRemoveRows();
+    emit dataChanged(labelIndex, labelIndex);
+  }
   else
   { //was the only instance of the label, therefor also remove the label node from the tree.
     auto groupItem = labelItem->ParentItem();
     auto groupIndex = GetIndexByItem(groupItem, this);
     this->beginRemoveRows(groupIndex, labelItem->Row(), labelItem->Row());
     groupItem->RemoveChild(labelItem->Row());
     this->endRemoveRows();
   }
 }
 
 void QmitkMultiLabelTreeModel::OnGroupAdded(SpatialGroupIndexType groupIndex)
 {
   if (m_ShowGroups)
   {
     this->beginInsertRows(QModelIndex(), groupIndex, groupIndex);
     auto rootItem = m_RootItem.get();
     auto groupItem = new QmitkMultiLabelSegTreeItem(QmitkMultiLabelSegTreeItem::ItemType::Group, rootItem);
     rootItem->AppendChild(groupItem);
     this->GenerateInternalGroupTree(groupIndex, groupItem);
     this->endInsertRows();
   }
 }
 
 void QmitkMultiLabelTreeModel::OnGroupModified(SpatialGroupIndexType groupIndex)
 {
   //currently not needed
 }
 
 void QmitkMultiLabelTreeModel::OnGroupRemoved(SpatialGroupIndexType groupIndex)
 {
   if (m_ShowGroups)
   {
     this->beginRemoveRows(QModelIndex(), groupIndex, groupIndex);
     auto root = m_RootItem.get();
     root->RemoveChild(groupIndex);
     this->endRemoveRows();
   }
 }
 
+void QmitkMultiLabelTreeModel::SetAllowVisibilityModification(bool vmod)
+{
+  m_AllowVisibilityModification = vmod;
+}
+
+bool QmitkMultiLabelTreeModel::GetAllowVisibilityModification() const
+{
+  return m_AllowVisibilityModification;
+}
+
+void QmitkMultiLabelTreeModel::SetAllowLockModification(bool lmod)
+{
+  m_AllowLockModification = lmod;
+}
+
+bool QmitkMultiLabelTreeModel::GetAllowLockModification() const
+{
+  return m_AllowLockModification;
+}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.h b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.h
index 1cef2abe4d..bafdf0ce68 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeModel.h
@@ -1,108 +1,149 @@
 /*============================================================================
 
 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 QmitkMultiLabelTreeModel_h
 #define QmitkMultiLabelTreeModel_h
 
 #include "mitkLabelSetImage.h"
 
 // qt
 #include <QAbstractItemModel>
 
 #include "MitkSegmentationUIExports.h"
 
 
 class QmitkMultiLabelSegTreeItem;
 
 /*!
 \class QmitkMultiLabelTreeModel
 The class is used to represent the information of an MITK MultiLabel segmentation instance (labels, spacial groups...).
 */
 class MITKSEGMENTATIONUI_EXPORT QmitkMultiLabelTreeModel : public QAbstractItemModel
 {
     Q_OBJECT
 
 public:
   using LabelValueType = mitk::LabelSetImage::LabelValueType;
   using SpatialGroupIndexType = mitk::LabelSetImage::SpatialGroupIndexType;
 
   QmitkMultiLabelTreeModel(QObject *parent = nullptr);
   ~QmitkMultiLabelTreeModel() override;
 
   void SetSegmentation(mitk::LabelSetImage* segmentation);
   const mitk::LabelSetImage* GetSegmentation() const;
 
   Qt::ItemFlags flags(const QModelIndex &index) const override;
   QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
   bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
 
   QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
   int rowCount(const QModelIndex &parent = QModelIndex()) const override;
   int columnCount(const QModelIndex &parent = QModelIndex()) const override;
 
   QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
   QModelIndex parent(const QModelIndex &child) const override;
 
+  /** returns the index of a passed label value (always first column). If label value does not exist in
+  segmentation or segmentation is not set an invalid index will be returned.*/
+  QModelIndex indexOfLabel(mitk::Label::PixelType labelValue) const;
+  QModelIndex indexOfGroup(mitk::LabelSetImage::SpatialGroupIndexType groupIndex) const;
+  /** Returns the index to the next node in the tree that behaves like an instance (label node with only one instance
+  or instance node). If current index is at the end, an invalid index is returned.*/
+  QModelIndex ClosestLabelInstanceIndex(const QModelIndex& currentIndex) const;
+
+  ///** Returns the index to the next node in the tree that behaves like an instance (label node with only one instance
+  //or instance node). If current index is at the end, an invalid index is returned.*/
+  //QModelIndex PrevLabelInstanceIndex(const QModelIndex& currentIndex) const;
+
   enum TableColumns
   {
     NAME_COL = 0,
     LOCKED_COL,
     COLOR_COL,
     VISIBLE_COL
   };
 
   enum ItemModelRole
   {
+    /**This role returns the label object that is associated with an index.
+       - On group level it always returns an invalid QVariant
+       - On label level (with multiple instances) it returns the first label instance).
+       - On instance level it returns the label instance object.*/
     LabelDataRole = 64,
-    LabelValueRole = 65, //this role returns the value of the label instance.
-                         //If index is in a row that does not represent a a Label instance
-                         //an invalid QVarient will be returned.
+    /**This role returns only the label value of the label that would be returned by
+       LabelDataRole.*/
+    LabelValueRole = 65,
+    /**Simelar to LabelDataRole, but only returns a valid QVariant if index points only to
+      a specific instance (so either instance level or label level with only one instance).
+      You can use that role if you want to assure that only one specific label instance is
+      referenced by the index.*/
+    LabelInstanceDataRole = 66,
+    /**Simelar to LabelValueRole, but like LabelInstanceDataRole only returns a valid QVariant
+      if index points only to a specific instance (so either instance level or label
+      level with only one instance).
+      You can use that role if you want to assure that only one specific label instance is
+      referenced by the index.*/
+    LabelInstanceValueRole = 67
   };
 
-signals:
+  bool GetAllowVisibilityModification() const;
+  bool GetAllowLockModification() const;
+
+public Q_SLOTS:
+  void SetAllowVisibilityModification(bool vmod);
+  void SetAllowLockModification(bool lmod);
+
+Q_SIGNALS:
   void dataAvailable();
   /** Is emitted whenever the model changes are finished (usually a bit later than dataAvailable()).*/
   void modelChanged();
 
 protected:
   void OnLabelAdded(LabelValueType labelValue);
   void OnLabelModified(LabelValueType labelValue);
   void OnLabelRemoved(LabelValueType labelValue);
   void OnGroupAdded(SpatialGroupIndexType groupIndex);
   void OnGroupModified(SpatialGroupIndexType groupIndex);
   void OnGroupRemoved(SpatialGroupIndexType groupIndex);
 
 private:
   void AddObserver();
   void RemoveObserver();
 
   void UpdateInternalTree();
   void GenerateInternalGroupTree(unsigned int layerID, QmitkMultiLabelSegTreeItem* layerItem);
   QmitkMultiLabelSegTreeItem* GenerateInternalTree();
 
   /* builds a hierarchical tree model for the image statistics
   1. Level: Image
   --> 2. Level: Mask [if exist]
       --> 3. Level: Timestep [if >1 exist] */
   void BuildHierarchicalModel();
 
   mitk::LabelSetImage::Pointer m_Segmentation;
 
   std::mutex m_Mutex;
   std::unique_ptr<QmitkMultiLabelSegTreeItem> m_RootItem;
 
   bool m_Observed;
   bool m_ShowGroups = true;
+
+  bool m_ShowVisibility = true;
+  bool m_ShowLock = true;
+  bool m_ShowOther = false;
+
+  bool m_AllowVisibilityModification = true;
+  bool m_AllowLockModification = true;
 };
 
 #endif // mitkQmitkMultiLabelTreeModel_h
diff --git a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeView.cpp b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeView.cpp
index b6cba705c8..e6ed2c7835 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeView.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkMultiLabelTreeView.cpp
@@ -1,31 +1,31 @@
 /*============================================================================
 
 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 <QmitkMultiLabelTreeView.h>
 
 #include <QmitkMultiLabelTreeModel.h>
 
 QmitkMultiLabelTreeView::QmitkMultiLabelTreeView(QWidget* parent) : QTreeView(parent)
 {
 }
 
 QItemSelectionModel::SelectionFlags QmitkMultiLabelTreeView::selectionCommand(const QModelIndex& index, const QEvent* event) const
 {
-  auto value = index.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelValueRole);
+  auto value = index.data(QmitkMultiLabelTreeModel::ItemModelRole::LabelInstanceValueRole);
   if (index.column()!=0 || !value.isValid())
   {
     return QItemSelectionModel::NoUpdate;
   }
 
   return   QAbstractItemView::selectionCommand(index, event);
 }