Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.h	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.h	(revision 48301)
@@ -71,6 +71,4 @@
         , SetRegionEventType
         , ModifierKeyChangeEventType
-        , MediumEnumeratedEventType
-        , MediumsEnumeratedEventType
 #ifdef Q_WS_WIN
         , ShellExecuteEventType
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 48301)
@@ -70,4 +70,5 @@
 #include "UISession.h"
 #include "UIConverter.h"
+#include "UIMediumEnumerator.h"
 
 #ifdef Q_WS_X11
@@ -162,35 +163,4 @@
 #endif
 
-/* Medium enumerated event: */
-class UIMediumEnumeratedEvent : public QEvent
-{
-public:
-
-    /* Constructor: */
-    UIMediumEnumeratedEvent(const UIMedium &medium, const VBoxMediaList::iterator &iterator)
-        : QEvent((QEvent::Type)MediumEnumeratedEventType)
-        , m_medium(medium), m_iterator(iterator)
-    {}
-
-    /* Variables: */
-    const UIMedium m_medium;
-    const VBoxMediaList::iterator m_iterator;
-};
-
-/* Mediums enumerated event: */
-class UIMediumsEnumeratedEvent : public QEvent
-{
-public:
-
-    /* Constructor: */
-    UIMediumsEnumeratedEvent(const VBoxMediaList::iterator &iterator)
-        : QEvent((QEvent::Type)MediumsEnumeratedEventType)
-        , m_iterator(iterator)
-    {}
-
-    /* Variable: */
-    const VBoxMediaList::iterator m_iterator;
-};
-
 // VBoxGlobal
 ////////////////////////////////////////////////////////////////////////////////
@@ -270,5 +240,5 @@
     , mSelectorWnd (NULL)
     , m_pVirtualMachine(0)
-    , m_pMediumEnumerationThread(0)
+    , m_pMediumEnumerator(0)
     , mIsKWinManaged (false)
 #if defined(DEBUG_bird)
@@ -1687,117 +1657,20 @@
 }
 
-void VBoxGlobal::createMedium(const UIMedium &uimedium)
-{
-    VBoxMediaList::iterator it = m_mediums.begin();
-
-    if (uimedium.type() == UIMediumType_HardDisk)
-    {
-        VBoxMediaList::iterator itParent = m_mediums.end();
-
-        for (; it != m_mediums.end(); ++ it)
-        {
-            /* skip null medium that come first */
-            if ((*it).isNull()) continue;
-
-            if ((*it).type() != UIMediumType_HardDisk)
-                break;
-
-            if (uimedium.parent() != NULL && itParent == m_mediums.end())
-            {
-                if (&*it == uimedium.parent())
-                    itParent = it;
-            }
-            else
-            {
-                /* break if met a parent's sibling (will insert before it) */
-                if (uimedium.parent() != NULL &&
-                    (*it).parent() == (*itParent).parent())
-                    break;
-
-                /* compare to uimedium's siblings */
-                if ((*it).parent() == uimedium.parent() &&
-                    (*it).name().localeAwareCompare (uimedium.name()) > 0)
-                    break;
-            }
-        }
-
-        AssertReturnVoid (uimedium.parent() == NULL || itParent != m_mediums.end());
-    }
-    else
-    {
-        for (; it != m_mediums.end(); ++ it)
-        {
-            /* skip null medium that come first */
-            if ((*it).isNull()) continue;
-
-            /* skip HardDisks that come first */
-            if ((*it).type() == UIMediumType_HardDisk)
-                continue;
-
-            /* skip DVD when inserting Floppy */
-            if (uimedium.type() == UIMediumType_Floppy &&
-                (*it).type() == UIMediumType_DVD)
-                continue;
-
-            if ((*it).name().localeAwareCompare (uimedium.name()) > 0 ||
-                (uimedium.type() == UIMediumType_DVD &&
-                 (*it).type() == UIMediumType_Floppy))
-                break;
-        }
-    }
-
-    it = m_mediums.insert (it, uimedium);
-
-    emit sigMediumCreated((*it).id());
-}
-
-void VBoxGlobal::updateMedium(const UIMedium &uimedium)
-{
-    VBoxMediaList::Iterator it;
-    for (it = m_mediums.begin(); it != m_mediums.end(); ++ it)
-        if ((*it).id() == uimedium.id())
-            break;
-
-    AssertReturnVoid (it != m_mediums.end());
-
-    if (&*it != &uimedium)
-        *it = uimedium;
-
-    emit sigMediumUpdated((*it).id());
+void VBoxGlobal::createMedium(const UIMedium &medium)
+{
+    /* Create medium in medium-enumerator: */
+    m_pMediumEnumerator->createMedium(medium);
+}
+
+void VBoxGlobal::updateMedium(const UIMedium &medium)
+{
+    /* Update medium of medium-enumerator: */
+    m_pMediumEnumerator->updateMedium(medium);
 }
 
 void VBoxGlobal::deleteMedium(const QString &strMediumID)
 {
-    VBoxMediaList::Iterator it;
-    for (it = m_mediums.begin(); it != m_mediums.end(); ++it)
-        if ((*it).id() == strMediumID)
-            break;
-
-    AssertReturnVoid(it != m_mediums.end());
-
-#if DEBUG
-    /* sanity: must be no children */
-    {
-        VBoxMediaList::Iterator jt = it;
-        ++jt;
-        AssertReturnVoid(jt == m_mediums.end() || (*jt).parent() != &*it);
-    }
-#endif /* DEBUG */
-
-    UIMedium *pParent = (*it).parent();
-
-    /* remove the medium from the list to keep it in sync with the server "for
-     * free" when the medium is deleted from one of our UIs */
-    m_mediums.erase(it);
-
-    emit sigMediumDeleted(strMediumID);
-
-    /* also emit the parent update signal because some attributes like
-     * isReadOnly() may have been changed after child removal */
-    if (pParent != NULL)
-    {
-        pParent->refresh();
-        emit sigMediumUpdated(pParent->id());
-    }
+    /* Delete medium from medium-enumerator: */
+    m_pMediumEnumerator->deleteMedium(strMediumID);
 }
 
@@ -1937,77 +1810,4 @@
 }
 
