diff --git a/scenarios/ArVizExample/config/RobotToArVizApp.cfg b/scenarios/ArVizExample/config/RobotToArVizApp.cfg
index b33276fe2dc50c8d6eadcb7beb004710f336e825..55d034d9c687c16ad2f34f458f85ca66da54cdff 100644
--- a/scenarios/ArVizExample/config/RobotToArVizApp.cfg
+++ b/scenarios/ArVizExample/config/RobotToArVizApp.cfg
@@ -109,6 +109,14 @@
 # ArmarX.RemoteHandlesDeletionTimeout = 3000
 
 
+# ArmarX.RobotToArViz.ArVizStorageName:  Name of the ArViz storage
+#  Attributes:
+#  - Default:            ArVizStorage
+#  - Case sensitivity:   yes
+#  - Required:           no
+# ArmarX.RobotToArViz.ArVizStorageName = ArVizStorage
+
+
 # ArmarX.RobotToArViz.ArVizTopicName:  Name of the ArViz topic
 #  Attributes:
 #  - Default:            ArVizTopic
diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
index 0b5826a8975afca18a2b4181238b20e2d3a0fb18..c47f98b7773f4bb07cabf82ac2a6ca003a5b50f1 100644
--- a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
+++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
@@ -4,6 +4,7 @@
 
 #include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/util/CPPUtility/GetTypeString.h>
+#include <Inventor/nodes/SoUnits.h>
 
 #include <Inventor/SoPath.h>
 
@@ -14,6 +15,12 @@ namespace coin
     void clearRobotCache();
     void clearObjectCache();
 }
+    static const int ANY_TRANSFORM = data::InteractionEnableFlags::TRANSLATION_X |
+                                     data::InteractionEnableFlags::TRANSLATION_Y |
+                                     data::InteractionEnableFlags::TRANSLATION_Z |
+                                     data::InteractionEnableFlags::ROTATION_X |
+                                     data::InteractionEnableFlags::ROTATION_Y |
+                                     data::InteractionEnableFlags::ROTATION_Z;
 
     struct CoinVisualizerWrapper : IceUtil::Shared
     {
@@ -89,7 +96,7 @@ namespace coin
                    &CoinVisualizerWrapper::onUpdateSuccess,
                    &CoinVisualizerWrapper::onUpdateFailure);
 
-        root = new SoSeparator;
+        manipulatorGroup = new SoSeparator;
 
         // The SoSelection node enable selection of nodes via mouse click / ray casting
         selection = new SoSelection;
@@ -97,7 +104,9 @@ namespace coin
         selection->addDeselectionCallback(&deselectionCallback, this);
         selection->setUserData(this);
 
-        selection->addChild(root);
+        root = new SoSeparator;
+        root->addChild(manipulatorGroup);
+        root->addChild(selection);
 
         // Preallocate some space for layers
         layers.data.reserve(32);
@@ -178,7 +187,7 @@ namespace coin
             // Create a new layer
             SoSeparator* coinNode = new SoSeparator;
             coinNode->ref();
-            root->addChild(coinNode);
+            selection->addChild(coinNode);
 
             layerIt = layers.data.insert(layerIt, CoinLayer(layerID, coinNode));
             layerIt->elements.reserve(64);
@@ -236,33 +245,10 @@ namespace coin
                     // Has an interaction been added?
                     viz::data::InteractionDescription& oldInteraction = oldElement->data->interaction;
                     viz::data::InteractionDescription& newInteraction = updatedElementPtr->interaction;
-                    // TODO: Also handle the case, when an interaction is removed!
                     if (newInteraction.enableFlags != oldInteraction.enableFlags
                             || oldInteraction.contextMenuOptions != newInteraction.contextMenuOptions)
                     {
-                        // Lookup the interaction entry
-                        ElementInteractionData* foundInteraction = nullptr;
-                        for (auto& interaction : elementInteractions)
-                        {
-                            if (interaction->layer == layer->id
-                                    && interaction->element == updatedElement.id)
-                            {
-                                foundInteraction = interaction.get();
-                            }
-                        }
-                        if (foundInteraction == nullptr)
-                        {
-                            // Need to add a new entry
-                            foundInteraction = elementInteractions.emplace_back(
-                                                   new ElementInteractionData).get();
-                        }
-                        foundInteraction->layer = layer->id;
-                        foundInteraction->element = updatedElement.id;
-                        foundInteraction->interaction = newInteraction;
-
-                        // Add user data to Coin node
-                        oldElement->visu->separator->setUserData(foundInteraction);
-                        oldElement->visu->separator->setName("InteractiveNode");
+                        addOrUpdateInteraction(layer->id, updatedElement.id, newInteraction, oldElement->visu.get());
                     }
 
                     oldElement->data = updatedElementPtr;
