Index: trunk/src/VBox/Main/DHCPServerImpl.cpp
===================================================================
--- trunk/src/VBox/Main/DHCPServerImpl.cpp	(revision 25183)
+++ trunk/src/VBox/Main/DHCPServerImpl.cpp	(revision 25184)
@@ -52,10 +52,4 @@
         return;
 
-//    /* we uninit children and reset mParent
-//     * and VirtualBox::removeDependentChild() needs a write lock */
-//    AutoMultiWriteLock2 alock (mVirtualBox->lockHandle(), this->treeLock());
-
-    mVirtualBox->removeDependentChild (this);
-
     unconst(mVirtualBox).setNull();
 }
@@ -78,8 +72,4 @@
     m.upperIP = "0.0.0.0";
 
-    /* register with VirtualBox early, since uninit() will
-     * unconditionally unregister on failure */
-    aVirtualBox->addDependentChild (this);
-
     /* Confirm a successful initialization */
     autoInitSpan.setSucceeded();
@@ -97,6 +87,4 @@
     /* share VirtualBox weakly (parent remains NULL so far) */
     unconst(mVirtualBox) = aVirtualBox;
-
-    aVirtualBox->addDependentChild (this);
 
     unconst(mName) = data.strNetworkName;
Index: trunk/src/VBox/Main/MachineImpl.cpp
===================================================================
--- trunk/src/VBox/Main/MachineImpl.cpp	(revision 25183)
+++ trunk/src/VBox/Main/MachineImpl.cpp	(revision 25184)
@@ -395,8 +395,4 @@
     unconst(mParent) = aParent;
 
-    /* register with parent early, since uninit() will unconditionally
-     * unregister on failure */
-    mParent->addDependentChild (this);
-
     /* allocate the essential machine data structure (the rest will be
      * allocated later by initDataAndChildObjects() */
@@ -691,6 +687,4 @@
     /* free the essential data structure last */
     mData.free();
-
-    mParent->removeDependentChild (this);
 
     LogFlowThisFuncLeave();
@@ -5099,5 +5093,5 @@
  *  children for writing.
  */
-HRESULT Machine::trySetRegistered (BOOL aRegistered)
+HRESULT Machine::trySetRegistered(BOOL argNewRegistered)
 {
     AssertReturn(mParent->isWriteLockOnCurrentThread(), E_FAIL);
@@ -5111,5 +5105,5 @@
     ensureNoStateDependencies();
 
-    ComAssertRet (mData->mRegistered != aRegistered, E_FAIL);
+    ComAssertRet(mData->mRegistered != argNewRegistered, E_FAIL);
 
     if (!mData->mAccessible)
@@ -5118,5 +5112,5 @@
 
         /* inaccessible machines can only be unregistered */
-        AssertReturn(!aRegistered, E_FAIL);
+        AssertReturn(!argNewRegistered, E_FAIL);
 
         /* Uninitialize ourselves here because currently there may be no
@@ -5135,5 +5129,5 @@
     AssertReturn(autoCaller.state() == Ready, E_FAIL);
 
-    if (aRegistered)
+    if (argNewRegistered)
     {
         if (mData->mRegistered)
@@ -5181,5 +5175,5 @@
      * so create it by calling saveSettings() too. */
     if (    isModified()
-         || (aRegistered && !mData->m_pMachineConfigFile->fileExists())
+         || (argNewRegistered && !mData->m_pMachineConfigFile->fileExists())
        )
     {
@@ -5195,5 +5189,5 @@
         commit();
 
-        mData->mRegistered = aRegistered;
+        mData->mRegistered = argNewRegistered;
     }
     else
@@ -5464,8 +5458,8 @@
     for (ULONG slot = 0; slot < RT_ELEMENTS (mNetworkAdapters); slot ++)
     {
-        if (mNetworkAdapters [slot])
-        {
-            mNetworkAdapters [slot]->uninit();
-            unconst(mNetworkAdapters [slot]).setNull();
+        if (mNetworkAdapters[slot])
+        {
+            mNetworkAdapters[slot]->uninit();
+            unconst(mNetworkAdapters[slot]).setNull();
         }
     }
@@ -5485,8 +5479,8 @@
     for (ULONG slot = 0; slot < RT_ELEMENTS (mParallelPorts); slot ++)
     {
-        if (mParallelPorts [slot])
-        {
-            mParallelPorts [slot]->uninit();
-            unconst(mParallelPorts [slot]).setNull();
+        if (mParallelPorts[slot])
+        {
+            mParallelPorts[slot]->uninit();
+            unconst(mParallelPorts[slot]).setNull();
         }
     }
@@ -5494,8 +5488,8 @@
     for (ULONG slot = 0; slot < RT_ELEMENTS (mSerialPorts); slot ++)
     {
-        if (mSerialPorts [slot])
-        {
-            mSerialPorts [slot]->uninit();
-            unconst(mSerialPorts [slot]).setNull();
+        if (mSerialPorts[slot])
+        {
+            mSerialPorts[slot]->uninit();
+            unconst(mSerialPorts[slot]).setNull();
         }
     }
@@ -9024,9 +9018,9 @@
     ComAssertRet (!control.isNull(), E_INVALIDARG);
 
-    /* Creating a Progress object requires the VirtualBox children lock, and
+    /* Creating a Progress object requires the VirtualBox lock, and
      * thus locking it here is required by the lock order rules. */
-    AutoMultiWriteLock2 alock(mParent->childrenLock(), this->lockHandle());
-
-    if (control.equalsTo (mData->mSession.mDirectControl))
+    AutoMultiWriteLock2 alock(mParent->lockHandle(), this->lockHandle());
+
+    if (control.equalsTo(mData->mSession.mDirectControl))
     {
         ComAssertRet (aProgress, E_POINTER);
Index: trunk/src/VBox/Main/MediumImpl.cpp
===================================================================
--- trunk/src/VBox/Main/MediumImpl.cpp	(revision 25183)
+++ trunk/src/VBox/Main/MediumImpl.cpp	(revision 25184)
@@ -896,8 +896,4 @@
     unconst(m->pVirtualBox) = aVirtualBox;
 
-    /* register with VirtualBox early, since uninit() will
-     * unconditionally unregister on failure */
-    aVirtualBox->addDependentChild(this);
-
     /* no storage yet */
     m->state = MediumState_NotCreated;
@@ -995,8 +991,4 @@
     unconst(m->pVirtualBox) = aVirtualBox;
 
-    /* register with VirtualBox early, since uninit() will
-     * unconditionally unregister on failure */
-    aVirtualBox->addDependentChild(this);
-
     /* there must be a storage unit */
     m->state = MediumState_Created;
@@ -1082,8 +1074,5 @@
     /* register with VirtualBox/parent early, since uninit() will
      * unconditionally unregister on failure */
-    if (aParent == NULL)
-        // base disk: add to global list
-        aVirtualBox->addDependentChild(this);
-    else
+    if (aParent)
     {
         // differencing image: add to parent
@@ -1226,5 +1215,4 @@
     /* share VirtualBox weakly (parent remains NULL so far) */
     unconst(m->pVirtualBox) = aVirtualBox;
-    aVirtualBox->addDependentChild(this);
 
     /* fake up a UUID which is unique, but also reproducible */
@@ -1314,7 +1302,4 @@
             deparent();
         }
-        else
-            // base image: remove it from the global list
-            m->pVirtualBox->removeDependentChild(this);
     }
 
@@ -2333,7 +2318,5 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    ComObjPtr<Medium> diff;
-    HRESULT rc = m->pVirtualBox->cast(aTarget, diff);
-    if (FAILED(rc)) return rc;
+    ComObjPtr<Medium> diff = static_cast<Medium*>(aTarget);
 
     AutoWriteLock alock(this);
@@ -2346,5 +2329,5 @@
     /* We want to be locked for reading as long as our diff child is being
      * created */
-    rc = LockRead(NULL);
+    HRESULT rc = LockRead(NULL);
     if (FAILED(rc)) return rc;
 
@@ -2386,17 +2369,13 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    ComObjPtr <Medium> target;
-    HRESULT rc = m->pVirtualBox->cast(aTarget, target);
-    if (FAILED(rc)) return rc;
-    ComObjPtr <Medium> parent;
+    ComObjPtr<Medium> target = static_cast<Medium*>(aTarget);
+    ComObjPtr<Medium> parent;
     if (aParent)
-    {
-        rc = m->pVirtualBox->cast(aParent, parent);
-        if (FAILED(rc)) return rc;
-    }
+        parent = static_cast<Medium*>(aParent);
 
     AutoMultiWriteLock3 alock(this, target, parent);
 
-    ComObjPtr <Progress> progress;
+    ComObjPtr<Progress> progress;
+    HRESULT rc = S_OK;
 
     try
@@ -3876,8 +3855,4 @@
                     }
 
-                    /* deassociate from VirtualBox, associate with parent */
-
-                    m->pVirtualBox->removeDependentChild(this);
-
                     /* we set mParent & children() */
                     AutoWriteLock treeLock(m->pVirtualBox->hardDiskTreeLockHandle());
@@ -4703,9 +4678,5 @@
 
     if (m->pParent)
-    {
-        /* deassociate from the parent, associate with VirtualBox */
-        m->pVirtualBox->addDependentChild(this);
         deparent();
-    }
 
     HRESULT rc = E_FAIL;
@@ -4713,8 +4684,8 @@
     {
         case DeviceType_DVD:
-            rc = m->pVirtualBox->unregisterDVDImage(this);
+            rc = m->pVirtualBox->unregisterImage(this, DeviceType_DVD);
             break;
         case DeviceType_Floppy:
-            rc = m->pVirtualBox->unregisterFloppyImage(this);
+            rc = m->pVirtualBox->unregisterImage(this, DeviceType_Floppy);
             break;
         case DeviceType_HardDisk:
@@ -4733,5 +4704,4 @@
             m->pParent = pParentBackup;
             m->pParent->m->llChildren.push_back(this);
-            m->pVirtualBox->removeDependentChild(this);
         }
     }
@@ -5139,9 +5109,7 @@
                 Assert(target->m->pParent.isNull());
 
-                /* associate the child with the parent and deassociate from
-                 * VirtualBox */
+                /* associate the child with the parent */
                 target->m->pParent = that;
                 that->m->llChildren.push_back(target);
-                target->m->pVirtualBox->removeDependentChild(target);
 
                 /** @todo r=klaus neither target nor that->base() are locked,
@@ -5158,9 +5126,6 @@
 
                 if (FAILED(rc))
-                {
                     /* break the parent association on failure to register */
-                    target->m->pVirtualBox->addDependentChild(target);
                     that->deparent();
-                }
             }
 
