Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp	(revision 50718)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp	(revision 50719)
@@ -1167,6 +1167,16 @@
 }
 
-bool UIMessageCenter::confirmMediumRelease(const UIMedium &medium, const QString &strUsage, QWidget *pParent /* = 0*/) const
-{
+bool UIMessageCenter::confirmMediumRelease(const UIMedium &medium, QWidget *pParent /* = 0*/) const
+{
+    /* Prepare the usage: */
+    QStringList usage;
+    CVirtualBox vbox = vboxGlobal().virtualBox();
+    foreach (const QString &strMachineID, medium.curStateMachineIds())
+    {
+        CMachine machine = vbox.FindMachine(strMachineID);
+        if (!vbox.isOk() || machine.isNull())
+            continue;
+        usage << machine.GetName();
+    }
     /* Prepare the message: */
     QString strMessage;
@@ -1196,5 +1206,5 @@
     /* Show the question: */
     return questionBinary(pParent, MessageType_Question,
-                          strMessage.arg(medium.location(), strUsage),
+                          strMessage.arg(medium.location(), usage.join(", ")),
                           0 /* auto-confirm id */,
                           tr("Release", "detach medium"));
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h	(revision 50718)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h	(revision 50719)
@@ -242,5 +242,5 @@
     /* API: Virtual Medium Manager warnings: */
     void cannotChangeMediumType(const CMedium &medium, KMediumType oldMediumType, KMediumType newMediumType, QWidget *pParent = 0) const;
-    bool confirmMediumRelease(const UIMedium &medium, const QString &strUsage, QWidget *pParent = 0) const;
+    bool confirmMediumRelease(const UIMedium &medium, QWidget *pParent = 0) const;
     bool confirmMediumRemoval(const UIMedium &medium, QWidget *pParent = 0) const;
     int confirmDeleteHardDiskStorage(const QString &strLocation, QWidget *pParent = 0) const;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp	(revision 50718)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp	(revision 50719)
@@ -80,6 +80,28 @@
     /** Remove UIMedium wrapped by <i>this</i> item. */
     virtual bool remove() = 0;
-
-    /** Refreshes item fully. */
+    /** Release UIMedium wrapped by <i>this</i> item. */
+    virtual bool release()
+    {
+        /* Refresh: */
+        refreshAll();
+
+        /* Make sure medium was not released yet: */
+        if (medium().curStateMachineIds().isEmpty())
+            return true;
+
+        /* Confirm release: */
+        if (!msgCenter().confirmMediumRelease(medium(), treeWidget()))
+            return false;
+
+        /* Release: */
+        foreach (const QString &strMachineID, medium().curStateMachineIds())
+            if (!releaseFrom(strMachineID))
+                return false;
+
+        /* True by default: */
+        return true;
+    }
+
+    /** Refresh item fully. */
     void refreshAll()
     {
@@ -136,7 +158,12 @@
     }
 
+protected:
+
+    /** Release UIMedium wrapped by <i>this</i> item from virtual @a machine. */
+    virtual bool releaseFrom(CMachine machine) = 0;
+
 private:
 
-    /** Refreshes item information such as icon, text and tool-tip. */
+    /** Refresh item information such as icon, text and tool-tip. */
     void refresh()
     {
@@ -152,4 +179,36 @@
     }
 
+    /** Release UIMedium wrapped by <i>this</i> item from virtual machine with @a strMachineID. */
+    bool releaseFrom(const QString &strMachineID)
+    {
+        /* Open session: */
+        CSession session = vboxGlobal().openSession(strMachineID);
+        if (session.isNull())
+            return false;
+
+        /* Get machine: */
+        CMachine machine = session.GetMachine();
+
+        /* Prepare result: */
+        bool fSuccess = false;
+
+        /* Release medium from machine: */
+        if (releaseFrom(machine))
+        {
+            /* Save machine settings: */
+            machine.SaveSettings();
+            if (!machine.isOk())
+                msgCenter().cannotSaveMachineSettings(machine, treeWidget());
+            else
+                fSuccess = true;
+        }
+
+        /* Close session: */
+        session.UnlockMachine();
+
+        /* Return result: */
+        return fSuccess;
+    }
+
     /** UIMedium wrapped by <i>this</i> item. */
     UIMedium m_medium;
@@ -242,4 +301,41 @@
         /* True by default: */
         return true;
+    }
+
+    /** Release UIMedium wrapped by <i>this</i> item from virtual @a machine. */
+    bool releaseFrom(CMachine machine)
+    {
+        /* Enumerate attachments: */
+        CMediumAttachmentVector attachments = machine.GetMediumAttachments();
+        foreach (const CMediumAttachment &attachment, attachments)
+        {
+            /* Skip non-hard-disks: */
+            if (attachment.GetType() != KDeviceType_HardDisk)
+                continue;
+
+            /* Skip unrelated hard-disks: */
+            if (attachment.GetMedium().GetId() != id())
+                continue;
+
+            /* Remember controller: */
+            CStorageController controller = machine.GetStorageControllerByName(attachment.GetController());
+
+            /* Try to detach device: */
+            machine.DetachDevice(attachment.GetController(), attachment.GetPort(), attachment.GetDevice());
+            if (!machine.isOk())
+            {
+                /* Return failure: */
+                msgCenter().cannotDetachDevice(machine, UIMediumType_HardDisk, location(),
+                                               StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice()),
+                                               treeWidget());
+                return false;
+            }
+
+            /* Return success: */
+            return true;
+        }
+
+        /* False by default: */
+        return false;
     }
 