-static void addNullMediumToList(VBoxMediaList &mediums, VBoxMediaList::iterator where)
-{
-   /* Append the NULL medium to the medium list: */
-    UIMedium medium;
-    mediums.insert(where, medium);
-}
-
-static void addMediumsToList(const CMediumVector &inputMediums,
-                             VBoxMediaList &outputMediums,
-                             VBoxMediaList::iterator where,
-                             UIMediumType mediumType,
-                             UIMedium *pParent = 0)
-{
-    /* Appends the given list of input-mediums to the output-mediums: */
-    VBoxMediaList::iterator first = where;
-
-    for (CMediumVector::ConstIterator it = inputMediums.begin(); it != inputMediums.end(); ++it)
-    {
-        CMedium cmedium(*it);
-        UIMedium medium(cmedium, mediumType, pParent);
-
-        /* Search for a proper alphabetic position: */
-        VBoxMediaList::iterator jt = first;
-        for (; jt != where; ++ jt)
-            if ((*jt).name().localeAwareCompare(medium.name()) > 0)
-                break;
-
-        outputMediums.insert(jt, medium);
-
-        /* Adjust the first item if inserted before it: */
-        if (jt == first)
-            --first;
-    }
-}
-
-static void addHardDisksToList(const CMediumVector &inputMediums,
-                               VBoxMediaList &outputMediums,
-                               VBoxMediaList::iterator where,
-                               UIMedium *pParent = 0)
-{
-    /* Appends the given list of input-hard-disks and all their children to the output-mediums: */
-    VBoxMediaList::iterator first = where;
-
-    /* First pass: Add siblings sorted */
-    for (CMediumVector::ConstIterator it = inputMediums.begin(); it != inputMediums.end(); ++it)
-    {
-        CMedium cmedium(*it);
-        UIMedium medium(cmedium, UIMediumType_HardDisk, pParent);
-
-        /* Search for a proper alphabetic position: */
-        VBoxMediaList::iterator jt = first;
-        for (; jt != where; ++ jt)
-            if ((*jt).name().localeAwareCompare(medium.name()) > 0)
-                break;
-
-        outputMediums.insert(jt, medium);
-
-        /* Adjust the first item if inserted before it: */
-        if (jt == first)
-            --first;
-    }
-
-    /* Second pass: Add children: */
-    for (VBoxMediaList::iterator it = first; it != where;)
-    {
-        CMediumVector children = (*it).medium().GetChildren();
-        UIMedium *parent = &(*it);
-
-        ++it; /* go to the next sibling before inserting children */
-        addHardDisksToList(children, outputMediums, it, parent);
-    }
-}
-
 void VBoxGlobal::startMediumEnumeration(bool fForceStart /*= true*/)
 {
@@ -2032,72 +1832,24 @@
         return;
 
-    /* Compose a list of all currently known mediums & their children: */
-    m_mediums.clear();
-    addNullMediumToList(m_mediums, m_mediums.end());
-    addHardDisksToList(mVBox.GetHardDisks(), m_mediums, m_mediums.end());
-    addMediumsToList(mHost.GetDVDDrives(), m_mediums, m_mediums.end(), UIMediumType_DVD);
-    addMediumsToList(mVBox.GetDVDImages(), m_mediums, m_mediums.end(), UIMediumType_DVD);
-    addMediumsToList(mHost.GetFloppyDrives(), m_mediums, m_mediums.end(), UIMediumType_Floppy);
-    addMediumsToList(mVBox.GetFloppyImages(), m_mediums, m_mediums.end(), UIMediumType_Floppy);
-
-    /* Enumeration thread class: */
-    class MediaEnumThread : public QThread
-    {
-    public:
-
-        MediaEnumThread(VBoxMediaList &mediums)
-            : m_mediums(mediums.size())
-            , m_iterator(mediums.begin())
-        {
-            int i = 0;
-            for (VBoxMediaList::const_iterator it = mediums.begin(); it != mediums.end(); ++it)
-                m_mediums[i++] = *it;
-        }
-
-        void run()
-        {
-            LogFlow(("MediaEnumThread started.\n"));
-            COMBase::InitializeCOM(false);
-
-            QObject *pSelf = &vboxGlobal();
-
-            /* Enumerate medium list: */
-            for (int i = 0; i < m_mediums.size() && !m_sfCleanupInProgress; ++i)
-            {
-                m_mediums[i].blockAndQueryState();
-                QApplication::postEvent(pSelf, new UIMediumEnumeratedEvent(m_mediums[i], m_iterator));
-                ++m_iterator;
-            }
-
-            /* Post the end-of-enumeration event: */
-            if (!m_sfCleanupInProgress)
-                QApplication::postEvent(pSelf, new UIMediumsEnumeratedEvent(m_iterator));
-
-            COMBase::CleanupCOM();
-            LogFlow(("MediaEnumThread finished.\n"));
-        }
-
-    private:
-
-        QVector<UIMedium> m_mediums;
-        VBoxMediaList::iterator m_iterator;
-    };
-
-    m_pMediumEnumerationThread = new MediaEnumThread(m_mediums);
-    AssertReturnVoid(m_pMediumEnumerationThread);
-
-    /* Emit signal *after* we set m_pMediumEnumerationThread to != NULL
-     * to cause isMediaEnumerationStarted() to return TRUE from slots: */
-    emit sigMediumEnumerationStarted();
-
-    m_pMediumEnumerationThread->start();
+    /* Redirect request to medium-enumerator: */
+    m_pMediumEnumerator->enumerateMediums();
+}
+
+bool VBoxGlobal::isMediumEnumerationInProgress() const
+{
+    /* Redirect request to medium-enumerator: */
+    return m_pMediumEnumerator->isMediumEnumerationInProgress();
 }
 
 UIMedium VBoxGlobal::medium(const QString &strMediumID) const
 {
-    for (VBoxMediaList::ConstIterator it = m_mediums.begin(); it != m_mediums.end(); ++it)
-        if ((*it).id() == strMediumID)
-            return *it;
-    return UIMedium();
+    /* Redirect call to medium-enumerator: */
+    return m_pMediumEnumerator->medium(strMediumID);
+}
+
+QList<QString> VBoxGlobal::mediumIDs() const
+{
+    /* Redirect call to medium-enumerator: */
+    return m_pMediumEnumerator->mediumIDs();
 }
 