@@ -282,29 +268,7 @@ namespace coin
                 viz::data::InteractionDescription& newInteraction = updatedElementPtr->interaction;
                 if (newInteraction.enableFlags != 0)
                 {
-                    // Lookup the interaction entry
-                    ElementInteractionData* foundInteraction = nullptr;
-                    for (auto& interaction : elementInteractions)
-                    {
-                        if (interaction->layer == layer->id
-                                && interaction->element == updatedElement.id)
-                        {
-                            foundInteraction = interaction.get();
-                        }
-                    }
-                    if (foundInteraction == nullptr)
-                    {
-                        // Need to add a new entry
-                        foundInteraction = elementInteractions.emplace_back(
-                                               new ElementInteractionData).get();
-                    }
-                    foundInteraction->layer = layer->id;
-                    foundInteraction->element = updatedElement.id;
-                    foundInteraction->interaction = newInteraction;
-
-                    // Add user data to Coin node
-                    elementVisu->separator->setUserData(foundInteraction);
-                    elementVisu->separator->setName("InteractiveNode");
+                    addOrUpdateInteraction(layer->id, updatedElement.id, newInteraction, elementVisu.get());
                 }
 
                 layer->node->addChild(elementVisu->separator);
@@ -329,6 +293,36 @@ namespace coin
         }
     }
 
+    void CoinVisualizer::addOrUpdateInteraction(CoinLayerID const& layerID, std::string const& elementID,
+                                                data::InteractionDescription const& interactionDesc,
+                                                coin::ElementVisualization* visu)
+    {
+        // Lookup the interaction entry
+        ElementInteractionData* foundInteraction = nullptr;
+        for (auto& interaction : elementInteractions)
+        {
+            if (interaction->layer == layerID
+                    && interaction->element == elementID)
+            {
+                foundInteraction = interaction.get();
+            }
+        }
+        if (foundInteraction == nullptr)
+        {
+            // Need to add a new entry
+            foundInteraction = elementInteractions.emplace_back(
+                                   new ElementInteractionData).get();
+        }
+        foundInteraction->layer = layerID;
+        foundInteraction->element = elementID;
+
+        foundInteraction->interaction = interactionDesc;
+
+        // Add user data to Coin node
+        visu->separator->setUserData(foundInteraction);
+        visu->separator->setName("InteractiveNode");
+    }
+
     void CoinVisualizer::removeElementsIfNotUpdated(CoinLayer* layer)
     {
         for (auto iter = layer->elements.begin(); iter != layer->elements.end();)
@@ -374,7 +368,8 @@ namespace coin
                 std::unique_lock<std::mutex> lock(stateMutex);
                 storage = stateStorage;
                 selection->deselectAll();
-                root->removeAllChildren();
+                selection->removeAllChildren();
+                manipulatorGroup->removeAllChildren();
                 interactionFeedbackBuffer.clear();
                 elementInteractions.clear();
                 selectedElement = nullptr;
@@ -493,13 +488,13 @@ namespace coin
             return;
         }
 
-        int childIndex = root->findChild(layer->node);
+        int childIndex = selection->findChild(layer->node);
         if (childIndex < 0)
         {
             // Layer is currently not visible
             if (visible)
             {
-                root->addChild(layer->node);
+                selection->addChild(layer->node);
             }
         }
         else
@@ -513,7 +508,7 @@ namespace coin
                 {
                     selection->deselectAll();
                 }
-                root->removeChild(childIndex);
+                selection->removeChild(childIndex);
             }
         }
     }
@@ -626,14 +621,51 @@ namespace coin
             }
             return;
         }