@@ -5372,9 +5337,4 @@
                         source->deparent();
                     }
-                    else
-                    {
-                        target->m->pVirtualBox->addDependentChild(target);
-                        target->m->pVirtualBox->removeDependentChild(source);
-                    }
 
                     /* then, register again */
@@ -5650,5 +5610,4 @@
                         target->m->pParent = parent;
                         parent->m->llChildren.push_back(target);
-                        target->m->pVirtualBox->removeDependentChild(target);
 
                         /* register with mVirtualBox as the last step and move to
@@ -5658,9 +5617,6 @@
 
                         if (FAILED(rc))
-                        {
                             /* break parent association on failure to register */
-                            target->m->pVirtualBox->addDependentChild(target);
                             target->deparent();     // removes target from parent
-                        }
                     }
                     else
Index: trunk/src/VBox/Main/PerformanceImpl.cpp
===================================================================
--- trunk/src/VBox/Main/PerformanceImpl.cpp	(revision 25183)
+++ trunk/src/VBox/Main/PerformanceImpl.cpp	(revision 25184)
@@ -528,5 +528,4 @@
     if (!SUCCEEDED(autoCaller.rc())) return;
 
-    Log(("PerformanceCollector::suspendSampling\n"));
     int rc = RTTimerLRStop(m.sampler);
     AssertRC(rc);
@@ -538,5 +537,4 @@
     if (!SUCCEEDED(autoCaller.rc())) return;
 
-    Log(("PerformanceCollector::resumeSampling\n"));
     int rc = RTTimerLRStart(m.sampler, 0);
     AssertRC(rc);
@@ -556,5 +554,4 @@
     if (collector->mMagic == MAGIC)
     {
-Log(("staticSamplerCallback %RX64\n", RTTimeNanoTS()));
         collector->samplerCallback();
     }
Index: trunk/src/VBox/Main/ProgressImpl.cpp
===================================================================
--- trunk/src/VBox/Main/ProgressImpl.cpp	(revision 25183)
+++ trunk/src/VBox/Main/ProgressImpl.cpp	(revision 25184)
@@ -121,8 +121,4 @@
     /* share parent weakly */
     unconst(mParent) = aParent;
-
-    /* register with parent early, since uninit() will unconditionally
-     * unregister on failure */
-    mParent->addDependentChild (this);
 #endif
 
@@ -194,6 +190,4 @@
         if (aAutoUninitSpan.initFailed() && !mId.isEmpty())
             mParent->removeProgress (mId);
-
-        mParent->removeDependentChild (this);
 
         unconst(mParent).setNull();
Index: trunk/src/VBox/Main/SharedFolderImpl.cpp
===================================================================
--- trunk/src/VBox/Main/SharedFolderImpl.cpp	(revision 25183)
+++ trunk/src/VBox/Main/SharedFolderImpl.cpp	(revision 25184)
@@ -161,5 +161,5 @@
     unconst(mVirtualBox) = aVirtualBox;
 
-    HRESULT rc = protectedInit (aVirtualBox, aName, aHostPath, aWritable);
+    HRESULT rc = protectedInit(aVirtualBox, aName, aHostPath, aWritable);
 
     /* Confirm a successful initialization when it's the case */
@@ -176,6 +176,8 @@
  *      Must be called from under the object's lock!
  */
-HRESULT SharedFolder::protectedInit (VirtualBoxBaseWithChildrenNEXT *aParent,
-                                     CBSTR aName, CBSTR aHostPath, BOOL aWritable)
+HRESULT SharedFolder::protectedInit(VirtualBoxBase *aParent,
+                                    CBSTR aName,
+                                    CBSTR aHostPath,
+                                    BOOL aWritable)
 {
     LogFlowThisFunc(("aName={%ls}, aHostPath={%ls}, aWritable={%d}\n",
@@ -221,7 +223,4 @@
     unconst(mParent) = aParent;
 
-    /* register with parent */
-    mParent->addDependentChild (this);
-
     unconst(m.name) = aName;
     unconst(m.hostPath) = hostPath;
@@ -243,7 +242,4 @@
     if (autoUninitSpan.uninitDone())
         return;
-
-    if (mParent)
-        mParent->removeDependentChild (this);
 
     unconst(mParent) = NULL;
Index: trunk/src/VBox/Main/VirtualBoxBase.cpp
===================================================================
--- trunk/src/VBox/Main/VirtualBoxBase.cpp	(revision 25183)
+++ trunk/src/VBox/Main/VirtualBoxBase.cpp	(revision 25184)
@@ -38,5 +38,10 @@
 #include "Logging.h"
 
-// VirtualBoxBaseProto methods
+#include "objectslist.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// VirtualBoxBaseProto
+//
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -286,5 +291,8 @@
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//
 // VirtualBoxBaseProto::AutoInitSpan methods
+//
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -637,5 +645,8 @@
 }
 
-// VirtualBoxBase methods
+////////////////////////////////////////////////////////////////////////////////
+//
+// VirtualBoxBase
+//
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -675,5 +686,8 @@
 }
 
-// VirtualBoxSupportTranslationBase methods
+////////////////////////////////////////////////////////////////////////////////
+//
+// VirtualBoxSupportTranslationBase
+//
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -738,5 +752,8 @@
 }
 
-// VirtualBoxSupportErrorInfoImplBase methods
+////////////////////////////////////////////////////////////////////////////////
+//
+// VirtualBoxSupportErrorInfoImplBase
+//
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -912,6 +929,4 @@
 }
 
-// VirtualBoxBaseWithChildrenNEXT methods
-////////////////////////////////////////////////////////////////////////////////
 
 /**
Index: trunk/src/VBox/Main/VirtualBoxImpl.cpp
===================================================================
--- trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 25183)
+++ trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 25184)
@@ -70,4 +70,5 @@
 
 #include "Logging.h"
+#include "objectslist.h"
 
 #ifdef RT_OS_WINDOWS
@@ -82,18 +83,4 @@
 
 #define VBOX_GLOBAL_SETTINGS_FILE "VirtualBox.xml"
-
-typedef std::vector< ComObjPtr<Machine> > MachineVector;
-
-typedef std::list< ComObjPtr<Machine> > MachineList;
-typedef std::vector< ComObjPtr<SessionMachine> > SessionMachineVector;
-typedef std::list< ComObjPtr<GuestOSType> > GuestOSTypeList;
-
-typedef std::map<Guid, ComPtr<IProgress> > ProgressMap;
-
-typedef std::list <ComObjPtr<SharedFolder> > SharedFolderList;
-typedef std::list <ComObjPtr<DHCPServer> > DHCPServerList;
-
-typedef std::map<Guid, ComObjPtr<Medium> > HardDiskMap;
-
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -169,4 +156,13 @@
 #endif
 
+typedef ObjectsList<Machine> MachinesOList;
+typedef ObjectsList<Medium> MediaOList;
+typedef ObjectsList<GuestOSType> GuestOSTypesOList;
+typedef ObjectsList<SharedFolder> SharedFoldersOList;
+typedef ObjectsList<DHCPServer> DHCPServersOList;
+
+typedef std::map<Guid, ComPtr<IProgress> > ProgressMap;
+typedef std::map<Guid, ComObjPtr<Medium> > HardDiskMap;
+
 /**
  *  Main VirtualBox data structure.
@@ -198,28 +194,28 @@
 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
 
-    MachineList                         llMachines;
-    GuestOSTypeList                     llGuestOSTypes;
+    // the following lists all have an RWLockHandle as a member and are locked
+    // individually; getting the VirtualBox object lock is NOT necessary, but
+    // see the remarks which ObjectsList method lock themselves and which require
+    // external locking
+    MachinesOList                       ollMachines;
+    GuestOSTypesOList                   ollGuestOSTypes;
+
+    MediaOList                          ollHardDisks,           // only base hard disks; the RWLockHandle in here is also used
+                                                                // for hardDiskTreeLockHandle()
+                                        ollDVDImages,
+                                        ollFloppyImages;
+    SharedFoldersOList                  ollSharedFolders;
+    DHCPServersOList                    ollDHCPServers;
+
+    // the hard disks map is an additional map sorted by UUID for quick lookup
+    // and contains ALL hard disks (base and differencing);
+    // the map must also be protected by ollHardDisks.getLockHandle()!
+    HardDiskMap                         mapHardDisks;
 
     ProgressMap                         mapProgressOperations;
-
-    MediaList                           llHardDisks,
-                                        llDVDImages,
-                                        llFloppyImages;
-    SharedFolderList                    llSharedFolders;
-    DHCPServerList                      llDHCPServers;
-
-    /// @todo NEWMEDIA do we really need this map? Used only in
-    /// find() it seems
-    HardDiskMap                         mapHardDisks;
-
     CallbackList                        llCallbacks;
 
     RWLockHandle                        mtxProgressOperations;
             // protects mutex operations; "leaf" lock, no other lock may be requested after this
-    RWLockHandle                        mtxHardDiskTree;
-            // protects the hard disk tree; this is implemented here, but only requested through
-            // Medium::treeLock, which returns exactly this
-    RWLockHandle                        mtxChildrenMap;
-            // used for VirtualBoxWithChildrenNEXT management
 
     // the following are data for the client watcher thread
@@ -373,5 +369,5 @@
                                           Global::sOSTypes [i].numSerialEnabled);
                 if (SUCCEEDED(rc))
-                    m->llGuestOSTypes.push_back (guestOSTypeObj);
+                    m->ollGuestOSTypes.addChild(guestOSTypeObj);
             }
             ComAssertComRCThrowRC (rc);
@@ -533,5 +529,5 @@
         if (FAILED(rc)) return rc;
 
-        rc = registerDVDImage(pImage, false /* aSaveRegistry */);
+        rc = registerImage(pImage, DeviceType_DVD, false /* aSaveRegistry */);
         if (FAILED(rc)) return rc;
     }
@@ -548,5 +544,5 @@
         if (FAILED(rc)) return rc;
 
-        rc = registerFloppyImage(pImage, false /* aSaveRegistry */);
+        rc = registerImage(pImage, DeviceType_Floppy, false /* aSaveRegistry */);
         if (FAILED(rc)) return rc;
     }