@@ -3982,51 +3734,4 @@
 // Protected members
 ////////////////////////////////////////////////////////////////////////////////
-
-bool VBoxGlobal::event(QEvent *pEvent)
-{
-    /* Handle events: */
-    switch (pEvent->type())
-    {
-        case MediumEnumeratedEventType:
-        {
-            /* Cast to corresponding event: */
-            UIMediumEnumeratedEvent *pMediumEnumeratedEvent = static_cast<UIMediumEnumeratedEvent*>(pEvent);
-
-            /* Show accessibility error message if necessary: */
-            if (pMediumEnumeratedEvent->m_medium.state() == KMediumState_Inaccessible &&
-                !pMediumEnumeratedEvent->m_medium.result().isOk())
-                msgCenter().cannotGetMediaAccessibility(pMediumEnumeratedEvent->m_medium);
-
-            /* Make sure incoming iterator is valid: */
-            AssertReturn(pMediumEnumeratedEvent->m_iterator != m_mediums.end(), false);
-
-            /* Assign enumeration result to corresponding medium: */
-            *(pMediumEnumeratedEvent->m_iterator) = pMediumEnumeratedEvent->m_medium;
-
-            /* Notify listeners about newly enumerated medium: */
-            emit sigMediumEnumerated((*pMediumEnumeratedEvent->m_iterator).id());
-
-            /* Accept event: */
-            return true;
-        }
-        case MediumsEnumeratedEventType:
-        {
-            /* Cleanup enumeration thread: */
-            m_pMediumEnumerationThread->wait();
-            delete m_pMediumEnumerationThread;
-            m_pMediumEnumerationThread = 0;
-
-            /* Notify listeners about enumeration finished: */
-            emit sigMediumEnumerationFinished();
-
-            /* Accept event: */
-            return true;
-        }
-        default:
-            break;
-    }
-    /* Call to base-class: */
-    return QObject::event(pEvent);
-}
 
 bool VBoxGlobal::eventFilter (QObject *aObject, QEvent *aEvent)
@@ -4543,4 +4248,20 @@
      * but this method should be run anyway just to enumerate null UIMedium object,
      * used by some VBox smart widgets, like VBoxMediaComboBox: */