+        int enableFlags = id->interaction.enableFlags;
+        if ((enableFlags & data::InteractionEnableFlags::SELECT) == 0)
+        {
+            // Element was not marked for selection
+            return;
+        }
 
         if (eventType == data::InteractionFeedbackType::SELECT)
         {
             selectedElement = id;
+
+            // Does the element support transform interactions?
+            if (enableFlags & ANY_TRANSFORM)
+            {
+                // TODO: Look up the element and add it to the manipulator group
+                CoinLayer* layer = layers.findLayer(id->layer);
+                if (layer == nullptr)
+                {
+                    ARMARX_WARNING << "Selected an element whose layer does not exist: \n"
+                                   << "Layer: " << id->layer.first << "/" << id->layer.second
+                                   << ", element: " << id->element;
+                    return;
+                }
+                CoinLayerElement* element = layer->findElement(id->element);
+                if (element == nullptr)
+                {
+                    ARMARX_WARNING << "Selected an element which does not exist: \n"
+                                   << "Layer: " << id->layer.first << "/" << id->layer.second
+                                   << ", element: " << id->element;
+                    return;
+                }
+
+                manipulatorGroup->removeAllChildren();
+                // We need to create the manipulator everytime to achieve the desired effect
+                // If we reuse an instance, the manipulator gets stuck to old objects...
+                manipulator = new SoTransformerManip;
+                manipulatorGroup->addChild(manipulator);
+                manipulatorGroup->addChild(element->visu->separator);
+            }
         }
         else
         {
             selectedElement = nullptr;
+
+            // TODO: Remove the element from the manipulatorGroup if it was in there
         }
 
         viz::data::InteractionFeedback& feedback = interactionFeedbackBuffer.emplace_back();
@@ -646,6 +678,6 @@ namespace coin
 
     void CoinVisualizer::exportToVRML(const std::string& exportFilePath)
     {
-        coin::exportToVRML(root, exportFilePath);
+        coin::exportToVRML(selection, exportFilePath);
     }
 }
diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.h b/source/RobotAPI/components/ArViz/Coin/Visualizer.h
index adda36b9ae47404a3f59062c649dad681cd0502f..bbcb9ed6604f50bfda38c3ce75326341da2c9b28 100644
--- a/source/RobotAPI/components/ArViz/Coin/Visualizer.h
+++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.h
@@ -4,6 +4,7 @@
 
 #include <RobotAPI/interface/ArViz/Component.h>
 
+#include <Inventor/manips/SoTransformerManip.h>
 #include <Inventor/nodes/SoSelection.h>
 #include <Inventor/nodes/SoSeparator.h>
 
@@ -230,6 +231,9 @@ namespace armarx::viz
 
         CoinLayer& findOrAddLayer(CoinLayerID const& layerID);
         void addOrUpdateElements(CoinLayer* layer, data::LayerUpdate const& update);
+        void addOrUpdateInteraction(CoinLayerID const& layerID, std::string const& elementID,
+                                    data::InteractionDescription const& interactionDesc,
+                                    coin::ElementVisualization* visu);
         void removeElementsIfNotUpdated(CoinLayer* layer);
 
         std::vector<CoinLayerID> getLayerIDs();
@@ -261,6 +265,8 @@ namespace armarx::viz
 
         SoSelection* selection = nullptr;
         SoSeparator* root = nullptr;
+        SoSeparator* manipulatorGroup = nullptr;
+        SoTransformerManip* manipulator = nullptr;
 
         std::atomic<CoinVisualizerUpdateResult> updateResult{CoinVisualizerUpdateResult::SUCCESS};
         data::LayerUpdates pulledUpdates;
diff --git a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
index d772854de1792982ecf4015f7b61fd412ab6fb09..7ac979f030a7da3f1752a47c8076d8cb6d56fb29 100644
--- a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
+++ b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
@@ -511,7 +511,8 @@ namespace armarx
         // Enable some interaction possibilities
         box.enable(viz::interaction()
                    .selection()
-                   .contextMenu({"First Option", "Second Option", "Third Option"}));
+                   .contextMenu({"First Option", "Second Option", "Third Option"})
+                   .fullTransform());
 
         layer.add(box);
 
@@ -524,7 +525,8 @@ namespace armarx
         // Enable some interaction possibilities
         cyl.enable(viz::interaction()
                    .selection()
-                   .contextMenu({"Cyl Option 1", "Cyl Option 2"}));
+                   .contextMenu({"Cyl Option 1", "Cyl Option 2"})
+                   .fullTransform());
 
         layer.add(cyl);
     }
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
index 7aa05e3a197d4054ea04eaaa8ebc0f68304c50cc..1962d259c0d2329c9870f1e3d314fdea17a1f60d 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
@@ -1121,7 +1121,7 @@ namespace armarx
 
     SoNode* ArVizWidgetController::getScene()
     {
-        return visualizer.selection;
+        return visualizer.root;
     }
 
     static const std::string CONFIG_KEY_STORAGE = "Storage";