@@ -344,4 +440,36 @@
         return true;
     }
+
+    /** Release UIMedium wrapped by <i>this</i> item from virtual @a machine. */
+    bool releaseFrom(CMachine machine)
+    {
+        /* Enumerate attachments: */
+        CMediumAttachmentVector attachments = machine.GetMediumAttachments();
+        foreach (const CMediumAttachment &attachment, attachments)
+        {
+            /* Skip non-optical-disks: */
+            if (attachment.GetType() != KDeviceType_DVD)
+                continue;
+
+            /* Skip unrelated optical-disks: */
+            if (attachment.GetMedium().GetId() != id())
+                continue;
+
+            /* Try to unmount device: */
+            machine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
+            if (!machine.isOk())
+            {
+                /* Return failure: */
+                msgCenter().cannotRemountMedium(machine, medium(), false /* mount? */, false /* retry? */, treeWidget());
+                return false;
+            }
+
+            /* Return success: */
+            return true;
+        }
+
+        /* Return failure: */
+        return false;
+    }
 };
 
@@ -394,4 +522,36 @@
         /* True by default: */
         return true;
+    }
+
+    /** Release UIMedium wrapped by <i>this</i> item from virtual @a machine. */
+    bool releaseFrom(CMachine machine)
+    {
+        /* Enumerate attachments: */
+        CMediumAttachmentVector attachments = machine.GetMediumAttachments();
+        foreach (const CMediumAttachment &attachment, attachments)
+        {
+            /* Skip non-floppy-disks: */
+            if (attachment.GetType() != KDeviceType_Floppy)
+                continue;
+
+            /* Skip unrelated floppy-disks: */
+            if (attachment.GetMedium().GetId() != id())
+                continue;
+
+            /* Try to unmount device: */
+            machine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
+            if (!machine.isOk())
+            {
+                /* Return failure: */
+                msgCenter().cannotRemountMedium(machine, medium(), false /* mount? */, false /* retry? */, treeWidget());
+                return false;
+            }
+
+            /* Return success: */
+            return true;
+        }
+
+        /* Return failure: */
+        return false;
     }
 };
@@ -670,34 +830,10 @@
     AssertReturnVoid(!pMediumItem->id().isNull());
 
-    /* Refresh attached VM id list: */
-    pMediumItem->refreshAll();
-    const QList<QString> machineIds(pMediumItem->medium().curStateMachineIds());
-    /* If the machine id list is empty: */
-    if (machineIds.isEmpty())
-    {
-        /* This may happen if medium was already released by a third party,
-         * re-fetch currently chosen medium-item and silently return. */
-        return refetchCurrentChosenMediumItem();
-    }
-
-    /* Gather usage list: */
-    QStringList usage;
-    foreach (const QString &strMachineId, machineIds)
-    {
-        CMachine machine = m_vbox.FindMachine(strMachineId);
-        if (!m_vbox.isOk())
-            continue;
-        usage << machine.GetName();
-    }
-    AssertReturnVoid(!usage.isEmpty());
-
-    /* Confirm release: */
-    if (!msgCenter().confirmMediumRelease(pMediumItem->medium(), usage.join(", "), this))
-        return;
-
-    /* Release: */
-    foreach (const QString &strMachineId, machineIds)
-        if (!releaseMediumFrom(pMediumItem->medium(), strMachineId))
-            break;
+    /* Remove current medium-item: */
+    bool fResult = pMediumItem->release();
+
+    /* Refetch currently chosen medium-item: */
+    if (fResult)
+        refetchCurrentChosenMediumItem();
 }
 
@@ -1634,146 +1770,4 @@
 }
 