+    m_pMediumEnumerator = new UIMediumEnumerator;
+    {
+        /* Prepare medium-enumerator: */
+        connect(m_pMediumEnumerator, SIGNAL(sigMediumCreated(const QString&)),
+                this, SIGNAL(sigMediumCreated(const QString&)));
+        connect(m_pMediumEnumerator, SIGNAL(sigMediumUpdated(const QString&)),
+                this, SIGNAL(sigMediumUpdated(const QString&)));
+        connect(m_pMediumEnumerator, SIGNAL(sigMediumDeleted(const QString&)),
+                this, SIGNAL(sigMediumDeleted(const QString&)));
+        connect(m_pMediumEnumerator, SIGNAL(sigMediumEnumerationStarted()),
+                this, SIGNAL(sigMediumEnumerationStarted()));
+        connect(m_pMediumEnumerator, SIGNAL(sigMediumEnumerated(const QString&)),
+                this, SIGNAL(sigMediumEnumerated(const QString&)));
+        connect(m_pMediumEnumerator, SIGNAL(sigMediumEnumerationFinished()),
+                this, SIGNAL(sigMediumEnumerationFinished()));
+    }
     if (agressiveCaching())
         startMediumEnumeration();
@@ -4599,11 +4320,7 @@
     UIExtraDataEventHandler::destroy();
 
-    /* Cleanup medium enumeration thread: */
-    if (m_pMediumEnumerationThread)
-    {
-        m_pMediumEnumerationThread->wait();
-        delete m_pMediumEnumerationThread;
-        m_pMediumEnumerationThread = 0;
-    }
+    /* Cleanup medium-enumerator: */
+    delete m_pMediumEnumerator;
+    m_pMediumEnumerator = 0;
 
     if (mSelectorWnd)
@@ -4621,6 +4338,4 @@
     mTypes.clear();
 
-    /* media list contains a lot of CUUnknown, release them */
-    m_mediums.clear();
     /* the last steps to ensure we don't use COM any more */
     mHost.detach();
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h	(revision 48301)
@@ -52,4 +52,5 @@
 class CUSBDevice;
 class QSpinBox;
+class UIMediumEnumerator;
 
 // VBoxGlobal class
@@ -253,7 +254,7 @@
     void startMediumEnumeration(bool fForceStart = true);
     bool agressiveCaching() const { return mAgressiveCaching; }
-    bool isMediumEnumerationInProgress() const { return !!m_pMediumEnumerationThread; }
+    bool isMediumEnumerationInProgress() const;
     UIMedium medium(const QString &strMediumID) const;
-    const VBoxMediaList &currentMediaList() const { return m_mediums; }
+    QList<QString> mediumIDs() const;
 
     /* various helpers */
@@ -395,5 +396,4 @@
 protected:
 
-    bool event(QEvent *pEvent);
     bool eventFilter (QObject *, QEvent *);
 
@@ -426,6 +426,6 @@
     bool mShowStartVMErrors;
 
-    QThread *m_pMediumEnumerationThread;
-    VBoxMediaList m_mediums;
+    /* Variable: Medium-enumeration stuff: */
+    UIMediumEnumerator *m_pMediumEnumerator;
 
     RenderMode vm_render_mode;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.cpp	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.cpp	(revision 48301)
@@ -37,4 +37,5 @@
 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
 
+QString UIMedium::m_sstrNullID = QUuid().toString().remove('{').remove('}');
 QString UIMedium::m_sstrTable = QString("<table>%1</table>");
 QString UIMedium::m_sstrRow = QString("<tr><td>%1</td></tr>");
@@ -43,5 +44,4 @@
     : m_type(UIMediumType_Invalid)
     , m_state(KMediumState_NotCreated)
-    , m_pParent(0)
 {
     refresh();
@@ -49,9 +49,8 @@
 }
 
-UIMedium::UIMedium(const CMedium &medium, UIMediumType type, UIMedium *pParent /*= 0*/)
+UIMedium::UIMedium(const CMedium &medium, UIMediumType type)
     : m_medium(medium)
     , m_type(type)
     , m_state(KMediumState_NotCreated)