@@ -568,28 +564,14 @@
     /* tell all our child objects we've been uninitialized */
 
-    LogFlowThisFunc(("Uninitializing machines (%d)...\n", m->llMachines.size()));
-    if (m->llMachines.size())
-    {
-        MachineList::iterator it = m->llMachines.begin();
-        while (it != m->llMachines.end())
-            (*it++)->uninit();
-        m->llMachines.clear();
-    }
-
-    /* Uninit all other children still referenced by clients (unregistered
-     * machines, hard disks, DVD/floppy images, server-side progress
-     * operations). */
-    uninitDependentChildren();
-
-    m->mapHardDisks.clear();
-
-    m->llFloppyImages.clear();
-    m->llDVDImages.clear();
-    m->llHardDisks.clear();
-    m->llDHCPServers.clear();
+    LogFlowThisFunc(("Uninitializing machines (%d)...\n", m->ollMachines.size()));
+    m->ollMachines.uninitAll();
+    m->ollFloppyImages.uninitAll();
+    m->ollDVDImages.uninitAll();
+    m->ollHardDisks.uninitAll();
+    m->ollDHCPServers.uninitAll();
 
     m->mapProgressOperations.clear();
 
-    m->llGuestOSTypes.clear();
+    m->ollGuestOSTypes.uninitAll();
 
     /* Note that we release singleton children after we've all other children.
@@ -788,7 +770,6 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoReadLock alock(this);
-
-    SafeIfaceArray<IMachine> machines(m->llMachines);
+    AutoReadLock al(m->ollMachines.getLockHandle());
+    SafeIfaceArray<IMachine> machines(m->ollMachines.getList());
     machines.detachTo(ComSafeArrayOutArg(aMachines));
 
@@ -804,7 +785,6 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoReadLock alock(this);
-
-    SafeIfaceArray<IMedium> hardDisks(m->llHardDisks);
+    AutoReadLock al(m->ollHardDisks.getLockHandle());
+    SafeIfaceArray<IMedium> hardDisks(m->ollHardDisks.getList());
     hardDisks.detachTo(ComSafeArrayOutArg(aHardDisks));
 
@@ -812,6 +792,5 @@
 }
 
-STDMETHODIMP
-VirtualBox::COMGETTER(DVDImages) (ComSafeArrayOut(IMedium *, aDVDImages))
+STDMETHODIMP VirtualBox::COMGETTER(DVDImages) (ComSafeArrayOut(IMedium *, aDVDImages))
 {
     if (ComSafeArrayOutIsNull(aDVDImages))
@@ -821,7 +800,6 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoReadLock alock(this);
-
-    SafeIfaceArray<IMedium> images(m->llDVDImages);
+    AutoReadLock al(m->ollDVDImages.getLockHandle());
+    SafeIfaceArray<IMedium> images(m->ollDVDImages.getList());
     images.detachTo(ComSafeArrayOutArg(aDVDImages));
 
@@ -829,6 +807,5 @@
 }
 
-STDMETHODIMP
-VirtualBox::COMGETTER(FloppyImages) (ComSafeArrayOut(IMedium *, aFloppyImages))
+STDMETHODIMP VirtualBox::COMGETTER(FloppyImages) (ComSafeArrayOut(IMedium *, aFloppyImages))
 {
     if (ComSafeArrayOutIsNull(aFloppyImages))
@@ -838,7 +815,6 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoReadLock alock(this);
-
-    SafeIfaceArray<IMedium> images(m->llFloppyImages);
+    AutoReadLock al(m->ollFloppyImages.getLockHandle());
+    SafeIfaceArray<IMedium> images(m->ollFloppyImages.getList());
     images.detachTo(ComSafeArrayOutArg(aFloppyImages));
 
@@ -855,5 +831,4 @@
     /* protect mProgressOperations */
     AutoReadLock safeLock(m->mtxProgressOperations);
-
     SafeIfaceArray<IProgress> progress(m->mapProgressOperations);
     progress.detachTo(ComSafeArrayOutArg(aOperations));
@@ -869,7 +844,6 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoReadLock alock(this);
-
-    SafeIfaceArray<IGuestOSType> ostypes(m->llGuestOSTypes);
+    AutoReadLock al(m->ollGuestOSTypes.getLockHandle());
+    SafeIfaceArray<IGuestOSType> ostypes(m->ollGuestOSTypes.getList());
     ostypes.detachTo(ComSafeArrayOutArg(aGuestOSTypes));
 
@@ -877,6 +851,5 @@
 }
 