-bool UIMediumManager::releaseMediumFrom(const UIMedium &medium, const QString &strMachineId)
-{
-    /* Open session: */
-    CSession session = vboxGlobal().openSession(strMachineId);
-    if (session.isNull())
-        return false;
-
-    /* Get machine: */
-    CMachine machine = session.GetMachine();
-
-    /* Prepare result: */
-    bool fSuccess = true;
-
-    /* Depending on medium-type: */
-    switch (medium.type())
-    {
-        case UIMediumType_HardDisk: fSuccess = releaseHardDiskFrom(medium, machine); break;
-        case UIMediumType_DVD:      fSuccess = releaseOpticalDiskFrom(medium, machine); break;
-        case UIMediumType_Floppy:   fSuccess = releaseFloppyDiskFrom(medium, machine); break;
-        default: AssertMsgFailed(("Medium-type unknown: %d\n", medium.type())); break;
-    }
-
-    /* If medium was released: */
-    if (fSuccess)
-    {
-        /* Save machine settings: */
-        machine.SaveSettings();
-        if (!machine.isOk())
-        {
-            msgCenter().cannotSaveMachineSettings(machine, this);
-            fSuccess = false;
-        }
-    }
-
-    /* Close session: */
-    session.UnlockMachine();
-
-    /* Return result: */
-    return fSuccess;
-}
-
-bool UIMediumManager::releaseHardDiskFrom(const UIMedium &medium, CMachine &machine)
-{
-    /* Enumerate attachments: */
-    CMediumAttachmentVector attachments = machine.GetMediumAttachments();
-    foreach (const CMediumAttachment &attachment, attachments)
-    {
-        /* Skip non-hard-disks: */
-        if (attachment.GetType() != KDeviceType_HardDisk)
-            continue;
-
-        /* Skip unrelated hard-disks: */
-        if (attachment.GetMedium().GetId() != medium.id())
-            continue;
-
-        /* Try detaching device: */
-        machine.DetachDevice(attachment.GetController(), attachment.GetPort(), attachment.GetDevice());
-        if (machine.isOk())
-        {
-            /* Return success: */
-            return true;
-        }
-        else
-        {
-            /* Show error: */
-            CStorageController controller = machine.GetStorageControllerByName(attachment.GetController());
-            msgCenter().cannotDetachDevice(machine, UIMediumType_HardDisk, medium.location(),
-                                           StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice()), this);
-            /* Return failure: */
-            return false;
-        }
-    }
-    /* Return failure: */
-    return false;
-}
-
-bool UIMediumManager::releaseOpticalDiskFrom(const UIMedium &medium, CMachine &machine)
-{
-    /* Enumerate attachments: */
-    CMediumAttachmentVector attachments = machine.GetMediumAttachments();
-    foreach (const CMediumAttachment &attachment, attachments)
-    {
-        /* Skip non-optical-disks: */
-        if (attachment.GetType() != KDeviceType_DVD)
-            continue;
-
-        /* Skip unrelated optical-disks: */
-        if (attachment.GetMedium().GetId() != medium.id())
-            continue;
-
-        /* Try device unmounting: */
-        machine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
-        if (machine.isOk())
-        {
-            /* Return success: */
-            return true;
-        }
-        else
-        {
-            /* Show error: */
-            msgCenter().cannotRemountMedium(machine, medium, false /* mount? */, false /* retry? */, this);
-            /* Return failure: */
-            return false;
-        }
-    }
-    /* Return failure: */
-    return false;
-}
-
-bool UIMediumManager::releaseFloppyDiskFrom(const UIMedium &medium, CMachine &machine)
-{
-    /* Enumerate attachments: */
-    CMediumAttachmentVector attachments = machine.GetMediumAttachments();
-    foreach (const CMediumAttachment &attachment, attachments)
-    {
-        /* Skip non-floppy-disks: */
-        if (attachment.GetType() != KDeviceType_Floppy)
-            continue;
-
-        /* Skip unrelated floppy-disks: */
-        if (attachment.GetMedium().GetId() != medium.id())
-            continue;
-
-        /* Try device unmounting: */
-        machine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
-        if (machine.isOk())
-        {
-            /* Return success: */
-            return true;
-        }
-        else
-        {
-            /* Show error: */
-            msgCenter().cannotRemountMedium(machine, medium, false /* mount? */, false /* retry? */, this);
-            /* Return failure: */
-            return false;
-        }
-    }
-    /* Return failure: */
-    return false;
-}
-
 UIMediumType UIMediumManager::mediumType(QTreeWidget *pTreeWidget) const
 {
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.h	(revision 50718)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.h	(revision 50719)
@@ -164,10 +164,4 @@
     void deleteMediumItem(const QString &strMediumID);
 
-    /* Helpers: Medium-modification stuff: */
-    bool releaseMediumFrom(const UIMedium &medium, const QString &strMachineId);
-    bool releaseHardDiskFrom(const UIMedium &medium, CMachine &machine);
-    bool releaseOpticalDiskFrom(const UIMedium &medium, CMachine &machine);
-    bool releaseFloppyDiskFrom(const UIMedium &medium, CMachine &machine);
-
     /** Determines medium type for passed @a pTreeWidget. */
     UIMediumType mediumType(QTreeWidget *pTreeWidget) const;