-    , m_pParent(pParent)
 {
     refresh();
@@ -63,5 +62,4 @@
     , m_type(type)
     , m_state(state)
-    , m_pParent(0)
 {
     refresh();
@@ -106,5 +104,6 @@
     m_curStateMachineIds = other.curStateMachineIds();
 
-    m_pParent = other.parent();
+    m_strParentID = other.parentID();
+    m_strRootID = other.rootID();
 
     m_noDiffs = other.cache();
@@ -194,4 +193,7 @@
     }
 
+    /* Initialize parent/root IDs: */
+    m_strParentID = nullID();
+    m_strRootID = m_strId;
     if (m_type == UIMediumType_HardDisk)
     {
@@ -207,23 +209,12 @@
         m_fReadOnly = m_medium.GetReadOnly();
 
-        /* Adjust the parent if its possible: */
+        /* Adjust parent/root IDs: */
         CMedium parentMedium = m_medium.GetParent();
-        Assert(!parentMedium.isNull() || m_pParent == NULL);
-
-        if (!parentMedium.isNull() && (m_pParent == NULL || m_pParent->m_medium != parentMedium))
-        {
-            /* Search for the parent (might be there): */
-            const VBoxMediaList &list = vboxGlobal().currentMediaList();
-            for (VBoxMediaList::const_iterator it = list.begin(); it != list.end(); ++it)
-            {
-                if ((*it).m_type != UIMediumType_HardDisk)
-                    break;
-
-                if ((*it).m_medium == parentMedium)
-                {
-                    m_pParent = unconst(&*it);
-                    break;
-                }
-            }
+        if (!parentMedium.isNull())
+            m_strParentID = parentMedium.GetId();
+        while (!parentMedium.isNull())
+        {
+            m_strRootID = parentMedium.GetId();
+            parentMedium = parentMedium.GetParent();
         }
     }
@@ -371,15 +362,14 @@
 }
 
-/**
- * Returns a root medium of this medium. For non-hard disk media, this is always
- * this medium itself.
- */
-UIMedium &UIMedium::root() const
-{
-    UIMedium *pRoot = unconst(this);
-    while (pRoot->m_pParent != NULL)
-        pRoot = pRoot->m_pParent;
-
-    return *pRoot;
+UIMedium UIMedium::parent() const
+{
+    /* Redirect call to VBoxGlobal: */
+    return vboxGlobal().medium(m_strParentID);
+}
+
+UIMedium UIMedium::root() const
+{
+    /* Redirect call to VBoxGlobal: */
+    return vboxGlobal().medium(m_strRootID);
 }
 
@@ -500,5 +490,6 @@
     QString strDetails, strText;
 
-    UIMedium *pRoot = unconst(this);
+    /* Note: root accessible only if medium enumerated: */
+    UIMedium rootMedium = root();
     KMediumState eState = m_state;
 
@@ -507,20 +498,18 @@
         if (fNoDiffs)
         {
-            pRoot = &this->root();
-
-            bool isDiff = (!fPredictDiff && m_pParent != NULL) || (fPredictDiff && m_fReadOnly);
+            bool isDiff = (!fPredictDiff && parentID() != nullID()) || (fPredictDiff && m_fReadOnly);
 
             strDetails = isDiff && fUseHTML ?
-                QString("<i>%1</i>, ").arg(pRoot->m_strHardDiskType) :
-                QString("%1, ").arg(pRoot->m_strHardDiskType);
+                QString("<i>%1</i>, ").arg(rootMedium.m_strHardDiskType) :
+                QString("%1, ").arg(rootMedium.m_strHardDiskType);
 
             eState = this->state(true /* fNoDiffs */);
 
-            if (pRoot->m_state == KMediumState_NotCreated)
+            if (rootMedium.m_state == KMediumState_NotCreated)
                 eState = KMediumState_NotCreated;
         }
         else
         {
-            strDetails = QString("%1, ").arg(pRoot->m_strHardDiskType);
+            strDetails = QString("%1, ").arg(rootMedium.m_strHardDiskType);
         }
     }
@@ -539,11 +528,11 @@
             break;
         default:
-            strDetails += m_type == UIMediumType_HardDisk ? pRoot->m_strLogicalSize : pRoot->m_strSize;
+            strDetails += m_type == UIMediumType_HardDisk ? rootMedium.m_strLogicalSize : rootMedium.m_strSize;
             break;
     }
 
     strDetails = fUseHTML ?
-        QString("%1 (<nobr>%2</nobr>)").arg(VBoxGlobal::locationForHTML(pRoot->m_strName), strDetails) :
-        QString("%1 (%2)").arg(VBoxGlobal::locationForHTML(pRoot->m_strName), strDetails);
+        QString("%1 (<nobr>%2</nobr>)").arg(VBoxGlobal::locationForHTML(rootMedium.m_strName), strDetails) :
+        QString("%1 (%2)").arg(VBoxGlobal::locationForHTML(rootMedium.m_strName), strDetails);
 
     return strDetails;
@@ -553,5 +542,5 @@
 QString UIMedium::nullID()
 {
-    return QUuid().toString().remove('{').remove('}');
+    return m_sstrNullID;
 }
 
@@ -569,9 +558,9 @@
 
     m_noDiffs.state = m_state;