-STDMETHODIMP
-VirtualBox::COMGETTER(SharedFolders) (ComSafeArrayOut(ISharedFolder *, aSharedFolders))
+STDMETHODIMP VirtualBox::COMGETTER(SharedFolders) (ComSafeArrayOut(ISharedFolder *, aSharedFolders))
 {
 #ifndef RT_OS_WINDOWS
@@ -919,7 +892,6 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoReadLock alock(this);
-
-    SafeIfaceArray<IDHCPServer> svrs (m->llDHCPServers);
+    AutoReadLock al(m->ollDHCPServers.getLockHandle());
+    SafeIfaceArray<IDHCPServer> svrs (m->ollDHCPServers.getList());
     svrs.detachTo(ComSafeArrayOutArg(aDHCPServers));
 
@@ -1177,5 +1149,5 @@
 
 /** @note Locks objects! */
-STDMETHODIMP VirtualBox::RegisterMachine (IMachine *aMachine)
+STDMETHODIMP VirtualBox::RegisterMachine(IMachine *aMachine)
 {
     CheckComArgNotNull(aMachine);
@@ -1190,28 +1162,15 @@
     if (FAILED(rc)) return rc;
 
-    /* We need the children map lock here to keep the getDependentChild() result
-     * valid until we finish */
-    AutoReadLock chLock (childrenLock());
-
     /* We can safely cast child to Machine * here because only Machine
      * implementations of IMachine can be among our children. */
-    Machine *machine = static_cast <Machine *> (getDependentChild (aMachine));
-    if (machine == NULL)
-    {
-        /* this machine was not created by CreateMachine() or opened by
-         * OpenMachine() or loaded during startup */
-        return setError (VBOX_E_INVALID_OBJECT_STATE,
-            tr ("The machine named '%ls' is not created within this "
-                "VirtualBox instance"), name.raw());
-    }
-
-    AutoCaller machCaller (machine);
-    ComAssertComRCRetRC (machCaller.rc());
-
-    rc = registerMachine (machine);
-
+    Machine *pMachine = static_cast<Machine*>(aMachine);
+
+    AutoCaller machCaller(pMachine);
+    ComAssertComRCRetRC(machCaller.rc());
+
+    rc = registerMachine(pMachine);
     /* fire an event */
     if (SUCCEEDED(rc))
-        onMachineRegistered(machine->getId(), TRUE);
+        onMachineRegistered(pMachine->getId(), TRUE);
 
     return rc;
@@ -1219,5 +1178,5 @@
 
 /** @note Locks objects! */
-STDMETHODIMP VirtualBox::GetMachine (IN_BSTR aId, IMachine **aMachine)
+STDMETHODIMP VirtualBox::GetMachine(IN_BSTR aId, IMachine **aMachine)
 {
     CheckComArgOutSafeArrayPointerValid(aMachine);
@@ -1236,5 +1195,5 @@
 
 /** @note Locks this object for reading, then some machine objects for reading. */
-STDMETHODIMP VirtualBox::FindMachine (IN_BSTR aName, IMachine **aMachine)
+STDMETHODIMP VirtualBox::FindMachine(IN_BSTR aName, IMachine **aMachine)
 {
     LogFlowThisFuncEnter();
@@ -1248,15 +1207,10 @@
 
     /* start with not found */
-    ComObjPtr<Machine> machine;
-    MachineList machines;
-    {
-        /* take a copy for safe iteration outside the lock */
-        AutoReadLock alock(this);
-        machines = m->llMachines;
-    }
-
-    for (MachineList::iterator it = machines.begin();
-         !machine && it != machines.end();
-         ++ it)
+    ComObjPtr<Machine> pMachineFound;
+
+    AutoReadLock al(m->ollMachines.getLockHandle());
+    for (MachinesOList::iterator it = m->ollMachines.begin();
+         it != m->ollMachines.end();
+         ++it)
     {
         ComObjPtr<Machine> &pMachine2 = *it;
@@ -1269,15 +1223,18 @@
             AutoReadLock machLock(pMachine2);
             if (pMachine2->getName() == aName)
-                machine = pMachine2;
+            {
+                pMachineFound = pMachine2;
+                break;
+            }
         }
     }
 
     /* this will set (*machine) to NULL if machineObj is null */
-    machine.queryInterfaceTo(aMachine);
-
-    HRESULT rc = machine
+    pMachineFound.queryInterfaceTo(aMachine);
+
+    HRESULT rc = pMachineFound
         ? S_OK
-        : setError (VBOX_E_OBJECT_NOT_FOUND,
-            tr ("Could not find a registered machine named '%ls'"), aName);
+        : setError(VBOX_E_OBJECT_NOT_FOUND,
+                   tr("Could not find a registered machine named '%ls'"), aName);
 
     LogFlowThisFunc(("aName=\"%ls\", aMachine=%p, rc=%08X\n", aName, *aMachine, rc));
@@ -1288,6 +1245,6 @@
 
 /** @note Locks objects! */
-STDMETHODIMP VirtualBox::UnregisterMachine (IN_BSTR  aId,
-                                            IMachine **aMachine)
+STDMETHODIMP VirtualBox::UnregisterMachine(IN_BSTR  aId,
+                                           IMachine **aMachine)
 {
     Guid id(aId);
@@ -1298,16 +1255,16 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
+    // find machine from the given ID
+    ComObjPtr<Machine> pMachine;
+    HRESULT rc = findMachine(id, true /* setError */, &pMachine);
+    if (FAILED(rc)) return rc;
+
+    // trySetRegistered needs VirtualBox object write lock
     AutoWriteLock alock(this);
-
-    ComObjPtr<Machine> machine;
-
-    HRESULT rc = findMachine (id, true /* setError */, &machine);
+    rc = pMachine->trySetRegistered(FALSE);
     if (FAILED(rc)) return rc;
 
-    rc = machine->trySetRegistered (FALSE);
-    if (FAILED(rc)) return rc;
-
     /* remove from the collection of registered machines */
-    m->llMachines.remove (machine);
+    m->ollMachines.removeChild(pMachine);
 
     /* save the global registry */
@@ -1315,8 +1272,8 @@
 
     /* return the unregistered machine to the caller */
-    machine.queryInterfaceTo(aMachine);
+    pMachine.queryInterfaceTo(aMachine);
 
     /* fire an event */
-    onMachineRegistered (id, FALSE);
+    onMachineRegistered(id, FALSE);
 
     return rc;
@@ -1461,5 +1418,5 @@
     if (SUCCEEDED(rc))
     {
-        rc = registerDVDImage (image);
+        rc = registerImage(image, DeviceType_DVD);
 
         if (SUCCEEDED(rc))
@@ -1528,5 +1485,5 @@
     if (SUCCEEDED(rc))
     {
-        rc = registerFloppyImage (image);
+        rc = registerImage(image, DeviceType_Floppy);
 
         if (SUCCEEDED(rc))
@@ -1616,9 +1573,8 @@
     *aType = NULL;
 
-    AutoReadLock alock(this);
-
-    for (GuestOSTypeList::iterator it = m->llGuestOSTypes.begin();
-         it != m->llGuestOSTypes.end();
-         ++ it)
+    AutoReadLock alock(m->ollGuestOSTypes.getLockHandle());
+    for (GuestOSTypesOList::iterator it = m->ollGuestOSTypes.begin();
+         it != m->ollGuestOSTypes.end();
+         ++it)
     {
         const Bstr &typeId = (*it)->id();
@@ -1637,6 +1593,5 @@
 }
 
-STDMETHODIMP
-VirtualBox::CreateSharedFolder (IN_BSTR aName, IN_BSTR aHostPath, BOOL /* aWritable */)
+STDMETHODIMP VirtualBox::CreateSharedFolder(IN_BSTR aName, IN_BSTR aHostPath, BOOL /* aWritable */)
 {
     CheckComArgNotNull(aName);
@@ -1649,5 +1604,5 @@
 }
 
-STDMETHODIMP VirtualBox::RemoveSharedFolder (IN_BSTR aName)
+STDMETHODIMP VirtualBox::RemoveSharedFolder(IN_BSTR aName)
 {
     CheckComArgNotNull(aName);
@@ -2006,17 +1961,23 @@
 void VirtualBox::dumpAllBackRefs()
 {
-    for (MediaList::const_iterator mt = m->llHardDisks.begin();
-         mt != m->llHardDisks.end();
-         ++mt)
-    {
-        ComObjPtr<Medium> pMedium = *mt;
-        pMedium->dumpBackRefs();
-    }
-    for (MediaList::const_iterator mt = m->llDVDImages.begin();
-         mt != m->llDVDImages.end();
-         ++mt)
-    {
-        ComObjPtr<Medium> pMedium = *mt;
-        pMedium->dumpBackRefs();
+    {
+        AutoReadLock al(m->ollHardDisks.getLockHandle());
+        for (MediaList::const_iterator mt = m->ollHardDisks.begin();
+             mt != m->ollHardDisks.end();
+             ++mt)
+        {
+            ComObjPtr<Medium> pMedium = *mt;
+            pMedium->dumpBackRefs();
+        }
+    }
+    {
+        AutoReadLock al(m->ollDVDImages.getLockHandle());
+        for (MediaList::const_iterator mt = m->ollDVDImages.begin();
+             mt != m->ollDVDImages.end();
+             ++mt)
+        {
+            ComObjPtr<Medium> pMedium = *mt;
+            pMedium->dumpBackRefs();
+        }
     }
 }
@@ -2662,15 +2623,11 @@
 {
     ComObjPtr<GuestOSType> type;
-
     AutoCaller autoCaller(this);
     AssertComRCReturn(autoCaller.rc(), type);
 
-    AutoReadLock alock(this);
-
     /* unknown type must always be the first */
-    ComAssertRet (m->llGuestOSTypes.size() > 0, type);
-
-    type = m->llGuestOSTypes.front();
-    return type;
+    ComAssertRet(m->ollGuestOSTypes.size() > 0, type);
+
+    return m->ollGuestOSTypes.front();
 }
 
@@ -2703,6 +2660,6 @@
     AutoReadLock alock(this);
 
-    for (MachineList::iterator it = m->llMachines.begin();
-         it != m->llMachines.end();
+    for (MachinesOList::iterator it = m->ollMachines.begin();
+         it != m->ollMachines.end();
          ++it)
     {
@@ -2739,15 +2696,15 @@
                                 ComObjPtr<Machine> *aMachine /* = NULL */)
 {
+    HRESULT rc = VBOX_E_OBJECT_NOT_FOUND;
+
     AutoCaller autoCaller(this);
     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
 
-    bool found = false;
-
-    {
-        AutoReadLock alock(this);
-
-        for (MachineList::iterator it = m->llMachines.begin();
-             !found && it != m->llMachines.end();
-             ++ it)
+    {
+        AutoReadLock al(m->ollMachines.getLockHandle());
+
+        for (MachinesOList::iterator it = m->ollMachines.begin();
+             it != m->ollMachines.end();
+             ++it)
         {
             ComObjPtr<Machine> pMachine2 = *it;
@@ -2756,18 +2713,18 @@
             AssertComRC(machCaller.rc());
 
-            found = pMachine2->getId() == aId;
-            if (found && aMachine)
-                *aMachine = pMachine2;
-        }
-    }
-
-    HRESULT rc = found ? S_OK : VBOX_E_OBJECT_NOT_FOUND;
-
-    if (aSetError && !found)
-    {
-        setError (VBOX_E_OBJECT_NOT_FOUND,
-            tr ("Could not find a registered machine with UUID {%RTuuid}"),
-            aId.raw());
-    }
+            if (pMachine2->getId() == aId)
+            {
+                rc = S_OK;
+                if (aMachine)
+                    *aMachine = pMachine2;
+                break;
+            }
+        }
+    }
+
+    if (aSetError && FAILED(rc))
+        setError(VBOX_E_OBJECT_NOT_FOUND,
+                 tr("Could not find a registered machine with UUID {%RTuuid}"),
+                 aId.raw());
 
     return rc;
@@ -2796,10 +2753,12 @@
     AssertReturn(aId || aLocation, E_INVALIDARG);
 
-    AutoReadLock alock(this);
+    // we use the hard disks map, but it is protected by the
+    // hard disk _list_ lock handle
+    AutoReadLock alock(m->ollHardDisks.getLockHandle());
 
     /* first, look up by UUID in the map if UUID is provided */
     if (aId)
     {
-        HardDiskMap::const_iterator it = m->mapHardDisks.find (*aId);
+        HardDiskMap::const_iterator it = m->mapHardDisks.find(*aId);
         if (it != m->mapHardDisks.end())
         {
@@ -2887,10 +2846,10 @@
     }
 
-    AutoReadLock alock(this);
+    AutoReadLock alock(m->ollDVDImages.getLockHandle());
 
     bool found = false;
 
-    for (MediaList::const_iterator it = m->llDVDImages.begin();
-         it != m->llDVDImages.end();
+    for (MediaList::const_iterator it = m->ollDVDImages.begin();
+         it != m->ollDVDImages.end();
          ++ it)
     {
@@ -2963,10 +2922,10 @@
     }
 
-    AutoReadLock alock(this);
+    AutoReadLock alock(m->ollFloppyImages.getLockHandle());
 
     bool found = false;
 
-    for (MediaList::const_iterator it = m->llFloppyImages.begin();
-         it != m->llFloppyImages.end();
+    for (MediaList::const_iterator it = m->ollFloppyImages.begin();
+         it != m->ollFloppyImages.end();
          ++ it)
     {
@@ -3009,8 +2968,6 @@
                                     GuestOSType*& pGuestOSType)
 {
-    AutoReadLock alock(this);
-
     /* Look for a GuestOSType object */
-    AssertMsg(m->llGuestOSTypes.size() != 0,
+    AssertMsg(m->ollGuestOSTypes.size() != 0,
               ("Guest OS types array must be filled"));
 
@@ -3021,6 +2978,7 @@
     }
 
-    for (GuestOSTypeList::const_iterator it = m->llGuestOSTypes.begin();
-         it != m->llGuestOSTypes.end();
+    AutoReadLock alock(m->ollGuestOSTypes.getLockHandle());
+    for (GuestOSTypesOList::const_iterator it = m->ollGuestOSTypes.begin();
+         it != m->ollGuestOSTypes.end();
          ++it)
     {
@@ -3166,7 +3124,7 @@
  * @note Locks this object and media objects for reading.
  */
-HRESULT VirtualBox::checkMediaForConflicts2 (const Guid &aId,
-                                             const Utf8Str &aLocation,
-                                             Utf8Str &aConflict)
+HRESULT VirtualBox::checkMediaForConflicts2(const Guid &aId,
+                                            const Utf8Str &aLocation,
+                                            Utf8Str &aConflict)
 {
     aConflict.setNull();
@@ -3239,67 +3197,90 @@
     HRESULT rc = S_OK;
 
-    /* serialize file access (prevents concurrent reads and writes) */
-    AutoWriteLock alock(this);
-
     try
     {
         // machines
-        m->pMainConfigFile->llMachines.clear();
-        for (MachineList::iterator it = m->llMachines.begin();
-             it != m->llMachines.end();
-             ++it)
-        {
-            settings::MachineRegistryEntry mre;
-            rc = (*it)->saveRegistryEntry(mre);
-            m->pMainConfigFile->llMachines.push_back(mre);
+        settings::MachinesRegistry machinesTemp;
+        {
+            AutoReadLock al(m->ollMachines.getLockHandle());
+            for (MachinesOList::iterator it = m->ollMachines.begin();
+                 it != m->ollMachines.end();
+                 ++it)
+            {
+                settings::MachineRegistryEntry mre;
+                rc = (*it)->saveRegistryEntry(mre);
+                machinesTemp.push_back(mre);
+            }
         }
 
         // hard disks
-        m->pMainConfigFile->llHardDisks.clear();
-        for (MediaList::const_iterator it = m->llHardDisks.begin();
-             it != m->llHardDisks.end();
-             ++it)
-        {
-            settings::Medium med;
-            rc = (*it)->saveSettings(med);
-            m->pMainConfigFile->llHardDisks.push_back(med);
-            if (FAILED(rc)) throw rc;
+        settings::MediaList hardDisksTemp;
+        {
+            AutoReadLock al(m->ollHardDisks.getLockHandle());
+            for (MediaList::const_iterator it = m->ollHardDisks.begin();
+                 it != m->ollHardDisks.end();
+                 ++it)
+            {
+                settings::Medium med;
+                rc = (*it)->saveSettings(med);
+                if (FAILED(rc)) throw rc;
+                hardDisksTemp.push_back(med);
+            }
         }
 
         /* CD/DVD images */
-        m->pMainConfigFile->llDvdImages.clear();
-        for (MediaList::const_iterator it = m->llDVDImages.begin();
-             it != m->llDVDImages.end();
-             ++it)
-        {
-            settings::Medium med;
-            rc = (*it)->saveSettings(med);
-            if (FAILED(rc)) throw rc;
-            m->pMainConfigFile->llDvdImages.push_back(med);
+        settings::MediaList dvdsTemp;
+        {
+            AutoReadLock al(m->ollDVDImages.getLockHandle());
+            for (MediaList::const_iterator it = m->ollDVDImages.begin();
+                 it != m->ollDVDImages.end();
+                 ++it)
+            {
+                settings::Medium med;
+                rc = (*it)->saveSettings(med);
+                if (FAILED(rc)) throw rc;
+                dvdsTemp.push_back(med);
+            }
         }
 
         /* floppy images */
-        m->pMainConfigFile->llFloppyImages.clear();
-        for (MediaList::const_iterator it = m->llFloppyImages.begin();
-             it != m->llFloppyImages.end();
-             ++it)
-        {
-            settings::Medium med;
-            rc = (*it)->saveSettings(med);
-            if (FAILED(rc)) throw rc;
-            m->pMainConfigFile->llFloppyImages.push_back(med);
-        }
-
-        m->pMainConfigFile->llDhcpServers.clear();
-        for (DHCPServerList::const_iterator it =
-                m->llDHCPServers.begin();
-                it != m->llDHCPServers.end();
-                ++ it)
-        {
-            settings::DHCPServer d;
-            rc = (*it)->saveSettings(d);
-            if (FAILED(rc)) throw rc;
-            m->pMainConfigFile->llDhcpServers.push_back(d);
-        }
+        settings::MediaList floppiesTemp;
+        {
+            AutoReadLock al(m->ollFloppyImages.getLockHandle());
+            for (MediaList::const_iterator it = m->ollFloppyImages.begin();
+                 it != m->ollFloppyImages.end();
+                 ++it)
+            {
+                settings::Medium med;
+                rc = (*it)->saveSettings(med);
+                if (FAILED(rc)) throw rc;
+                floppiesTemp.push_back(med);
+            }
+        }
+
+        settings::DHCPServersList dhcpServersTemp;
+        {
+            AutoReadLock al(m->ollDHCPServers.getLockHandle());
+            for (DHCPServersOList::const_iterator it = m->ollDHCPServers.begin();
+                 it != m->ollDHCPServers.end();
+                 ++it)
+            {
+                settings::DHCPServer d;
+                rc = (*it)->saveSettings(d);
+                if (FAILED(rc)) throw rc;
+                dhcpServersTemp.push_back(d);
+            }
+        }
+
+        /* finally, lock VirtualBox object for writing */
+        AutoWriteLock alock(this);
+
+        /* now copy the temp data to the config file under the VirtualBox lock */
+        m->pMainConfigFile->llMachines = machinesTemp;
+        m->pMainConfigFile->llHardDisks = hardDisksTemp;
+        m->pMainConfigFile->llDvdImages = dvdsTemp;
+        m->pMainConfigFile->llFloppyImages = floppiesTemp;
+        m->pMainConfigFile->llDhcpServers = dhcpServersTemp;
+
+        // leave extra data alone, it's still in the config file
 
         /* host data (USB filters) */
@@ -3310,5 +3291,5 @@
         if (FAILED(rc)) throw rc;
 
-        // now write out the XML
+        // and write out the XML, still under the lock
         m->pMainConfigFile->write(m->strSettingsFilePath);
     }
@@ -3348,6 +3329,4 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoWriteLock alock(this);
-
     HRESULT rc = S_OK;
 
@@ -3373,5 +3352,7 @@
     if (autoCaller.state() != InInit)
     {
-        /* Machine::trySetRegistered() will commit and save machine settings */
+        // trySetRegistered needs VirtualBox object write lock;
+        // it will commit and save machine settings
+        AutoWriteLock alock(this);
         rc = aMachine->trySetRegistered(TRUE);
         if (FAILED(rc)) return rc;
@@ -3379,5 +3360,5 @@
 
     /* add to the collection of registered machines */
-    m->llMachines.push_back(aMachine);
+    m->ollMachines.addChild(aMachine);
 
     if (autoCaller.state() != InInit)
@@ -3410,40 +3391,48 @@
     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
 
-    AutoWriteLock alock(this);
-
-    AutoCaller hardDiskCaller (aHardDisk);
+    AutoCaller hardDiskCaller(aHardDisk);
     AssertComRCReturn(hardDiskCaller.rc(), hardDiskCaller.rc());
 
-    AutoReadLock hardDiskLock (aHardDisk);
-
-    Utf8Str strConflict;
-    HRESULT rc = checkMediaForConflicts2(aHardDisk->getId(),
-                                         aHardDisk->getLocationFull(),
-                                         strConflict);
-    if (FAILED(rc)) return rc;
-
-    if (strConflict.length())
-    {
-        return setError(E_INVALIDARG,
-                        tr("Cannot register the hard disk '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
-                        aHardDisk->getLocationFull().raw(),
-                        aHardDisk->getId().raw(),
-                        strConflict.raw(),
-                        m->strSettingsFilePath.raw());
-    }
-
-    if (aHardDisk->getParent().isNull())
-    {
-        /* base (root) hard disk */
-        m->llHardDisks.push_back (aHardDisk);
-    }
-
-    m->mapHardDisks.insert(HardDiskMap::value_type(aHardDisk->getId(),
-                                                   HardDiskMap::mapped_type(aHardDisk)));
+    Guid id;
+    Utf8Str strLocationFull;
+    ComObjPtr<Medium> pParent;
+    {
+        AutoReadLock hardDiskLock(aHardDisk);
+        id = aHardDisk->getId();
+        strLocationFull = aHardDisk->getLocationFull();
+        pParent = aHardDisk->getParent();
+    }
+
+    HRESULT rc;
+    {
+        // lock the hard disk lists (list + map) while checking for conflicts
+        AutoWriteLock al(m->ollHardDisks.getLockHandle());
+
+        Utf8Str strConflict;
+        rc = checkMediaForConflicts2(id,
+                                     strLocationFull,
+                                     strConflict);
+        if (FAILED(rc)) return rc;
+        if (strConflict.length())
+            return setError(E_INVALIDARG,
+                            tr("Cannot register the hard disk '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
+                            strLocationFull.raw(),
+                            id.raw(),
+                            strConflict.raw(),
+                            m->strSettingsFilePath.raw());
+
+        // store base (root) hard disks in the list
+        if (pParent.isNull())
+            m->ollHardDisks.getList().push_back(aHardDisk);
+                    // access the list directly because we already locked the list above
+
+        // store all hard disks (even differencing images) in the map
+        m->mapHardDisks[id] = aHardDisk;
+    }
 
     if (aSaveRegistry)
     {
         rc = saveSettings();
-        if (FAILED (rc))
+        if (FAILED(rc))
             unregisterHardDisk(aHardDisk, false /* aSaveRegistry */);
     }
@@ -3475,19 +3464,28 @@
     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
 
-    AutoWriteLock alock(this);
-
     AutoCaller hardDiskCaller (aHardDisk);
     AssertComRCReturn(hardDiskCaller.rc(), hardDiskCaller.rc());
 
-    AutoReadLock hardDiskLock (aHardDisk);
-
-    size_t cnt = m->mapHardDisks.erase(aHardDisk->getId());
-    Assert(cnt == 1);
-    NOREF(cnt);
-
-    if (aHardDisk->getParent().isNull())
-    {
-        /* base (root) hard disk */
-        m->llHardDisks.remove(aHardDisk);
+    Guid id;
+    ComObjPtr<Medium> pParent;
+    {
+        AutoReadLock hardDiskLock(aHardDisk);
+        id = aHardDisk->getId();
+        pParent = aHardDisk->getParent();
+    }
+
+    {
+        // lock the hard disk lists (list + map)
+        AutoWriteLock al(m->ollHardDisks.getLockHandle());
+
+        // remove base (root) hard disks from the list
+        if (pParent.isNull())
+            m->ollHardDisks.getList().remove(aHardDisk);
+                    // access the list directly because we already locked the list above
+
+        // remove all hard disks (even differencing images) from map
+        size_t cnt = m->mapHardDisks.erase(id);
+        Assert(cnt == 1);
+        NOREF(cnt);
     }
 
@@ -3497,5 +3495,5 @@
     {
         rc = saveSettings();
-        if (FAILED (rc))
+        if (FAILED(rc))
             registerHardDisk(aHardDisk, false /* aSaveRegistry */);
     }
@@ -3505,7 +3503,8 @@
 
 /**
- * Remembers the given image by storing it in the CD/DVD image registry.
- *
- * @param aImage        Image object to remember.
+ * Remembers the given image by storing it in the CD/DVD or floppy image registry.
+ *
+ * @param argImage      Image object to remember.
+ * @param argType       Either DeviceType_DVD or DeviceType_Floppy.
  * @param aSaveRegistry @c true to save the image registry to disk (default).
  *
@@ -3519,43 +3518,58 @@
  * @note Locks this object for writing and @a aImage for reading.
  */
-HRESULT VirtualBox::registerDVDImage (Medium *aImage,
-                                      bool aSaveRegistry /*= true*/)
-{
-    AssertReturn(aImage != NULL, E_INVALIDARG);
+HRESULT VirtualBox::registerImage(Medium *argImage,
+                                  DeviceType_T argType,
+                                  bool argSaveRegistry /*= true*/)
+{
+    AssertReturn(argImage != NULL, E_INVALIDARG);
 
     AutoCaller autoCaller(this);
     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
 
-    AutoWriteLock alock(this);
-
-    AutoCaller imageCaller (aImage);
+    AutoCaller imageCaller(argImage);
     AssertComRCReturn(imageCaller.rc(), imageCaller.rc());
 
-    AutoReadLock imageLock (aImage);
-
-    Utf8Str strConflict;
-    HRESULT rc = checkMediaForConflicts2(aImage->getId(),
-                                         aImage->getLocationFull(),
-                                         strConflict);
-    if (FAILED(rc)) return rc;
-
-    if (strConflict.length())
-    {
-        return setError(VBOX_E_INVALID_OBJECT_STATE,
-                        tr("Cannot register the CD/DVD image '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
-                        aImage->getLocationFull().raw(),
-                        aImage->getId().raw(),
-                        strConflict.raw(),
-                        m->strSettingsFilePath.raw());
-    }
-
-    /* add to the collection */
-    m->llDVDImages.push_back (aImage);
-
-    if (aSaveRegistry)
+    Guid id;
+    Utf8Str strLocationFull;
+    ComObjPtr<Medium> pParent;
+    {
+        AutoReadLock al(argImage);
+        id = argImage->getId();
+        strLocationFull = argImage->getLocationFull();
+        pParent = argImage->getParent();
+    }
+
+    // work on DVDs or floppies list?
+    ObjectsList<Medium> &oll = (argType == DeviceType_DVD) ? m->ollDVDImages : m->ollFloppyImages;
+
+    HRESULT rc;
+    {
+        // lock the images lists (list + map) while checking for conflicts
+        AutoWriteLock al(oll.getLockHandle());
+
+        Utf8Str strConflict;
+        rc = checkMediaForConflicts2(id,
+                                     strLocationFull,
+                                     strConflict);
+        if (FAILED(rc)) return rc;
+
+        if (strConflict.length())
+            return setError(VBOX_E_INVALID_OBJECT_STATE,
+                            tr("Cannot register the image '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
+                            strLocationFull.raw(),
+                            id.raw(),
+                            strConflict.raw(),
+                            m->strSettingsFilePath.raw());
+
+        // add to the collection
+        oll.getList().push_back(argImage);
+                // access the list directly because we already locked the list above
+    }
+
+    if (argSaveRegistry)
     {
         rc = saveSettings();
-        if (FAILED (rc))
-            unregisterDVDImage (aImage, false /* aSaveRegistry */);
+        if (FAILED(rc))
+            unregisterImage(argImage, argType, false /* aSaveRegistry */);
     }
 
@@ -3564,8 +3578,9 @@
 
 /**
- * Removes the given image from the CD/DVD image registry registry.
- *
- * @param aImage        Image object to remove.
- * @param aSaveRegistry @c true to save hard disk registry to disk (default).
+ * Removes the given image from the CD/DVD or floppy image registry.
+ *
+ * @param argImage        Image object to remove.
+ * @param argType         Either DeviceType_DVD or DeviceType_Floppy.
+ * @param argSaveRegistry @c true to save hard disk registry to disk (default).
  *
  * When @a aSaveRegistry is @c true, this operation may fail because of the
@@ -3578,168 +3593,39 @@
  * @note Locks this object for writing and @a aImage for reading.
  */
-HRESULT VirtualBox::unregisterDVDImage (Medium *aImage,
-                                        bool aSaveRegistry /*= true*/)
-{
-    AssertReturn(aImage != NULL, E_INVALIDARG);
+HRESULT VirtualBox::unregisterImage(Medium *argImage,
+                                    DeviceType_T argType,
+                                    bool argSaveRegistry /*= true*/)
+{
+    AssertReturn(argImage != NULL, E_INVALIDARG);
 
     AutoCaller autoCaller(this);
     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
 
-    AutoWriteLock alock(this);
-
-    AutoCaller imageCaller (aImage);
+    AutoCaller imageCaller(argImage);
     AssertComRCReturn(imageCaller.rc(), imageCaller.rc());
 
-    AutoReadLock imageLock (aImage);
-
-    m->llDVDImages.remove (aImage);
+    Guid id;
+    ComObjPtr<Medium> pParent;
+    {
+        AutoReadLock al(argImage);
+        id = argImage->getId();
+        pParent = argImage->getParent();
+    }
+
+    // work on DVDs or floppies list?
+    ObjectsList<Medium> &oll = (argType == DeviceType_DVD) ? m->ollDVDImages : m->ollFloppyImages;
+
+    oll.removeChild(argImage);
 
     HRESULT rc = S_OK;
 
-    if (aSaveRegistry)
+    if (argSaveRegistry)
     {
         rc = saveSettings();
-        if (FAILED (rc))
-            registerDVDImage (aImage, false /* aSaveRegistry */);
+        if (FAILED(rc))
+            registerImage(argImage, argType, false /* aSaveRegistry */);
     }
 
     return rc;
-}
-
-/**
- * Remembers the given image by storing it in the floppy image registry.
- *
- * @param aImage        Image object to remember.
- * @param aSaveRegistry @c true to save the image registry to disk (default).
- *
- * When @a aSaveRegistry is @c true, this operation may fail because of the
- * failed #saveSettings() method it calls. In this case, the image object
- * will not be remembered. It is therefore the responsibility of the caller to
- * call this method as the last step of some action that requires registration
- * in order to make sure that only fully functional image objects get
- * registered.
- *
- * @note Locks this object for writing and @a aImage for reading.
- */
-HRESULT VirtualBox::registerFloppyImage(Medium *aImage,
-                                        bool aSaveRegistry /*= true*/)
-{
-    AssertReturn(aImage != NULL, E_INVALIDARG);
-
-    AutoCaller autoCaller(this);
-    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
-
-    AutoWriteLock alock(this);
-
-    AutoCaller imageCaller (aImage);
-    AssertComRCReturn(imageCaller.rc(), imageCaller.rc());
-
-    AutoReadLock imageLock (aImage);
-
-    Utf8Str strConflict;
-    HRESULT rc = checkMediaForConflicts2(aImage->getId(),
-                                         aImage->getLocationFull(),
-                                         strConflict);
-    if (FAILED(rc)) return rc;
-
-    if (strConflict.length())
-    {
-        return setError(VBOX_E_INVALID_OBJECT_STATE,
-                        tr("Cannot register the floppy image '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
-                        aImage->getLocationFull().raw(),
-                        aImage->getId().raw(),
-                        strConflict.raw(),
-                        m->strSettingsFilePath.raw());
-    }
-
-    /* add to the collection */
-    m->llFloppyImages.push_back (aImage);
-
-    if (aSaveRegistry)
-    {
-        rc = saveSettings();
-        if (FAILED (rc))
-            unregisterFloppyImage(aImage, false /* aSaveRegistry */);
-    }
-
-    return rc;
-}
-
-/**
- * Removes the given image from the floppy image registry registry.
- *
- * @param aImage        Image object to remove.
- * @param aSaveRegistry @c true to save hard disk registry to disk (default).
- *
- * When @a aSaveRegistry is @c true, this operation may fail because of the
- * failed #saveSettings() method it calls. In this case, the image object
- * will NOT be removed from the registry when this method returns. It is
- * therefore the responsibility of the caller to call this method as the first
- * step of some action that requires unregistration, before calling uninit() on
- * @a aImage.
- *
- * @note Locks this object for writing and @a aImage for reading.
- */
-HRESULT VirtualBox::unregisterFloppyImage(Medium *aImage,
-                                          bool aSaveRegistry /*= true*/)
-{
-    AssertReturn(aImage != NULL, E_INVALIDARG);
-
-    AutoCaller autoCaller(this);
-    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
-
-    AutoWriteLock alock(this);
-
-    AutoCaller imageCaller (aImage);
-    AssertComRCReturn(imageCaller.rc(), imageCaller.rc());
-
-    AutoReadLock imageLock (aImage);
-
-    m->llFloppyImages.remove (aImage);
-
-    HRESULT rc = S_OK;
-
-    if (aSaveRegistry)
-    {
-        rc = saveSettings();
-        if (FAILED (rc))
-            registerFloppyImage (aImage, false /* aSaveRegistry */);
-    }
-
-    return rc;
-}
-
-/**
- * Attempts to cast from a raw interface pointer to an underlying object.
- * On success, @a aTo will contain the object reference. On failure, @a aTo will
- * be set to @c null and an extended error info will be returned.
- *
- * @param aFrom     Interface pointer to cast from.
- * @param aTo       Where to store a reference to the underlying object.
- *
- * @note Locks #childrenLock() for reading.
- */
-HRESULT VirtualBox::cast (IMedium *aFrom, ComObjPtr<Medium> &aTo)
-{
-    AssertReturn(aFrom != NULL, E_INVALIDARG);
-
-    AutoCaller autoCaller(this);
-    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
-
-    /* We need the children map lock here to keep the getDependentChild() result
-     * valid until we finish */
-    AutoReadLock chLock (childrenLock());
-
-    VirtualBoxBase *child = getDependentChild (aFrom);
-    if (!child)
-        return setError (E_FAIL, tr ("The given hard disk object is not created "
-                                     "within this VirtualBox instance"));
-
-    /* we can safely cast child to Medium * here because only Medium
-     * implementations of IMedium can be among our children */
-
-    aTo = static_cast<Medium*>(child);
-
-    return S_OK;
 }
 
@@ -3754,5 +3640,5 @@
  * @note Locks this object + DVD, Floppy and HardDisk children for writing.
  */
-HRESULT VirtualBox::updateSettings (const char *aOldPath, const char *aNewPath)
+HRESULT VirtualBox::updateSettings(const char *aOldPath, const char *aNewPath)
 {
     LogFlowThisFunc(("aOldPath={%s} aNewPath={%s}\n", aOldPath, aNewPath));
@@ -3764,28 +3650,14 @@
     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
 
-    AutoWriteLock alock(this);
-
-    /* check DVD paths */
-    for (MediaList::iterator it = m->llDVDImages.begin();
-         it != m->llDVDImages.end();
+    ObjectsList<Medium> ollAll;
+    ollAll.appendOtherList(m->ollDVDImages);
+    ollAll.appendOtherList(m->ollFloppyImages);
+    ollAll.appendOtherList(m->ollHardDisks);
+
+    for (MediaList::iterator it = ollAll.begin();
+         it != ollAll.end();
          ++ it)
     {
         (*it)->updatePath(aOldPath, aNewPath);
-    }
-
-    /* check Floppy paths */
-    for (MediaList::iterator it = m->llFloppyImages.begin();
-         it != m->llFloppyImages  .end();
-         ++ it)
-    {
-        (*it)->updatePath(aOldPath, aNewPath);
-    }
-
-    /* check HardDisk paths */
-    for (MediaList::const_iterator it = m->llHardDisks.begin();
-         it != m->llHardDisks.end();
-         ++ it)
-    {
-        (*it)->updatePaths(aOldPath, aNewPath);
     }
 
@@ -3899,18 +3771,5 @@
 RWLockHandle& VirtualBox::hardDiskTreeLockHandle()
 {
-    return m->mtxHardDiskTree;
-}
-
-/**
- * Reimplements VirtualBoxWithTypedChildren::childrenLock() to return a
- * dedicated lock instead of the main object lock. The dedicated lock for
- * child map operations frees callers of init() methods of these children
- * from acquiring a write parent (VirtualBox) lock (which would be mandatory
- * otherwise). Since VirtualBox has a lot of heterogenous children which
- * init() methods are called here and there, it definitely makes sense.
- */
-RWLockHandle* VirtualBox::childrenLock()
-{
-    return &m->mtxChildrenMap;
+    return m->ollHardDisks.getLockHandle();
 }
 
@@ -3924,6 +3783,9 @@
     LogFlowFuncEnter();
 
-    VirtualBox *that = (VirtualBox *) pvUser;
-    Assert (that);
+    VirtualBox *that = (VirtualBox*)pvUser;
+    Assert(that);
+
+    typedef std::vector< ComObjPtr<Machine> > MachineVector;
+    typedef std::vector< ComObjPtr<SessionMachine> > SessionMachineVector;
 
     SessionMachineVector machines;
@@ -3978,5 +3840,5 @@
             {
                 /* machine mutex is released */
-                (machines [rc - WAIT_OBJECT_0 - 1])->checkForDeath();
+                (machines[rc - WAIT_OBJECT_0 - 1])->checkForDeath();
                 update = true;
             }
@@ -3984,5 +3846,5 @@
             {
                 /* machine mutex is abandoned due to client process termination */
-                (machines [rc - WAIT_ABANDONED_0 - 1])->checkForDeath();
+                (machines[rc - WAIT_ABANDONED_0 - 1])->checkForDeath();
                 update = true;
             }
@@ -3998,8 +3860,9 @@
             {
                 /* close old process handles */
-                for (size_t i = 1 + cnt; i < 1 + cnt + cntSpawned; ++ i)
-                    CloseHandle (handles [i]);
-
-                AutoReadLock thatLock (that);
+                for (size_t i = 1 + cnt; i < 1 + cnt + cntSpawned; ++i)
+                    CloseHandle(handles[i]);
+
+                // lock the machines list for reading
+                AutoReadLock thatLock(that->m->ollMachines.getLockHandle());
 
                 /* obtain a new set of opened machines */
@@ -4007,6 +3870,7 @@
                 machines.clear();
 
-                for (MachineList::iterator it = that->m->llMachines.begin();
-                     it != that->m->llMachines.end(); ++ it)
+                for (MachinesOList::iterator it = that->m->ollMachines.begin();
+                     it != that->m->ollMachines.end();
+                     ++it)
                 {
                     /// @todo handle situations with more than 64 objects
@@ -4016,9 +3880,9 @@
                     ComObjPtr<SessionMachine> sm;
                     HANDLE ipcSem;
-                    if ((*it)->isSessionOpenOrClosing (sm, NULL, &ipcSem))
+                    if ((*it)->isSessionOpenOrClosing(sm, NULL, &ipcSem))
                     {
-                        machines.push_back (sm);
-                        handles [1 + cnt] = ipcSem;
-                        ++ cnt;
+                        machines.push_back(sm);
+                        handles[1 + cnt] = ipcSem;
+                        ++cnt;
                     }
                 }
@@ -4030,6 +3894,7 @@
                 spawnedMachines.clear();
 
-                for (MachineList::iterator it = that->m->llMachines.begin();
-                     it != that->m->llMachines.end(); ++ it)
+                for (MachinesOList::iterator it = that->m->ollMachines.begin();
+                     it != that->m->ollMachines.end();
+                     ++it)
                 {
                     /// @todo handle situations with more than 64 objects
@@ -4038,14 +3903,14 @@
 
                     RTPROCESS pid;
-                    if ((*it)->isSessionSpawning (&pid))
+                    if ((*it)->isSessionSpawning(&pid))
                     {
-                        HANDLE ph = OpenProcess (SYNCHRONIZE, FALSE, pid);
+                        HANDLE ph = OpenProcess(SYNCHRONIZE, FALSE, pid);
                         AssertMsg (ph != NULL, ("OpenProcess (pid=%d) failed with %d\n",
                                                 pid, GetLastError()));
                         if (rc == 0)
                         {
-                            spawnedMachines.push_back (*it);
-                            handles [1 + cnt + cntSpawned] = ph;
-                            ++ cntSpawned;
+                            spawnedMachines.push_back(*it);
+                            handles[1 + cnt + cntSpawned] = ph;
+                            ++cntSpawned;
                         }
                     }
@@ -4053,4 +3918,6 @@
 
                 LogFlowFunc (("UPDATE: spawned session count = %d\n", cntSpawned));
+
+                // machines lock unwinds here
             }
         }
@@ -4090,5 +3957,5 @@
             autoCaller.release();
 
-            int vrc = RTSemEventWait (that->m->updateReq, 500);
+            int vrc = RTSemEventWait(that->m->updateReq, 500);
 
             /* Restore the caller before using VirtualBox. If it fails, this
@@ -4129,10 +3996,10 @@
 #ifdef DEBUG
                             {
-                                AutoReadLock machineLock (machines [semId]);
+                                AutoReadLock machineLock(machines[semId]);
                                 LogFlowFunc (("released mutex: machine='%ls'\n",
-                                              machines [semId]->name().raw()));
+                                              machines[semId]->name().raw()));
                             }
 #endif
-                            machines [semId]->checkForDeath();
+                            machines[semId]->checkForDeath();
                         }
                         update = true;
@@ -4159,10 +4026,10 @@
 #ifdef DEBUG
                                     {
-                                        AutoReadLock machineLock (machines [semId]);
-                                        LogFlowFunc (("mutex owner dead: machine='%ls'\n",
-                                                      machines [i]->name().raw()));
+                                        AutoReadLock machineLock(machines[semId]);
+                                        LogFlowFunc(("mutex owner dead: machine='%ls'\n",
+                                                     machines[i]->name().raw()));
                                     }
 #endif
-                                    machines [i]->checkForDeath();
+                                    machines[i]->checkForDeath();
                                 }
                             }
@@ -4198,5 +4065,5 @@
                     machines.clear();
 
-                    for (MachineList::iterator it = that->m->llMachines.begin();
+                    for (MachinesOList::iterator it = that->m->llMachines.begin();
                          it != that->m->llMachines.end(); ++ it)
                     {
@@ -4211,6 +4078,6 @@
                         {
                             machines.push_back (sm);
-                            handles [cnt].hsemCur = (HSEM) ipcSem;
-                            handles [cnt].ulUser = cnt;
+                            handles[cnt].hsemCur = (HSEM) ipcSem;
+                            handles[cnt].ulUser = cnt;
                             ++ cnt;
                         }
@@ -4236,5 +4103,5 @@
                     spawnedMachines.clear();
 
-                    for (MachineList::iterator it = that->m->llMachines.begin();
+                    for (MachinesOList::iterator it = that->m->llMachines.begin();
                          it != that->m->llMachines.end(); ++ it)
                     {
@@ -4290,5 +4157,6 @@
                 /* RT_SUCCESS(rc) means an update event is signaled */
 
-                AutoReadLock thatLock (that);
+                // lock the machines list for reading
+                AutoReadLock thatLock(that->m->ollMachines.getLockHandle());
 
                 if (RT_SUCCESS(rc) || update)
@@ -4297,14 +4165,15 @@
                     machines.clear();
 
-                    for (MachineList::iterator it = that->m->llMachines.begin();
-                         it != that->m->llMachines.end(); ++ it)
+                    for (MachinesOList::iterator it = that->m->ollMachines.begin();
+                         it != that->m->ollMachines.end();
+                         ++it)
                     {
                         ComObjPtr<SessionMachine> sm;
-                        if ((*it)->isSessionOpenOrClosing (sm))
-                            machines.push_back (sm);
+                        if ((*it)->isSessionOpenOrClosing(sm))
+                            machines.push_back(sm);
                     }
 
                     cnt = machines.size();
-                    LogFlowFunc (("UPDATE: direct session count = %d\n", cnt));
+                    LogFlowFunc(("UPDATE: direct session count = %d\n", cnt));
                 }
 
@@ -4314,14 +4183,17 @@
                     spawnedMachines.clear();
 
-                    for (MachineList::iterator it = that->m->llMachines.begin();
-                         it != that->m->llMachines.end(); ++ it)
+                    for (MachinesOList::iterator it = that->m->ollMachines.begin();
+                         it != that->m->ollMachines.end();
+                         ++it)
                     {
                         if ((*it)->isSessionSpawning())
-                            spawnedMachines.push_back (*it);
+                            spawnedMachines.push_back(*it);
                     }
 
                     cntSpawned = spawnedMachines.size();
-                    LogFlowFunc (("UPDATE: spawned session count = %d\n", cntSpawned));
+                    LogFlowFunc(("UPDATE: spawned session count = %d\n", cntSpawned));
                 }
+
+                // machines lock unwinds here
             }
 
@@ -4490,10 +4362,5 @@
 }
 
-//STDMETHODIMP VirtualBox::FindDHCPServerForInterface (IHostNetworkInterface * aIinterface, IDHCPServer ** aServer)
-//{
-//    return E_NOTIMPL;
-//}
-
-STDMETHODIMP VirtualBox::FindDHCPServerByNetworkName (IN_BSTR aName, IDHCPServer ** aServer)
+STDMETHODIMP VirtualBox::FindDHCPServerByNetworkName(IN_BSTR aName, IDHCPServer ** aServer)
 {
     CheckComArgNotNull(aName);
@@ -4502,6 +4369,4 @@
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    AutoWriteLock alock(this);
 
     HRESULT rc;
@@ -4509,13 +4374,14 @@
     ComPtr<DHCPServer> found;
 
-    for (DHCPServerList::const_iterator it =
-            m->llDHCPServers.begin();
-         it != m->llDHCPServers.end();
-         ++ it)
-    {
-        rc = (*it)->COMGETTER(NetworkName) (bstr.asOutParam());
+    AutoReadLock alock(m->ollDHCPServers.getLockHandle());
+
+    for (DHCPServersOList::const_iterator it = m->ollDHCPServers.begin();
+         it != m->ollDHCPServers.end();
+         ++it)
+    {
+        rc = (*it)->COMGETTER(NetworkName)(bstr.asOutParam());
         if (FAILED(rc)) throw rc;
 
-        if(bstr == aName)
+        if (bstr == aName)
         {
             found = *it;
@@ -4558,5 +4424,5 @@
  */
 HRESULT VirtualBox::registerDHCPServer(DHCPServer *aDHCPServer,
-                                     bool aSaveRegistry /*= true*/)
+                                       bool aSaveRegistry /*= true*/)
 {
     AssertReturn(aDHCPServer != NULL, E_INVALIDARG);
@@ -4565,25 +4431,22 @@
     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
 
-    AutoWriteLock alock(this);
-
-    AutoCaller dhcpServerCaller (aDHCPServer);
+    AutoCaller dhcpServerCaller(aDHCPServer);
     AssertComRCReturn(dhcpServerCaller.rc(), dhcpServerCaller.rc());
-
-    AutoReadLock dhcpServerLock (aDHCPServer);
 
     Bstr name;
     HRESULT rc;
-    rc = aDHCPServer->COMGETTER(NetworkName) (name.asOutParam());
+    rc = aDHCPServer->COMGETTER(NetworkName)(name.asOutParam());
     if (FAILED(rc)) return rc;
 
     ComPtr<IDHCPServer> existing;
     rc = FindDHCPServerByNetworkName(name.mutableRaw(), existing.asOutParam());
-    if(SUCCEEDED(rc))
+    if (SUCCEEDED(rc))
     {
         return E_INVALIDARG;
     }
+
     rc = S_OK;
 
-    m->llDHCPServers.push_back (aDHCPServer);
+    m->ollDHCPServers.addChild(aDHCPServer);
 
     if (aSaveRegistry)
@@ -4625,7 +4488,5 @@
     AssertComRCReturn(dhcpServerCaller.rc(), dhcpServerCaller.rc());
 
-    AutoReadLock dhcpServerLock (aDHCPServer);
-
-    m->llDHCPServers.remove (aDHCPServer);
+    m->ollDHCPServers.removeChild(aDHCPServer);
 
     HRESULT rc = S_OK;
Index: trunk/src/VBox/Main/include/SharedFolderImpl.h
===================================================================
--- trunk/src/VBox/Main/include/SharedFolderImpl.h	(revision 25183)
+++ trunk/src/VBox/Main/include/SharedFolderImpl.h	(revision 25184)
@@ -31,5 +31,5 @@
 
 class ATL_NO_VTABLE SharedFolder :
-    public VirtualBoxBase,
+    public VirtualBoxBaseWithChildrenNEXT,
     public VirtualBoxSupportErrorInfoImpl<SharedFolder, ISharedFolder>,
     public VirtualBoxSupportTranslation<SharedFolder>,
@@ -94,10 +94,10 @@
 protected:
 
-    HRESULT protectedInit (VirtualBoxBaseWithChildrenNEXT *aParent,
-                           CBSTR aName, CBSTR aHostPath, BOOL aWritable);
+    HRESULT protectedInit(VirtualBoxBase *aParent,
+                          CBSTR aName, CBSTR aHostPath, BOOL aWritable);
 
 private:
 
-    VirtualBoxBaseWithChildrenNEXT *const mParent;
+    VirtualBoxBase *const mParent;
 
     /* weak parents (only one of them is not null) */
Index: trunk/src/VBox/Main/include/StorageControllerImpl.h
===================================================================
--- trunk/src/VBox/Main/include/StorageControllerImpl.h	(revision 25183)
+++ trunk/src/VBox/Main/include/StorageControllerImpl.h	(revision 25184)
@@ -32,5 +32,5 @@
 
 class ATL_NO_VTABLE StorageController :
-    public VirtualBoxBaseWithChildrenNEXT,
+    public VirtualBoxBase,
     public VirtualBoxSupportErrorInfoImpl<StorageController, IStorageController>,
     public VirtualBoxSupportTranslation<StorageController>,
Index: trunk/src/VBox/Main/include/VirtualBoxImpl.h
===================================================================
--- trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 25183)
+++ trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 25184)
@@ -60,5 +60,5 @@
 
 class ATL_NO_VTABLE VirtualBox :
-    public VirtualBoxBaseWithChildrenNEXT,
+    public VirtualBoxBase,
     public VirtualBoxSupportErrorInfoImpl<VirtualBox, IVirtualBox>,
     public VirtualBoxSupportTranslation<VirtualBox>,
@@ -257,11 +257,6 @@
     HRESULT unregisterHardDisk(Medium *aHardDisk, bool aSaveRegistry = true);
 
-    HRESULT registerDVDImage(Medium *aImage, bool aSaveRegistry = true);
-    HRESULT unregisterDVDImage(Medium *aImage, bool aSaveRegistry = true);
-
-    HRESULT registerFloppyImage (Medium *aImage, bool aSaveRegistry = true);
-    HRESULT unregisterFloppyImage (Medium *aImage, bool aSaveRegistry = true);
-
-    HRESULT cast (IMedium *aFrom, ComObjPtr<Medium> &aTo);
+    HRESULT registerImage(Medium *aImage, DeviceType_T argType, bool aSaveRegistry = true);
+    HRESULT unregisterImage(Medium *aImage, DeviceType_T argType, bool aSaveRegistry = true);
 
     HRESULT saveSettings();
@@ -275,5 +270,4 @@
 
     RWLockHandle& hardDiskTreeLockHandle();
-    RWLockHandle* childrenLock();
 
     /* for VirtualBoxSupportErrorInfoImpl */
Index: trunk/src/VBox/Main/include/objectslist.h
===================================================================
--- trunk/src/VBox/Main/include/objectslist.h	(revision 25184)
+++ trunk/src/VBox/Main/include/objectslist.h	(revision 25184)
@@ -0,0 +1,188 @@
+/** @file
+ *
+ * List of COM objects
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef ____H_OBJECTSLIST
+#define ____H_OBJECTSLIST
+
+#include <list>
+#include <VBox/com/ptr.h>
+
+/**
+ * Implements a "flat" objects list with a lock. Since each such list
+ * has its own lock it is not a good idea to implement trees with this.
+ *
+ * ObjectList<T> is designed to behave as if it were a std::list of
+ * COM pointers of class T; in other words,
+ * ObjectList<Medium> behaves like std::list< ComObjPtr<Medium> > but
+ * it's less typing. Iterators, front(), size(), begin() and end()
+ * are implemented.
+ *
+ * In addition it automatically includes an RWLockHandle which can be
+ * accessed with getLockHandle().
+ *
+ * If you need the raw std::list for some reason you can access it with
+ * getList().
+ *
+ * The destructor automatically calls uninit() on every contained
+ * COM object. If this is not desired, clear the member list before
+ * deleting the list object.
+ */
+template<typename T>
+class ObjectsList
+{
+public:
+    typedef ComObjPtr<T, ComStrongRef> MyType;
+    typedef std::list<MyType> MyList;
+
+    typedef typename MyList::iterator iterator;
+    typedef typename MyList::const_iterator const_iterator;
+        // typename is necessary to de-ambiguate "::iterator" in templates; see
+        // the "this might hurt your head" part in
+        // http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18
+
+    ObjectsList()
+    { }
+
+    ~ObjectsList()
+    {
+        uninitAll();
+    }
+
+    /**
+     * Returns the lock handle which protects this list, for use with
+     * AutoReadLock or AutoWriteLock.
+     */
+    RWLockHandle& getLockHandle()
+    {
+        return m_lock;
+    }
+
+    /**
+     * Calls m_ll.push_back(p) with locking.
+     * @param p
+     */
+    void addChild(MyType p)
+    {
+        AutoWriteLock al(m_lock);
+        m_ll.push_back(p);
+    }
+
+    /**
+     * Calls m_ll.remove(p) with locking. Does NOT call uninit()
+     * on the contained object.
+     * @param p
+     */
+    void removeChild(MyType p)
+    {
+        AutoWriteLock al(m_lock);
+        m_ll.remove(p);
+    }
+
+    /**
+     * Appends all objects from another list to the member list.
+     * Locks the other list for reading but does not lock "this"
+     * (because it might be on the caller's stack and needs no
+     * locking).
+     * @param ll
+     */
+    void appendOtherList(ObjectsList<T> &ll)
+    {
+        AutoReadLock alr(ll.getLockHandle());
+        for (const_iterator it = ll.begin();
+             it != ll.end();
+             ++it)
+        {
+            m_ll.push_back(*it);
+        }
+    }
+
+    /**
+     * Returns the no. of objects on the list (std::list compatibility)
+     * with locking.
+     */
+    size_t size()
+    {
+        AutoReadLock al(m_lock);
+        return m_ll.size();
+    }
+
+    /**
+     * Returns the first object on the list (std::list compatibility)
+     * with locking.
+     */
+    MyType front()
+    {
+        AutoReadLock al(m_lock);
+        return m_ll.front();
+    }
+
+    /**
+     * Returns a raw pointer to the member list of objects.
+     * Does not lock!
+     * @return
+     */
+    MyList& getList()
+    {
+        return m_ll;
+    }
+
+    /**
+     * Returns the begin iterator from the list (std::list compatibility).
+     * Does not lock!
+     * @return
+     */
+    iterator begin()
+    {
+        return m_ll.begin();
+    }
+
+    /**
+     * Returns the end iterator from the list (std::list compatibility).
+     * Does not lock!
+     */
+    iterator end()
+    {
+        return m_ll.end();
+    }
+
+    /**
+     * Calls uninit() on every COM object on the list and then
+     * clears the list, with locking.
+     */
+    void uninitAll()
+    {
+        AutoWriteLock al(m_lock);
+        for (iterator it = m_ll.begin();
+             it != m_ll.end();
+             ++it)
+        {
+            MyType &q = *it;
+            q->uninit();
+        }
+        m_ll.clear();
+    }
+
+private:
+    MyList          m_ll;
+    RWLockHandle    m_lock;
+};
+
+#endif