-    for (UIMedium *cur = m_pParent; cur != NULL; cur = cur->m_pParent)
-    {
-        if (cur->m_state == KMediumState_Inaccessible)
-        {
-            m_noDiffs.state = cur->m_state;
+    for (UIMedium parentMedium = parent(); !parentMedium.isNull(); parentMedium = parentMedium.parent())
+    {
+        if (parentMedium.m_state == KMediumState_Inaccessible)
+        {
+            m_noDiffs.state = parentMedium.m_state;
 
             if (m_noDiffs.toolTip.isNull())
@@ -581,7 +570,7 @@
                                                                  "mode to inspect these media.", "medium"));
 
-            if (!cur->m_result.isOk())
+            if (!parentMedium.m_result.isOk())
             {
-                m_noDiffs.result = cur->m_result;
+                m_noDiffs.result = parentMedium.m_result;
                 break;
             }
@@ -589,5 +578,5 @@
     }
 
-    if (m_pParent != NULL && !m_fReadOnly)
+    if (parentID() != nullID() && !m_fReadOnly)
     {
         m_noDiffs.toolTip = root().tip() +
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.h	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.h	(revision 48301)
@@ -22,5 +22,4 @@
 /* Qt includes: */
 #include <QMap>
-#include <QLinkedList>
 #include <QPixmap>
 
@@ -89,5 +88,5 @@
     /* Lazy wrapping constructor:
      * Creates a uimedium associated with the given medium. */
-    UIMedium(const CMedium &medium, UIMediumType type, UIMedium *pParent = 0);
+    UIMedium(const CMedium &medium, UIMediumType type);
 
     /* Wrapping constructor with known medium state:
@@ -196,10 +195,9 @@
     const QList <QString> &curStateMachineIds() const { return m_curStateMachineIds; }
 
-    /**
-     * Returns a parent medium. For non-hard disk media, this is always NULL.
-     */
-    UIMedium* parent() const { return m_pParent; }
-
-    UIMedium& root() const;
+    /* API: Parent/Root stuff: */
+    QString parentID() const { return m_strParentID; }
+    QString rootID() const { return m_strRootID; }
+    UIMedium parent() const;
+    UIMedium root() const;
 
     QString toolTip(bool fNoDiffs = false, bool fCheckRO = false, bool fNullAllowed = false) const;
@@ -259,8 +257,10 @@
     QList<QString> m_curStateMachineIds;
 
-    UIMedium *m_pParent;
+    QString m_strParentID;
+    QString m_strRootID;
 
     NoDiffsCache m_noDiffs;
 
+    static QString m_sstrNullID;
     static QString m_sstrTable;
     static QString m_sstrRow;
@@ -268,5 +268,4 @@
 Q_DECLARE_METATYPE(UIMedium);
 
-typedef QLinkedList<UIMedium> VBoxMediaList;
 typedef QMap<QString, UIMedium> UIMediumMap;
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumEnumerator.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumEnumerator.cpp	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumEnumerator.cpp	(revision 48301)
@@ -100,5 +100,5 @@
     /* Get medium ID: */
     QString strMediumID = medium.id();
-//    printf("UIMediumEnumerator: Medium with ID={%s} created.\n", strMediumID.toAscii().constData());
+    LogRel(("UIMediumEnumerator: Medium with ID={%s} created.\n", strMediumID.toAscii().constData()));
 
     /* Make sure medium doesn't exists already: */
@@ -116,5 +116,5 @@
     /* Get medium ID: */
     QString strMediumID = medium.id();
-//    printf("UIMediumEnumerator: Medium with ID={%s} updated.\n", strMediumID.toAscii().constData());
+    LogRel(("UIMediumEnumerator: Medium with ID={%s} updated.\n", strMediumID.toAscii().constData()));
 
     /* Make sure medium still exists: */
@@ -130,5 +130,5 @@
 void UIMediumEnumerator::deleteMedium(const QString &strMediumID)
 {
-//    printf("UIMediumEnumerator: Medium with ID={%s} removed.\n", strMediumID.toAscii().constData());
+    LogRel(("UIMediumEnumerator: Medium with ID={%s} removed.\n", strMediumID.toAscii().constData()));
 
     /* Make sure medium still exists: */
@@ -159,5 +159,5 @@
 
     /* Notify listener: */
-//    printf("UIMediumEnumerator: Medium-enumeration started...\n");
+    LogRel(("UIMediumEnumerator: Medium-enumeration started...\n"));
     m_fMediumEnumerationInProgress = true;
     emit sigMediumEnumerationStarted();
@@ -171,5 +171,5 @@
 void UIMediumEnumerator::sltHandleMachineUpdate(QString strMachineID)
 {
-//    printf("Machine event received, ID = %s\n", strMachineID.toAscii().constData());
+    LogRel(("Machine event received, ID = %s\n", strMachineID.toAscii().constData()));
 
     /* Compose a map of previous usage: */
@@ -182,5 +182,5 @@
             oldUsage << strMediumID;
     }
-//    printf("Old usage: %s\n", oldUsage.join(", ").toAscii().constData());
+    LogRel(("Old usage: %s\n", oldUsage.join(", ").toAscii().constData()));
 
     /* Compose a map of current usage: */
@@ -201,5 +201,5 @@
         }
     }
-//    printf("New usage: %s\n", newUsage.join(", ").toAscii().constData());
+    LogRel(("New usage: %s\n", newUsage.join(", ").toAscii().constData()));
 
     /* Manipulations over the sets: */
@@ -210,6 +210,6 @@
     QStringList excludedList = excludedSet.toList();
     QStringList includedList = includedSet.toList();
-//    printf("Excluded items of machine usage: %s\n", excludedList.join(", ").toAscii().constData());
-//    printf("Included items of machine usage: %s\n", includedList.join(", ").toAscii().constData());
+    LogRel(("Excluded items of machine usage: %s\n", excludedList.join(", ").toAscii().constData()));
+    LogRel(("Included items of machine usage: %s\n", includedList.join(", ").toAscii().constData()));
 
     /* For each of excluded items: */
@@ -244,5 +244,5 @@
     }
 
-//    printf("Machine event processed, ID = %s\n", strMachineID.toAscii().constData());
+    LogRel(("Machine event processed, ID = %s\n", strMachineID.toAscii().constData()));
 }
 
@@ -256,5 +256,5 @@
     UIMedium medium = pTask->data().value<UIMedium>();
     QString strMediumID = medium.id();
-//    printf("UIMediumEnumerator: Medium with ID={%s} enumerated.\n", strMediumID.toAscii().constData());
+    LogRel(("UIMediumEnumerator: Medium with ID={%s} enumerated.\n", strMediumID.toAscii().constData()));
 
     /* Delete task: */
@@ -275,5 +275,5 @@
     {
         /* Notify listener: */
-//        printf("UIMediumEnumerator: Medium-enumeration finished!\n");
+        LogRel(("UIMediumEnumerator: Medium-enumeration finished!\n"));
         m_fMediumEnumerationInProgress = false;
         emit sigMediumEnumerationFinished();
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp	(revision 48301)
@@ -38,5 +38,4 @@
 #include "QILabel.h"
 #include "UIIconPool.h"
-#include "UIVirtualBoxEventHandler.h"
 #include "UIMediumTypeChangeDialog.h"
 
@@ -421,10 +420,26 @@
     mTabWidget->setTabIcon(FDTab, m_iconFD);
 
-    /* Load current mediums: */
-    const VBoxMediaList &mediums = vboxGlobal().currentMediaList();
-    prepareToRefresh(mediums.size());
-    VBoxMediaList::const_iterator it;
-    for (it = mediums.begin(); it != mediums.end(); ++it)
-        sltHandleMediumCreated((*it).id());
+    /* Load mediums: */
+    QList<QString> mediumIDs = vboxGlobal().mediumIDs();
+    QList<QString> loadedMediumIDs;
+    prepareToRefresh(mediumIDs.size());
+    while (!mediumIDs.isEmpty())
+    {
+        /* Get first available medium: */
+        QString strMediumID = mediumIDs.first();
+        UIMedium medium = vboxGlobal().medium(strMediumID);
+        /* Make sure medium parent (if any) is already in list: */
+        while (medium.parentID() != UIMedium::nullID() &&
+               !loadedMediumIDs.contains(medium.parentID()))
+        {
+            medium = medium.parent();
+            strMediumID = medium.id();
+        }
+        /* Insert resulting medium into tree: */
+        int iItemIndex = mediumIDs.indexOf(strMediumID);
+        AssertReturnVoid(iItemIndex != -1);
+        loadedMediumIDs.append(mediumIDs.takeAt(iItemIndex));
+        sltHandleMediumCreated(strMediumID);
+    }
 
     /* Select the first item to be the current one
@@ -878,9 +893,4 @@
     connect(&vboxGlobal(), SIGNAL(sigMediumEnumerationFinished()),
             this, SLOT(sltHandleMediumEnumerationFinish()));
-
-    /* Configure Main event connections: */
-    connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)), this, SLOT(refreshAll()));
-    connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)), this, SLOT(refreshAll()));
-    connect(gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)), this, SLOT(refreshAll()));
 }
 
@@ -1159,13 +1169,26 @@
     {
         /* Emulate (possible partial) medium-enumeration: */
-        const VBoxMediaList &mediums = vboxGlobal().currentMediaList();
-        prepareToRefresh(mediums.size());
-        VBoxMediaList::const_iterator it;
-        /* Add every medium we have into trees: */
-        for (it = mediums.begin(); it != mediums.end(); ++it)
-        {
-            sltHandleMediumCreated((*it).id());
-            /* But advance progress-bar only for created mediums: */
-            if ((*it).state() != KMediumState_NotCreated)
+        QList<QString> mediumIDs = vboxGlobal().mediumIDs();
+        QList<QString> loadedMediumIDs;
+        prepareToRefresh(mediumIDs.size());
+        while (!mediumIDs.isEmpty())
+        {
+            /* Get first available medium: */
+            QString strMediumID = mediumIDs.first();
+            UIMedium medium = vboxGlobal().medium(strMediumID);
+            /* Make sure medium parent (if any) is already in list: */
+            while (medium.parentID() != UIMedium::nullID() &&
+                   !loadedMediumIDs.contains(medium.parentID()))
+            {
+                medium = medium.parent();
+                strMediumID = medium.id();
+            }
+            /* Insert resulting medium into tree: */
+            int iItemIndex = mediumIDs.indexOf(strMediumID);
+            AssertReturnVoid(iItemIndex != -1);
+            loadedMediumIDs.append(mediumIDs.takeAt(iItemIndex));
+            sltHandleMediumCreated(strMediumID);
+            /* Advance progress-bar only for created mediums: */
+            if (medium.state() != KMediumState_NotCreated)
                 m_pProgressBar->setValue(m_pProgressBar->value() + 1);
         }
@@ -1640,10 +1663,10 @@
         {
             /* False for children: */
-            return !pItem->medium().parent();
+            return pItem->medium().parentID() == UIMedium::nullID();
         }
         case Action_Modify:
         {
             /* False for children: */
-            return !pItem->medium().parent();
+            return pItem->medium().parentID() == UIMedium::nullID();
         }
         case Action_Remove:
@@ -1730,17 +1753,17 @@
 
 /* static */
-bool UIMediumManager::isMediumAttachedToHiddenMachinesOnly(const UIMedium &medium)
+bool UIMediumManager::isMediumAttachedToHiddenMachinesOnly(UIMedium medium)
 {
     /* Iterate till the root: */
-    const UIMedium *pMedium = &medium;
     do
     {
-        /* Ignore medium if its hidden or attached to hidden machines only: */
-        if (pMedium->isHidden())
+        /* Ignore medium if its hidden
+         * or attached to hidden machines only: */
+        if (medium.isHidden())
             return true;
         /* Move iterator to parent: */
-        pMedium = pMedium->parent();
-    }
-    while (pMedium);
+        medium = medium.parent();
+    }
+    while (!medium.isNull());
     /* False by default: */
     return false;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.h	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.h	(revision 48301)
@@ -152,5 +152,5 @@
 
     /* Static helper: Enumeration stuff: */
-    static bool isMediumAttachedToHiddenMachinesOnly(const UIMedium &medium);
+    static bool isMediumAttachedToHiddenMachinesOnly(UIMedium medium);
 
     /* Variable: Singleton instance: */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp	(revision 48301)
@@ -191,12 +191,16 @@
 
     /* Look for at least one inaccessible medium: */
-    const VBoxMediaList &list = vboxGlobal().currentMediaList();
-    VBoxMediaList::const_iterator it;
-    for (it = list.begin(); it != list.end(); ++it)
-        if ((*it).state() == KMediumState_Inaccessible)
+    bool fIsThereAnyInaccessibleMedium = false;
+    foreach (const QString &strMediumID, vboxGlobal().mediumIDs())
+    {
+        if (vboxGlobal().medium(strMediumID).state() == KMediumState_Inaccessible)
+        {
+            fIsThereAnyInaccessibleMedium = true;
             break;
+        }
+    }
 
     /* Warn the user about inaccessible medium: */
-    if (it != list.end() && !msgCenter().warnAboutInaccessibleMedia())
+    if (fIsThereAnyInaccessibleMedium && !msgCenter().warnAboutInaccessibleMedia())
     {
         /* Open the MM window (without refresh): */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp	(revision 48301)
@@ -1961,7 +1961,6 @@
                     storageAttachmentData.m_fAttachmentTempEject = attachment.GetTemporaryEject();
                     storageAttachmentData.m_fAttachmentNonRotational = attachment.GetNonRotational();
-                    CMedium cmedium = attachment.GetMedium();
-                    UIMedium uimedium = cmedium.isNull() ? UIMedium() : vboxGlobal().medium(cmedium.GetId());
-                    storageAttachmentData.m_strAttachmentMediumId = uimedium.id();
+                    const CMedium cmedium = attachment.GetMedium();
+                    storageAttachmentData.m_strAttachmentMediumId = cmedium.isNull() ? UIMedium::nullID() : cmedium.GetId();
                 }
 
@@ -3192,9 +3191,7 @@
 void UIMachineSettingsStorage::addChooseHostDriveActions(QMenu *pOpenMediumMenu)
 {
-    const VBoxMediaList &mediums = vboxGlobal().currentMediaList();
-    VBoxMediaList::const_iterator it;
-    for (it = mediums.begin(); it != mediums.end(); ++it)
-    {
-        const UIMedium &medium = *it;
+    foreach (const QString &strMediumID, vboxGlobal().mediumIDs())
+    {
+        const UIMedium medium = vboxGlobal().medium(strMediumID);
         if (medium.isHostDrive() && m_pMediumIdHolder->type() == medium.type())
         {
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp	(revision 48300)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp	(revision 48301)
@@ -67,7 +67,6 @@
     clear(), mMedia.clear();
 
-    VBoxMediaList list (vboxGlobal().currentMediaList());
-    foreach (UIMedium medium, list)
-        sltHandleMediumCreated(medium.id());
+    foreach (const QString &strMediumID, vboxGlobal().mediumIDs())
+        sltHandleMediumCreated(strMediumID);
 
     /* If at least one real medium present, process null medium */
@@ -178,5 +177,5 @@
 
     /* In !mShowDiffs mode, we ignore all diffs: */
-    if (!mShowDiffs && medium.type() == UIMediumType_HardDisk && medium.parent())
+    if (!mShowDiffs && medium.type() == UIMediumType_HardDisk && medium.parentID() != UIMedium::nullID())
         return;
 
@@ -227,8 +226,5 @@
     /* If no real medium left, add the NULL medium: */
     if (count() == 0)
-    {
-        UIMedium nullMedium;
-        sltHandleMediumCreated(nullMedium.id());
-    }
+        sltHandleMediumCreated(UIMedium::nullID());
 
     /* Emit the signal to ensure the parent dialog handles the change of
