Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 33631)
@@ -379,4 +379,5 @@
 	src/extensions/QISplitter.cpp \
 	src/selector/UIVMDesktop.cpp \
+	src/settings/UISettingsDialogSpecific.cpp \
 	src/settings/vm/VBoxVMSettingsPortForwardingDlg.cpp \
 	src/runtime/UIActionsPool.cpp \
@@ -451,4 +452,5 @@
 	src/settings/UISettingsDialog.cpp \
 	src/settings/UISettingsDialogSpecific.cpp \
+	src/settings/UISettingsPage.cpp \
 	src/settings/VBoxSettingsSelector.cpp \
 	src/settings/global/VBoxGLSettingsGeneral.cpp \
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 33631)
@@ -2813,4 +2813,9 @@
     mUSBDeviceStates [KUSBDeviceState_Captured] =
         tr ("Captured", "USBDeviceState");
+
+    mChipsetTypes [KChipsetType_PIIX3] =
+        tr ("PIIX3", "ChipsetType");
+    mChipsetTypes [KChipsetType_ICH9] =
+        tr ("ICH9", "ChipsetType");
 
     mUserDefinedPortName = tr ("User-defined", "serial port");
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h	(revision 33631)
@@ -490,4 +490,19 @@
     }
 
+    QString toString (KChipsetType t) const
+    {
+        AssertMsg (!mChipsetTypes.value (t).isNull(), ("No text for %d", t));
+        return mChipsetTypes.value (t);
+    }
+
+    KChipsetType toChipsetType (const QString &s) const
+    {
+        QULongStringHash::const_iterator it =
+            qFind (mChipsetTypes.begin(), mChipsetTypes.end(), s);
+        AssertMsg (it != mChipsetTypes.end(), ("No value for {%s}",
+                                               s.toLatin1().constData()));
+        return KChipsetType (it.key());
+    }
+
     QStringList COMPortNames() const;
     QString toCOMPortName (ulong aIRQ, ulong aIOBase) const;
@@ -815,4 +830,5 @@
     QULongStringHash mStorageControllerTypes;
     QULongStringHash mUSBDeviceStates;
+    QULongStringHash mChipsetTypes;
 
     QString mUserDefinedPortName;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp	(revision 33631)
@@ -115,5 +115,5 @@
         m_pSettings->setOrderAfter(this);
         VBoxGlobal::setLayoutMargin(m_pSettings->layout(), 0);
-        m_pSettings->getFrom(m_session.GetMachine());
+        m_pSettings->loadDirectlyFrom(m_session.GetMachine());
         pMainLayout->addWidget(m_pSettings);
 
@@ -140,5 +140,5 @@
     virtual void accept()
     {
-        m_pSettings->putBackTo();
+        m_pSettings->saveDirectlyTo(m_session.GetMachine());
         CMachine machine = m_session.GetMachine();
         machine.SaveSettings();
@@ -160,5 +160,5 @@
 private:
 
-    UISettingsPage *m_pSettings;
+    VBoxVMSettingsNetworkPage *m_pSettings;
     CSession &m_session;
 };
@@ -186,8 +186,7 @@
 
         /* Setup settings layout */
-        m_pSettings = new VBoxVMSettingsSF(MachineType | ConsoleType, this);
+        m_pSettings = new VBoxVMSettingsSF;
         VBoxGlobal::setLayoutMargin(m_pSettings->layout(), 0);
-        m_pSettings->getFromConsole(m_session.GetConsole());
-        m_pSettings->getFromMachine(m_session.GetMachine());
+        m_pSettings->loadDirectlyFrom(m_session.GetConsole());
         pMainLayout->addWidget(m_pSettings);
 
@@ -214,6 +213,5 @@
     virtual void accept()
     {
-        m_pSettings->putBackToConsole();
-        m_pSettings->putBackToMachine();
+        m_pSettings->saveDirectlyTo(m_session.GetConsole());
         CMachine machine = m_session.GetMachine();
         machine.SaveSettings();
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.cpp	(revision 33631)
@@ -161,4 +161,40 @@
 }
 
+void UISettingsDialog::sltCategoryChanged(int cId)
+{
+    QWidget *pRootPage = m_pSelector->rootPage(cId);
+#ifdef Q_WS_MAC
+    QSize cs = size();
+    /* First make all fully resizeable: */
+    setMinimumSize(QSize(minimumWidth(), 0));
+    setMaximumSize(QSize(minimumWidth(), QWIDGETSIZE_MAX));
+    for (int i = 0; i < m_pStack->count(); ++i)
+        m_pStack->widget(i)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
+    int a = m_pStack->indexOf(pRootPage);
+    if (a < m_sizeList.count())
+    {
+        QSize ss = m_sizeList.at(a);
+        m_pStack->widget(a)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+        /* Switch to the new page first if we are shrinking: */
+        if (cs.height() > ss.height())
+            m_pStack->setCurrentIndex(m_pStack->indexOf(pRootPage));
+        /* Do the animation: */
+        ::darwinWindowAnimateResize(this, QRect (x(), y(), ss.width(), ss.height()));
+        /* Switch to the new page last if we are zooming: */
+        if (cs.height() <= ss.height())
+            m_pStack->setCurrentIndex(m_pStack->indexOf(pRootPage));
+        /* Make the widget fixed size: */
+        setFixedSize(ss);
+    }
+    ::darwinSetShowsResizeIndicator(this, false);
+#else
+    m_pLbTitle->setText(m_pSelector->itemText(cId));
+    m_pStack->setCurrentIndex(m_pStack->indexOf(pRootPage));
+#endif
+#ifdef VBOX_GUI_WITH_TOOLBAR_SETTINGS
+    setWindowTitle(title());
+#endif /* VBOX_GUI_WITH_TOOLBAR_SETTINGS */
+}
+
 void UISettingsDialog::retranslateUi()
 {
@@ -371,40 +407,4 @@
 }
 
-void UISettingsDialog::sltCategoryChanged(int cId)
-{
-    QWidget *pRootPage = m_pSelector->rootPage(cId);
-#ifdef Q_WS_MAC
-    QSize cs = size();
-    /* First make all fully resizeable: */
-    setMinimumSize(QSize(minimumWidth(), 0));
-    setMaximumSize(QSize(minimumWidth(), QWIDGETSIZE_MAX));
-    for (int i = 0; i < m_pStack->count(); ++i)
-        m_pStack->widget(i)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
-    int a = m_pStack->indexOf(pRootPage);
-    if (a < m_sizeList.count())
-    {
-        QSize ss = m_sizeList.at(a);
-        m_pStack->widget(a)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
-        /* Switch to the new page first if we are shrinking: */
-        if (cs.height() > ss.height())
-            m_pStack->setCurrentIndex(m_pStack->indexOf(pRootPage));
-        /* Do the animation: */
-        ::darwinWindowAnimateResize(this, QRect (x(), y(), ss.width(), ss.height()));
-        /* Switch to the new page last if we are zooming: */
-        if (cs.height() <= ss.height())
-            m_pStack->setCurrentIndex(m_pStack->indexOf(pRootPage));
-        /* Make the widget fixed size: */
-        setFixedSize(ss);
-    }
-    ::darwinSetShowsResizeIndicator(this, false);
-#else
-    m_pLbTitle->setText(m_pSelector->itemText(cId));
-    m_pStack->setCurrentIndex(m_pStack->indexOf(pRootPage));
-#endif
-#ifdef VBOX_GUI_WITH_TOOLBAR_SETTINGS
-    setWindowTitle(title());
-#endif /* VBOX_GUI_WITH_TOOLBAR_SETTINGS */
-}
-
 bool UISettingsDialog::eventFilter(QObject *pObject, QEvent *pEvent)
 {
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialog.h	(revision 33631)
@@ -53,4 +53,7 @@
     virtual void sltRevalidate(QIWidgetValidator *pValidator);
 
+    /* Category-change slot: */
+    virtual void sltCategoryChanged(int cId);
+
 protected:
 
@@ -88,7 +91,4 @@
     void sltUpdateWhatsThis(bool fGotFocus = false);
 
-    /* Category-change slot: */
-    void sltCategoryChanged(int cId);
-
 private:
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp	(revision 33631)
@@ -20,4 +20,6 @@
 /* Global includes */
 #include <QStackedWidget>
+#include <QThread>
+#include <QTimer>
 
 /* Local includes */
@@ -49,4 +51,230 @@
 #endif /* Global USB filters are DISABLED now: */
 
+/* Settings page list: */
+typedef QList<UISettingsPage*> UISettingsPageList;
+typedef QMap<int, UISettingsPage*> UISettingsPageMap;
+
+/* Serializer direction: */
+enum UISettingsSerializeDirection
+{
+    UISettingsSerializeDirection_Load,
+    UISettingsSerializeDirection_Save
+};
+
+/* QThread reimplementation for loading/saving settings in async mode: */
+class UISettingsSerializer : public QThread
+{
+    Q_OBJECT;
+
+public:
+
+    /* Settings serializer instance: */
+    static UISettingsSerializer* instance() { return m_pInstance; }
+
+    /* Settings serializer constructor: */
+    UISettingsSerializer(QObject *pParent, const QVariant &data, UISettingsSerializeDirection direction)
+        : QThread(pParent)
+        , m_direction(direction)
+        , m_data(data)
+        , m_iPageIdWeAreWaitingFor(-1)
+        , m_iIdOfHighPriorityPage(-1)
+    {
+        /* Connecting thread signals: */
+        connect(this, SIGNAL(sigNotifyAboutPageProcessed(int)), this, SLOT(sltHandleProcessedPage(int)), Qt::QueuedConnection);
+        connect(this, SIGNAL(sigNotifyAboutPagesProcessed()), this, SLOT(sltHandleProcessedPages()), Qt::QueuedConnection);
+        connect(this, SIGNAL(finished()), this, SLOT(sltDestroySerializer()), Qt::QueuedConnection);
+
+        /* Set instance: */
+        m_pInstance = this;
+    }
+
+    /* Settings serializer destructor: */
+    ~UISettingsSerializer()
+    {
+        /* Reset instance: */
+        m_pInstance = 0;
+
+        /* If serializer is being destructed by it's parent,
+         * thread could still be running, we have to wait
+         * for it to be finished! */
+        if (isRunning())
+            wait();
+
+        /* If serializer still having event loop running,
+         * we should quit it now: */
+        if (m_eventLoop.isRunning())
+        {
+            m_eventLoop.processEvents();
+            m_eventLoop.quit();
+        }
+    }
+
+    /* Set pages list: */
+    void setPageList(const UISettingsPageList &pageList)
+    {
+        for (int iPageIndex = 0; iPageIndex < pageList.size(); ++iPageIndex)
+        {
+            UISettingsPage *pPage = pageList[iPageIndex];
+            m_pages.insert(pPage->id(), pPage);
+        }
+    }
+
+    /* Blocks calling thread until requested page will be processed: */
+    void waitForPageToBeProcessed(int iPageId)
+    {
+        if (!isRunning())
+            return;
+        m_iPageIdWeAreWaitingFor = iPageId;
+        m_eventLoop.exec();
+    }
+
+    /* Blocks calling thread until all pages will be processed: */
+    void waitForPagesToBeProcessed()
+    {
+        if (!isRunning())
+            return;
+        m_iPageIdWeAreWaitingFor = -1;
+        m_eventLoop.exec();
+    }
+
+    /* Raise priority of page: */
+    void raisePriorityOfPage(int iPageId)
+    {
+        /* If that page is not present or was processed already: */
+        if (!m_pages.contains(iPageId) || m_pages[iPageId]->processed())
+        {
+            /* We just ignoring that request: */
+            return;
+        }
+        else
+        {
+            /* Else remember which page we should be processed next: */
+            m_iIdOfHighPriorityPage = iPageId;
+        }
+    }
+
+    /* Return current m_data content: */
+    QVariant& data() { return m_data; }
+
+signals:
+
+    /* Signal to notify main GUI thread about some page was processed: */
+    void sigNotifyAboutPageProcessed(int iPageId);
+
+    /* Signal to notify main GUI thread about all pages were processed: */
+    void sigNotifyAboutPagesProcessed();
+
+public slots:
+
+    void start(Priority priority = InheritPriority)
+    {
+        /* If serializer saves settings: */
+        if (m_direction == UISettingsSerializeDirection_Save)
+        {
+            /* We should update internal page cache first: */
+            for (int iPageIndex = 0; iPageIndex < m_pages.values().size(); ++iPageIndex)
+                m_pages.values()[iPageIndex]->putToCache();
+        }
+        /* Start async thread: */
+        QThread::start(priority);
+    }
+
+protected slots:
+
+    /* Slot to handle the fact of some page was processed: */
+    void sltHandleProcessedPage(int iPageId)
+    {
+        /* If serializer loads settings: */
+        if (m_direction == UISettingsSerializeDirection_Load)
+        {
+            /* If such page present we should fetch internal page cache: */
+            if (m_pages.contains(iPageId))
+                m_pages[iPageId]->getFromCache();
+        }
+        /* If thats the page we are waiting for, unlock the loop,
+         * after all the events of the page which is currently fetching
+         * from cache will be processed: */
+        if (iPageId == m_iPageIdWeAreWaitingFor && m_eventLoop.isRunning())
+            QTimer::singleShot(0, this, SLOT(sltStopEventLoop()));
+    }
+
+    /* Slot to handle the fact of some page was processed: */
+    void sltHandleProcessedPages()
+    {
+        /* If all the pages were processed, unlock the loop,
+         * after all the events of the last page will be processed: */
+        if (m_eventLoop.isRunning())
+            QTimer::singleShot(0, this, SLOT(sltStopEventLoop()));
+    }
+
+    /* Slot to destroy serializer: */
+    void sltDestroySerializer()
+    {
+        /* If event loop is still running,
+         * we should try to destroy serializer only on next iteration: */
+        if (m_eventLoop.isRunning())
+            QTimer::singleShot(0, this, SLOT(sltDestroySerializer()));
+        /* Else really make a request to destroy serializer: */
+        else
+            deleteLater();
+    }
+
+    /* Slot to stop event loop: */
+    void sltStopEventLoop()
+    {
+        /* If event loop is still running, we should stop it: */
+        if (m_eventLoop.isRunning())
+        {
+            m_eventLoop.processEvents();
+            m_eventLoop.quit();
+        }
+    }
+
+protected:
+
+    /* Settings processor: */
+    void run()
+    {
+        /* Iterate over the all left settings pages: */
+        UISettingsPageMap pages(m_pages);
+        while (!pages.empty())
+        {
+            /* Get required page pointer, protect map by mutex while getting pointer: */
+            UISettingsPage *pPage = m_iIdOfHighPriorityPage != -1 && pages.contains(m_iIdOfHighPriorityPage) ?
+                                    pages[m_iIdOfHighPriorityPage] : *pages.begin();
+            /* Reset request of high priority: */
+            if (m_iIdOfHighPriorityPage != -1)
+                m_iIdOfHighPriorityPage = -1;
+            /* Process this page if its enabled: */
+            if (pPage->isEnabled())
+            {
+                if (m_direction == UISettingsSerializeDirection_Load)
+                    pPage->loadToCacheFrom(m_data);
+                if (m_direction == UISettingsSerializeDirection_Save)
+                    pPage->saveFromCacheTo(m_data);
+            }
+            /* Remember what page was processed: */
+            pPage->setProcessed(true);
+            /* Notify listeners about page was processed: */
+            emit sigNotifyAboutPageProcessed(pPage->id());
+            /* Remove processed page from our map: */
+            pages.remove(pPage->id());
+        }
+        /* Notify listeners about all pages were processed: */
+        emit sigNotifyAboutPagesProcessed();
+    }
+
+    /* Variables: */
+    UISettingsSerializeDirection m_direction;
+    QVariant m_data;
+    QEventLoop m_eventLoop;
+    UISettingsPageMap m_pages;
+    int m_iPageIdWeAreWaitingFor;
+    int m_iIdOfHighPriorityPage;
+    static UISettingsSerializer *m_pInstance;
+};
+
+UISettingsSerializer* UISettingsSerializer::m_pInstance = 0;
+
 UIGLSettingsDlg::UIGLSettingsDlg(QWidget *pParent)
     : UISettingsDialog(pParent)
@@ -68,4 +296,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxGLSettingsGeneral;
+                    pSettingsPage->setId(i);
                     addItem(":/machine_32px.png", ":/machine_disabled_32px.png",
                             ":/machine_16px.png", ":/machine_disabled_16px.png",
@@ -77,4 +306,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxGLSettingsInput;
+                    pSettingsPage->setId(i);
                     addItem(":/hostkey_32px.png", ":/hostkey_disabled_32px.png",
                             ":/hostkey_16px.png", ":/hostkey_disabled_16px.png",
@@ -86,4 +316,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxGLSettingsUpdate;
+                    pSettingsPage->setId(i);
                     addItem(":/refresh_32px.png", ":/refresh_disabled_32px.png",
                             ":/refresh_16px.png", ":/refresh_disabled_16px.png",
@@ -95,4 +326,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxGLSettingsLanguage;
+                    pSettingsPage->setId(i);
                     addItem(":/site_32px.png", ":/site_disabled_32px.png",
                             ":/site_16px.png", ":/site_disabled_16px.png",
@@ -103,5 +335,6 @@
                 case GLSettingsPage_USB:
                 {
-                    UISettingsPage *pSettingsPage = new VBoxVMSettingsUSB(VBoxVMSettingsUSB::HostType);
+                    UISettingsPage *pSettingsPage = new VBoxVMSettingsUSB(UISettingsPageType_Global);
+                    pSettingsPage->setId(i);
                     addItem(":/usb_32px.png", ":/usb_disabled_32px.png",
                             ":/usb_16px.png", ":/usb_disabled_16px.png",
@@ -113,4 +346,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxGLSettingsNetwork;
+                    pSettingsPage->setId(i);
                     addItem(":/nw_32px.png", ":/nw_disabled_32px.png",
                             ":/nw_16px.png", ":/nw_disabled_16px.png",
@@ -133,38 +367,44 @@
 void UIGLSettingsDlg::getFrom()
 {
+    /* Prepare global data: */
+    qRegisterMetaType<UISettingsDataGlobal>();
+    UISettingsDataGlobal data(vboxGlobal().virtualBox().GetSystemProperties(), vboxGlobal().settings());
+    /* Create global settings loader,
+     * it will load global settings & delete itself in the appropriate time: */
+    UISettingsSerializer *pGlobalSettingsLoader = new UISettingsSerializer(this, QVariant::fromValue(data), UISettingsSerializeDirection_Load);
+    /* Set pages to be loaded: */
+    pGlobalSettingsLoader->setPageList(m_pSelector->settingPages());
+    /* Start loader: */
+    pGlobalSettingsLoader->start();
+    /* Wait for just one (first) page to be loaded: */
+    pGlobalSettingsLoader->waitForPageToBeProcessed(m_pSelector->currentId());
+}
+
+void UIGLSettingsDlg::putBackTo()
+{
     /* Get properties and settings: */
     CSystemProperties properties = vboxGlobal().virtualBox().GetSystemProperties();
     VBoxGlobalSettings settings = vboxGlobal().settings();
-    /* Iterate over the settings pages: */
-    QList<UISettingsPage*> pages = m_pSelector->settingPages();
-    for (int i = 0; i < pages.size(); ++i)
-    {
-        /* For every page => load the settings: */
-        UISettingsPage *pPage = pages[i];
-        if (pPage->isEnabled())
-            pPage->getFrom(properties, settings);
-    }
-}
-
-void UIGLSettingsDlg::putBackTo()
-{
-    /* Get properties and settings: */
-    CSystemProperties properties = vboxGlobal().virtualBox().GetSystemProperties();
-    VBoxGlobalSettings oldSettings = vboxGlobal().settings();
-    VBoxGlobalSettings newSettings = oldSettings;
-    /* Iterate over the settings pages: */
-    QList<UISettingsPage*> pages = m_pSelector->settingPages();
-    for (int i = 0; i < pages.size(); ++i)
-    {
-        /* For every page => save the settings: */
-        UISettingsPage *pPage = pages[i];
-        if (pPage->isEnabled())
-            pPage->putBackTo(properties, newSettings);
-    }
+    /* Prepare global data: */
+    qRegisterMetaType<UISettingsDataGlobal>();
+    UISettingsDataGlobal data(properties, settings);
+    /* Create global settings saver,
+     * it will save global settings & delete itself in the appropriate time: */
+    UISettingsSerializer *pGlobalSettingsSaver = new UISettingsSerializer(this, QVariant::fromValue(data), UISettingsSerializeDirection_Save);
+    /* Set pages to be saved: */
+    pGlobalSettingsSaver->setPageList(m_pSelector->settingPages());
+    /* Start saver: */
+    pGlobalSettingsSaver->start();
+    /* Wait for all pages to be saved: */
+    pGlobalSettingsSaver->waitForPagesToBeProcessed();
+
+    /* Get updated properties & settings: */
+    CSystemProperties newProperties = pGlobalSettingsSaver->data().value<UISettingsDataGlobal>().m_properties;
+    VBoxGlobalSettings newSettings = pGlobalSettingsSaver->data().value<UISettingsDataGlobal>().m_settings;
     /* If properties are not OK => show the error: */
-    if (!properties.isOk())
-        vboxProblem().cannotSetSystemProperties(properties);
+    if (!newProperties.isOk())
+        vboxProblem().cannotSetSystemProperties(newProperties);
     /* Else save the new settings if they were changed: */
-    else if (!(newSettings == oldSettings))
+    else if (!(newSettings == settings))
         vboxGlobal().setSettings(newSettings);
 }
@@ -271,4 +511,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxVMSettingsGeneral;
+                    pSettingsPage->setId(i);
                     addItem(":/machine_32px.png", ":/machine_disabled_32px.png",
                             ":/machine_16px.png", ":/machine_disabled_16px.png",
@@ -280,4 +521,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxVMSettingsSystem;
+                    pSettingsPage->setId(i);
                     connect(pSettingsPage, SIGNAL(tableChanged()), this, SLOT(sltResetFirstRunFlag()));
                     addItem(":/chipset_32px.png", ":/chipset_disabled_32px.png",
@@ -290,4 +532,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxVMSettingsDisplay;
+                    pSettingsPage->setId(i);
                     addItem(":/vrdp_32px.png", ":/vrdp_disabled_32px.png",
                             ":/vrdp_16px.png", ":/vrdp_disabled_16px.png",
@@ -299,4 +542,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxVMSettingsHD;
+                    pSettingsPage->setId(i);
                     connect(pSettingsPage, SIGNAL(storageChanged()), this, SLOT(sltResetFirstRunFlag()));
                     addItem(":/hd_32px.png", ":/hd_disabled_32px.png",
@@ -309,4 +553,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxVMSettingsAudio;
+                    pSettingsPage->setId(i);
                     addItem(":/sound_32px.png", ":/sound_disabled_32px.png",
                             ":/sound_16px.png", ":/sound_disabled_16px.png",
@@ -318,4 +563,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxVMSettingsNetworkPage;
+                    pSettingsPage->setId(i);
                     addItem(":/nw_32px.png", ":/nw_disabled_32px.png",
                             ":/nw_16px.png", ":/nw_disabled_16px.png",
@@ -335,4 +581,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxVMSettingsSerialPage;
+                    pSettingsPage->setId(i);
                     addItem(":/serial_port_32px.png", ":/serial_port_disabled_32px.png",
                             ":/serial_port_16px.png", ":/serial_port_disabled_16px.png",
@@ -344,4 +591,5 @@
                 {
                     UISettingsPage *pSettingsPage = new VBoxVMSettingsParallelPage;
+                    pSettingsPage->setId(i);
                     addItem(":/parallel_port_32px.png", ":/parallel_port_disabled_32px.png",
                             ":/parallel_port_16px.png", ":/parallel_port_disabled_16px.png",
@@ -352,5 +600,6 @@
                 case VMSettingsPage_USB:
                 {
-                    UISettingsPage *pSettingsPage = new VBoxVMSettingsUSB(VBoxVMSettingsUSB::MachineType);
+                    UISettingsPage *pSettingsPage = new VBoxVMSettingsUSB(UISettingsPageType_Machine);
+                    pSettingsPage->setId(i);
                     addItem(":/usb_32px.png", ":/usb_disabled_32px.png",
                             ":/usb_16px.png", ":/usb_disabled_16px.png",
@@ -361,5 +610,6 @@
                 case VMSettingsPage_SF:
                 {
-                    UISettingsPage *pSettingsPage = new VBoxVMSettingsSF(MachineType);
+                    UISettingsPage *pSettingsPage = new VBoxVMSettingsSF;
+                    pSettingsPage->setId(i);
                     addItem(":/shared_folder_32px.png", ":/shared_folder_disabled_32px.png",
                             ":/shared_folder_16px.png", ":/shared_folder_disabled_16px.png",
@@ -367,4 +617,6 @@
                     break;
                 }
+                default:
+                    break;
             }
         }
@@ -410,30 +662,41 @@
 void UIVMSettingsDlg::getFrom()
 {
-    /* Iterate over the settings pages: */
-    QList<UISettingsPage*> pages = m_pSelector->settingPages();
-    for (int i = 0; i < pages.size(); ++i)
-    {
-        /* For every page => load the settings: */
-        UISettingsPage *pPage = pages[i];
-        if (pPage->isEnabled())
-            pPage->getFrom(m_machine);
-    }
-    /* Finally set the reset First Run Wizard flag to "false" to make sure
-     * user will see this dialog if he hasn't change the boot-order
-     * and/or mounted images configuration: */
-    m_fResetFirstRunFlag = false;
+    /* Prepare machine data: */
+    qRegisterMetaType<UISettingsDataMachine>();
+    UISettingsDataMachine data(m_machine);
+    /* Create machine settings loader,
+     * it will load machine settings & delete itself in the appropriate time: */
+    UISettingsSerializer *pMachineSettingsLoader = new UISettingsSerializer(this, QVariant::fromValue(data), UISettingsSerializeDirection_Load);
+    connect(pMachineSettingsLoader, SIGNAL(sigNotifyAboutPagesProcessed()), this, SLOT(sltSetFirstRunFlag()));
+    /* Set pages to be loaded: */
+    pMachineSettingsLoader->setPageList(m_pSelector->settingPages());
+    /* Ask to raise required page priority: */
+    pMachineSettingsLoader->raisePriorityOfPage(m_pSelector->currentId());
+    /* Start page loader: */
+    pMachineSettingsLoader->start();
+    /* Wait for just one (required) page to be loaded: */
+    pMachineSettingsLoader->waitForPageToBeProcessed(m_pSelector->currentId());
 }
 
 void UIVMSettingsDlg::putBackTo()
 {
-    /* Iterate over the settings pages: */
-    QList<UISettingsPage*> pages = m_pSelector->settingPages();
-    for (int i = 0; i < pages.size(); ++i)
-    {
-        /* For every page => save the settings: */
-        UISettingsPage *pPage = pages[i];
-        if (pPage->isEnabled())
-            pPage->putBackTo();
-    }
+    /* Prepare machine data: */
+    qRegisterMetaType<UISettingsDataMachine>();
+    UISettingsDataMachine data(m_machine);
+    /* Create machine settings saver,
+     * it will save machine settings & delete itself in the appropriate time: */
+    UISettingsSerializer *pMachineSettingsSaver = new UISettingsSerializer(this, QVariant::fromValue(data), UISettingsSerializeDirection_Save);
+    /* Set pages to be saved: */
+    pMachineSettingsSaver->setPageList(m_pSelector->settingPages());
+    /* Start saver: */
+    pMachineSettingsSaver->start();
+    /* Wait for all pages to be saved: */
+    pMachineSettingsSaver->waitForPagesToBeProcessed();
+
+    /* Get updated machine: */
+    m_machine = pMachineSettingsSaver->data().value<UISettingsDataMachine>().m_machine;
+    /* If machine is not OK => show the error: */
+    if (!m_machine.isOk())
+        vboxProblem().cannotSaveMachineSettings(m_machine);
 
     /* Guest OS type & VT-x/AMD-V option correlation auto-fix: */
@@ -482,5 +745,4 @@
      * vboxGlobal which is retranslated at that point already. */
     QEvent event(QEvent::LanguageChange);
-    QWidget *pPage = 0;
 
     /* General page: */
@@ -501,5 +763,5 @@
     /* Network page: */
     m_pSelector->setItemText(VMSettingsPage_Network, tr("Network"));
-    if ((pPage = m_pSelector->idToPage(VMSettingsPage_Network)))
+    if (QWidget *pPage = m_pSelector->idToPage(VMSettingsPage_Network))
         qApp->sendEvent(pPage, &event);
 
@@ -509,10 +771,10 @@
     /* Serial page: */
     m_pSelector->setItemText(VMSettingsPage_Serial, tr("Serial Ports"));
-    if ((pPage = m_pSelector->idToPage(VMSettingsPage_Serial)))
+    if (QWidget *pPage = m_pSelector->idToPage(VMSettingsPage_Serial))
         qApp->sendEvent(pPage, &event);
 
     /* Parallel page: */
     m_pSelector->setItemText(VMSettingsPage_Parallel, tr("Parallel Ports"));
-    if ((pPage = m_pSelector->idToPage(VMSettingsPage_Parallel)))
+    if (QWidget *pPage = m_pSelector->idToPage(VMSettingsPage_Parallel))
         qApp->sendEvent(pPage, &event);
 
@@ -552,6 +814,5 @@
      * between different pages of VM Settings dialog: */
 
-    if (pPage == m_pSelector->idToPage(VMSettingsPage_General) ||
-        pPage == m_pSelector->idToPage(VMSettingsPage_System))
+    if (pPage == m_pSelector->idToPage(VMSettingsPage_General))
     {
         /* Get General & System pages: */
@@ -603,6 +864,5 @@
 
 #ifndef VBOX_OSE
-    if (pPage == m_pSelector->idToPage(VMSettingsPage_System) ||
-        pPage == m_pSelector->idToPage(VMSettingsPage_USB))
+    if (pPage == m_pSelector->idToPage(VMSettingsPage_System))
     {
         /* Get System & USB pages: */
@@ -627,7 +887,20 @@
 }
 
+void UIVMSettingsDlg::sltCategoryChanged(int cId)
+{
+    if (UISettingsSerializer::instance())
+        UISettingsSerializer::instance()->raisePriorityOfPage(cId);
+
+    UISettingsDialog::sltCategoryChanged(cId);
+}
+
 void UIVMSettingsDlg::sltAllowResetFirstRunFlag()
 {
     m_fAllowResetFirstRunFlag = true;
+}
+
+void UIVMSettingsDlg::sltSetFirstRunFlag()
+{
+    m_fResetFirstRunFlag = false;
 }
 
@@ -684,2 +957,4 @@
 }
 
+# include "UISettingsDialogSpecific.moc"
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.h	(revision 33631)
@@ -97,5 +97,7 @@
 private slots:
 
+    void sltCategoryChanged(int cId);
     void sltAllowResetFirstRunFlag();
+    void sltSetFirstRunFlag();
     void sltResetFirstRunFlag();
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.cpp	(revision 33631)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.cpp	(revision 33631)
@@ -0,0 +1,119 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * UISettingsPage class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * 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.
+ */
+
+/* Local includes */
+#include "UISettingsPage.h"
+
+/* Returns settings page type: */
+UISettingsPageType UISettingsPage::type() const
+{
+    return m_type;
+}
+
+/* Validation stuff: */
+void UISettingsPage::setValidator(QIWidgetValidator *pValidator)
+{
+    Q_UNUSED(pValidator);
+}
+
+/* Validation stuff: */
+bool UISettingsPage::revalidate(QString &strWarningText, QString &strTitle)
+{
+    Q_UNUSED(strWarningText);
+    Q_UNUSED(strTitle);
+    return true;
+}
+
+/* Navigation stuff: */
+void UISettingsPage::setOrderAfter(QWidget *pWidget)
+{
+    m_pFirstWidget = pWidget;
+}
+
+/* Page 'ID' stuff: */
+int UISettingsPage::id() const
+{
+    return m_cId;
+}
+
+/* Page 'ID' stuff: */
+void UISettingsPage::setId(int cId)
+{
+    m_cId = cId;
+}
+
+/* Page 'processed' stuff: */
+bool UISettingsPage::processed() const
+{
+    return m_fProcessed;
+}
+
+/* Page 'processed' stuff: */
+void UISettingsPage::setProcessed(bool fProcessed)
+{
+    m_fProcessed = fProcessed;
+}
+
+/* Settings page constructor, hidden: */
+UISettingsPage::UISettingsPage(UISettingsPageType type, QWidget *pParent)
+    : QIWithRetranslateUI<QWidget>(pParent)
+    , m_type(type)
+    , m_cId(-1)
+    , m_fProcessed(false)
+    , m_pFirstWidget(0)
+{
+}
+
+/* Fetch data to m_properties & m_settings: */
+void UISettingsPageGlobal::fetchData(const QVariant &data)
+{
+    m_properties = data.value<UISettingsDataGlobal>().m_properties;
+    m_settings = data.value<UISettingsDataGlobal>().m_settings;
+}
+
+/* Upload m_properties & m_settings to data: */
+void UISettingsPageGlobal::uploadData(QVariant &data) const
+{
+    data = QVariant::fromValue(UISettingsDataGlobal(m_properties, m_settings));
+}
+
+/* Global settings page constructor, hidden: */
+UISettingsPageGlobal::UISettingsPageGlobal(QWidget *pParent)
+    : UISettingsPage(UISettingsPageType_Global, pParent)
+{
+}
+
+/* Fetch data to m_machine: */
+void UISettingsPageMachine::fetchData(const QVariant &data)
+{
+    m_machine = data.value<UISettingsDataMachine>().m_machine;
+}
+
+/* Upload m_machine to data: */
+void UISettingsPageMachine::uploadData(QVariant &data) const
+{
+    data = QVariant::fromValue(UISettingsDataMachine(m_machine));
+}
+
+/* Machine settings page constructor, hidden: */
+UISettingsPageMachine::UISettingsPageMachine(QWidget *pParent)
+    : UISettingsPage(UISettingsPageType_Machine, pParent)
+{
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsPage.h	(revision 33631)
@@ -22,12 +22,41 @@
 /* Global includes */
 #include <QWidget>
+#include <QVariant>
 
 /* Local includes */
 #include "QIWithRetranslateUI.h"
 #include "COMDefs.h"
+#include "VBoxGlobalSettings.h"
 
 /* Forward declarations */
-class VBoxGlobalSettings;
 class QIWidgetValidator;
+
+/* Settings page types: */
+enum UISettingsPageType
+{
+    UISettingsPageType_Global,
+    UISettingsPageType_Machine
+};
+
+/* Global settings data wrapper: */
+struct UISettingsDataGlobal
+{
+    UISettingsDataGlobal() {}
+    UISettingsDataGlobal(const CSystemProperties &properties, const VBoxGlobalSettings &settings)
+        : m_properties(properties), m_settings(settings) {}
+    CSystemProperties m_properties;
+    VBoxGlobalSettings m_settings;
+};
+Q_DECLARE_METATYPE(UISettingsDataGlobal);
+
+/* Machine settings data wrapper: */
+struct UISettingsDataMachine
+{
+    UISettingsDataMachine() {}
+    UISettingsDataMachine(const CMachine &machine)
+        : m_machine(machine) {}
+    CMachine m_machine;
+};
+Q_DECLARE_METATYPE(UISettingsDataMachine);
 
 /* Settings page base class: */
@@ -38,31 +67,87 @@
 public:
 
-    /* Settings page constructor: */
-    UISettingsPage(QWidget *pParent = 0)
-        : QIWithRetranslateUI<QWidget>(pParent)
-        , m_pFirstWidget(0)
-    {
-    }
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    virtual void loadToCacheFrom(QVariant &data) = 0;
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    virtual void getFromCache() = 0;
 
-    /* Global settings set/get stuff */
-    virtual void getFrom (const CSystemProperties & /* aProps */,
-                          const VBoxGlobalSettings & /* aGs */) {}
-    virtual void putBackTo (CSystemProperties & /* aProps */,
-                            VBoxGlobalSettings & /* aGs */) {}
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    virtual void putToCache() = 0;
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    virtual void saveFromCacheTo(QVariant &data) = 0;
 
-    /* VM settings set/get stuff */
-    virtual void getFrom (const CMachine & /* aMachine */) {}
-    virtual void putBackTo() {}
+    /* Returns settings page type: */
+    virtual UISettingsPageType type() const;
 
     /* Validation stuff: */
-    virtual void setValidator(QIWidgetValidator * /* pValidator */) {}
-    virtual bool revalidate(QString & /* strWarningText */, QString & /* strTitle */) { return true; }
+    virtual void setValidator(QIWidgetValidator *pValidator);
+    virtual bool revalidate(QString &strWarningText, QString &strTitle);
 
     /* Navigation stuff: */
-    virtual void setOrderAfter(QWidget *pWidget) { m_pFirstWidget = pWidget; }
+    virtual void setOrderAfter(QWidget *pWidget);
+
+    /* Page 'ID' stuff: */
+    int id() const;
+    void setId(int cId);
+
+    /* Page 'processed' stuff: */
+    bool processed() const;
+    void setProcessed(bool fProcessed);
 
 protected:
 
+    /* Settings page constructor, hidden: */
+    UISettingsPage(UISettingsPageType type, QWidget *pParent = 0);
+
+    /* Variables: */
+    UISettingsPageType m_type;
+    int m_cId;
+    bool m_fProcessed;
     QWidget *m_pFirstWidget;
+};
+
+/* Global settings page class: */
+class UISettingsPageGlobal : public UISettingsPage
+{
+    Q_OBJECT;
+
+protected:
+
+    /* Fetch data to m_properties & m_settings: */
+    void fetchData(const QVariant &data);
+
+    /* Upload m_properties & m_settings to data: */
+    void uploadData(QVariant &data) const;
+
+    /* Global settings page constructor, hidden: */
+    UISettingsPageGlobal(QWidget *pParent = 0);
+
+    /* Global data source: */
+    CSystemProperties m_properties;
+    VBoxGlobalSettings m_settings;
+};
+
+/* Machine settings page class: */
+class UISettingsPageMachine : public UISettingsPage
+{
+    Q_OBJECT;
+
+protected:
+
+    /* Fetch data to m_machine: */
+    void fetchData(const QVariant &data);
+
+    /* Upload m_machine to data: */
+    void uploadData(QVariant &data) const;
+
+    /* Machine settings page constructor, hidden: */
+    UISettingsPageMachine(QWidget *pParent = 0);
+
+    /* Machine data source: */
+    CMachine m_machine;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -48,5 +48,4 @@
         mLnSeparator2->hide();
 
-    mPsHardDisk->setHomeDir (vboxGlobal().virtualBox().GetHomeFolder());
     mPsMach->setHomeDir (vboxGlobal().virtualBox().GetHomeFolder());
     mPsVRDP->setHomeDir (vboxGlobal().virtualBox().GetHomeFolder());
@@ -57,28 +56,81 @@
 }
 
-void VBoxGLSettingsGeneral::getFrom (const CSystemProperties &aProps,
-                                     const VBoxGlobalSettings &aGs)
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsGeneral::loadToCacheFrom(QVariant &data)
 {
-    mPsMach->setPath (aProps.GetDefaultMachineFolder());
-    mPsVRDP->setPath (aProps.GetVRDEAuthLibrary());
-    mCbCheckTrayIcon->setChecked (aGs.trayIconEnabled());
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Load to cache: */
+    m_cache.m_strDefaultMachineFolder = m_properties.GetDefaultMachineFolder();
+    m_cache.m_strVRDEAuthLibrary = m_properties.GetVRDEAuthLibrary();
+    m_cache.m_fTrayIconEnabled = m_settings.trayIconEnabled();
 #ifdef Q_WS_MAC
-    mCbCheckPresentationMode->setChecked (aGs.presentationModeEnabled());
+    m_cache.m_fPresentationModeEnabled = m_settings.presentationModeEnabled();
 #endif /* Q_WS_MAC */
-    mCbDisableHostScreenSaver->setChecked (aGs.hostScreenSaverDisabled());
+    m_cache.m_fHostScreenSaverDisables = m_settings.hostScreenSaverDisabled();
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
 }
 
-void VBoxGLSettingsGeneral::putBackTo (CSystemProperties &aProps,
-                                       VBoxGlobalSettings &aGs)
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsGeneral::getFromCache()
 {
-    if (aProps.isOk() && mPsMach->isModified())
-        aProps.SetDefaultMachineFolder (mPsMach->path());
-    if (aProps.isOk() && mPsVRDP->isModified())
-        aProps.SetVRDEAuthLibrary (mPsVRDP->path());
-    aGs.setTrayIconEnabled (mCbCheckTrayIcon->isChecked());
+    /* Fetch from cache: */
+    mPsMach->setPath(m_cache.m_strDefaultMachineFolder);
+    mPsVRDP->setPath(m_cache.m_strVRDEAuthLibrary);
+    mCbCheckTrayIcon->setChecked(m_cache.m_fTrayIconEnabled);
 #ifdef Q_WS_MAC
-    aGs.setPresentationModeEnabled (mCbCheckPresentationMode->isChecked());
+    mCbCheckPresentationMode->setChecked(m_cache.m_fPresentationModeEnabled);
 #endif /* Q_WS_MAC */
-    aGs.setHostScreenSaverDisabled (mCbDisableHostScreenSaver->isChecked());
+    mCbDisableHostScreenSaver->setChecked(m_cache.m_fHostScreenSaverDisables);
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsGeneral::putToCache()
+{
+    /* Upload to cache: */
+    m_cache.m_strDefaultMachineFolder = mPsMach->path();
+    m_cache.m_strVRDEAuthLibrary = mPsVRDP->path();
+    m_cache.m_fTrayIconEnabled = mCbCheckTrayIcon->isChecked();
+#ifdef Q_WS_MAC
+    m_cache.m_fPresentationModeEnabled = mCbCheckPresentationMode->isChecked();
+#endif /* Q_WS_MAC */
+    m_cache.m_fHostScreenSaverDisables = mCbDisableHostScreenSaver->isChecked();
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsGeneral::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Save from cache: */
+    if (m_properties.isOk() && mPsMach->isModified())
+        m_properties.SetDefaultMachineFolder(m_cache.m_strDefaultMachineFolder);
+    if (m_properties.isOk() && mPsVRDP->isModified())
+        m_properties.SetVRDEAuthLibrary(m_cache.m_strVRDEAuthLibrary);
+    m_settings.setTrayIconEnabled(m_cache.m_fTrayIconEnabled);
+#ifdef Q_WS_MAC
+    m_settings.setPresentationModeEnabled(m_cache.m_fPresentationModeEnabled);
+#endif /* Q_WS_MAC */
+    m_settings.setHostScreenSaverDisabled(m_cache.m_fHostScreenSaverDisables);
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
+}
+
+void VBoxGLSettingsGeneral::setOrderAfter (QWidget *aWidget)
+{
+    setTabOrder (aWidget, mPsMach);
+    setTabOrder (mPsMach, mPsVRDP);
+    setTabOrder (mPsVRDP, mCbCheckTrayIcon);
+    setTabOrder (mCbCheckTrayIcon, mCbCheckPresentationMode);
+    setTabOrder (mCbCheckPresentationMode, mCbDisableHostScreenSaver);
 }
 
@@ -88,8 +140,4 @@
     Ui::VBoxGLSettingsGeneral::retranslateUi (this);
 
-    mPsHardDisk->setWhatsThis (tr ("Displays the path to the default hard disk "
-                                   "folder. This folder is used, if not explicitly "
-                                   "specified otherwise, when adding existing or "
-                                   "creating new virtual hard disks."));
     mPsMach->setWhatsThis (tr ("Displays the path to the default virtual "
                                "machine folder. This folder is used, if not "
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -23,5 +23,18 @@
 #include "VBoxGLSettingsGeneral.gen.h"
 
-class VBoxGLSettingsGeneral : public UISettingsPage,
+/* Global settings / General page / Cache: */
+struct UISettingsCacheGlobalGeneral
+{
+    QString m_strDefaultMachineFolder;
+    QString m_strVRDEAuthLibrary;
+    bool m_fTrayIconEnabled;
+#ifdef Q_WS_MAC
+    bool m_fPresentationModeEnabled;
+#endif /* Q_WS_MAC */
+    bool m_fHostScreenSaverDisables;
+};
+
+/* Global settings / General page: */
+class VBoxGLSettingsGeneral : public UISettingsPageGlobal,
                               public Ui::VBoxGLSettingsGeneral
 {
@@ -34,10 +47,26 @@
 protected:
 
-    void getFrom (const CSystemProperties &aProps,
-                  const VBoxGlobalSettings &aGs);
-    void putBackTo (CSystemProperties &aProps,
-                    VBoxGlobalSettings &aGs);
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
+
+    void setOrderAfter (QWidget *aWidget);
 
     void retranslateUi();
+
+private:
+
+    /* Cache: */
+    UISettingsCacheGlobalGeneral m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.ui
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.ui	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsGeneral.ui	(revision 33631)
@@ -4,5 +4,5 @@
  VBox frontends: Qt4 GUI (&quot;VirtualBox&quot;):
 
-     Copyright (C) 2008 Oracle Corporation
+     Copyright (C) 2008-2010 Oracle Corporation
 
      This file is part of VirtualBox Open Source Edition (OSE), as
@@ -29,27 +29,4 @@
    </property>
    <item row="0" column="0" colspan="2">
-    <widget class="QLabel" name="mLbHardDisk">
-     <property name="text">
-      <string>Default &amp;Hard Disk Folder:</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-     </property>
-     <property name="buddy">
-      <cstring>mPsHardDisk</cstring>
-     </property>
-    </widget>
-   </item>
-   <item row="0" column="2">
-    <widget class="VBoxFilePathSelectorWidget" name="mPsHardDisk">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="0" colspan="2">
     <widget class="QLabel" name="mLbMach">
      <property name="text">
@@ -64,5 +41,5 @@
     </widget>
    </item>
-   <item row="1" column="2">
+   <item row="0" column="2">
     <widget class="VBoxFilePathSelectorWidget" name="mPsMach">
      <property name="sizePolicy">
@@ -74,5 +51,5 @@
     </widget>
    </item>
-   <item row="2" column="0" colspan="3">
+   <item row="1" column="0" colspan="3">
     <widget class="Line" name="mLnSeparator">
      <property name="orientation">
@@ -81,5 +58,5 @@
     </widget>
    </item>
-   <item row="3" column="0" colspan="2">
+   <item row="2" column="0" colspan="2">
     <widget class="QLabel" name="mLbVRDP">
      <property name="text">
@@ -94,5 +71,5 @@
     </widget>
    </item>
-   <item row="3" column="2">
+   <item row="2" column="2">
     <widget class="VBoxFilePathSelectorWidget" name="mPsVRDP">
      <property name="sizePolicy">
@@ -104,5 +81,5 @@
     </widget>
    </item>
-   <item row="4" column="0" colspan="3">
+   <item row="3" column="0" colspan="3">
     <widget class="Line" name="mLnSeparator2">
      <property name="orientation">
@@ -111,5 +88,5 @@
     </widget>
    </item>
-   <item row="5" column="0">
+   <item row="4" column="0">
     <widget class="QWidget" name="mWtSpacer1">
      <property name="sizePolicy">
@@ -124,5 +101,5 @@
     </widget>
    </item>
-   <item row="5" column="1" colspan="2">
+   <item row="4" column="1" colspan="2">
     <widget class="QCheckBox" name="mCbCheckTrayIcon">
      <property name="whatsThis">
@@ -137,5 +114,5 @@
     </widget>
    </item>
-   <item row="6" column="0">
+   <item row="5" column="0">
     <widget class="QWidget" name="mWtSpacer2">
      <property name="sizePolicy">
@@ -150,5 +127,5 @@
     </widget>
    </item>
-   <item row="6" column="1" colspan="2">
+   <item row="5" column="1" colspan="2">
     <widget class="QCheckBox" name="mCbCheckPresentationMode">
      <property name="text">
@@ -157,5 +134,5 @@
     </widget>
    </item>
-   <item row="7" column="0">
+   <item row="6" column="0">
     <widget class="QWidget" name="mWtSpacer3">
      <property name="sizePolicy">
@@ -170,5 +147,5 @@
     </widget>
    </item>
-   <item row="7" column="1" colspan="2">
+   <item row="6" column="1" colspan="2">
     <widget class="QCheckBox" name="mCbDisableHostScreenSaver">
      <property name="whatsThis">
@@ -180,5 +157,5 @@
     </widget>
    </item>
-   <item row="10" column="0" colspan="3">
+   <item row="7" column="0" colspan="3">
     <spacer>
      <property name="orientation">
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsInput.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsInput.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsInput.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -30,16 +30,50 @@
 }
 
-void VBoxGLSettingsInput::getFrom (const CSystemProperties &,
-                                   const VBoxGlobalSettings &aGs)
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsInput::loadToCacheFrom(QVariant &data)
 {
-    mHeHostKey->setKey (aGs.hostKey());
-    mCbAutoGrab->setChecked (aGs.autoCapture());
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Load to cache: */
+    m_cache.m_iHostKey = m_settings.hostKey();
+    m_cache.m_fAutoCapture = m_settings.autoCapture();
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
 }
 
-void VBoxGLSettingsInput::putBackTo (CSystemProperties &,
-                                     VBoxGlobalSettings &aGs)
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsInput::getFromCache()
 {
-    aGs.setHostKey (mHeHostKey->key());
-    aGs.setAutoCapture (mCbAutoGrab->isChecked());
+    /* Fetch from cache: */
+    mHeHostKey->setKey(m_cache.m_iHostKey);
+    mCbAutoGrab->setChecked(m_cache.m_fAutoCapture);
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsInput::putToCache()
+{
+    /* Upload to cache: */
+    m_cache.m_iHostKey = mHeHostKey->key();
+    m_cache.m_fAutoCapture = mCbAutoGrab->isChecked();
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsInput::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Save from cache: */
+    m_settings.setHostKey(m_cache.m_iHostKey);
+    m_settings.setAutoCapture(m_cache.m_fAutoCapture);
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsInput.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsInput.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsInput.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -23,5 +23,13 @@
 #include "VBoxGLSettingsInput.gen.h"
 
-class VBoxGLSettingsInput : public UISettingsPage,
+/* Global settings / Input page / Cache: */
+struct UISettingsCacheGlobalInput
+{
+    int m_iHostKey;
+    bool m_fAutoCapture;
+};
+
+/* Global settings / Input page: */
+class VBoxGLSettingsInput : public UISettingsPageGlobal,
                             public Ui::VBoxGLSettingsInput
 {
@@ -34,12 +42,26 @@
 protected:
 
-    void getFrom (const CSystemProperties &aProps,
-                  const VBoxGlobalSettings &aGs);
-    void putBackTo (CSystemProperties &aProps,
-                    VBoxGlobalSettings &aGs);
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setOrderAfter (QWidget *aWidget);
 
     void retranslateUi();
+
+private:
+
+    /* Cache: */
+    UISettingsCacheGlobalInput m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsLanguage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsLanguage.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsLanguage.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -189,19 +189,54 @@
 }
 
-void VBoxGLSettingsLanguage::getFrom (const CSystemProperties & /* aProps */, const VBoxGlobalSettings &aGs)
-{
-    reload (aGs.languageId());
-    mTxName->setFixedHeight (fontMetrics().height() * 4);
-}
-
-void VBoxGLSettingsLanguage::putBackTo (CSystemProperties & /* aProps */, VBoxGlobalSettings &aGs)
-{
-    QTreeWidgetItem *curItem = mTwLanguage->currentItem();
-    Assert (curItem);
-    if (mLanguageChanged && curItem)
-    {
-        aGs.setLanguageId (curItem->text (1));
-        VBoxGlobal::loadLanguage (curItem->text (1));
-    }
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsLanguage::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Load to cache: */
+    m_cache.m_strLanguageId = m_settings.languageId();
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsLanguage::getFromCache()
+{
+    /* Fetch from cache: */
+    reload(m_cache.m_strLanguageId);
+    mTxName->setFixedHeight(fontMetrics().height() * 4);
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsLanguage::putToCache()
+{
+    /* Upload to cache: */
+    QTreeWidgetItem *pCurrentItem = mTwLanguage->currentItem();
+    Assert(pCurrentItem);
+    if (pCurrentItem)
+        m_cache.m_strLanguageId = pCurrentItem->text(1);
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsLanguage::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Save from cache: */
+    if (mLanguageChanged)
+    {
+        m_settings.setLanguageId(m_cache.m_strLanguageId);
+        VBoxGlobal::loadLanguage(m_cache.m_strLanguageId);
+    }
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsLanguage.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsLanguage.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsLanguage.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -23,5 +23,12 @@
 #include "VBoxGLSettingsLanguage.gen.h"
 
-class VBoxGLSettingsLanguage : public UISettingsPage,
+/* Global settings / Language page / Cache: */
+struct UISettingsCacheGlobalLanguage
+{
+    QString m_strLanguageId;
+};
+
+/* Global settings / Language page: */
+class VBoxGLSettingsLanguage : public UISettingsPageGlobal,
                                public Ui::VBoxGLSettingsLanguage
 {
@@ -34,8 +41,17 @@
 protected:
 
-    void getFrom (const CSystemProperties &aProps,
-                  const VBoxGlobalSettings &aGs);
-    void putBackTo (CSystemProperties &aProps,
-                    VBoxGlobalSettings &aGs);
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setOrderAfter (QWidget *aWidget);
@@ -53,4 +69,7 @@
 
     bool mLanguageChanged;
+
+    /* Cache: */
+    UISettingsCacheGlobalLanguage m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -32,88 +32,20 @@
 NetworkItem::NetworkItem()
     : QTreeWidgetItem()
-    , mChanged (false)
-    , mName (QString::null)
-    , mDhcpClientEnabled (false)
-    , mInterfaceAddress (QString::null)
-    , mInterfaceMask (QString::null)
-    , mIpv6Supported (false)
-    , mInterfaceAddress6 (QString::null)
-    , mInterfaceMaskLength6 (QString::null)
-    , mDhcpServerEnabled (false)
-    , mDhcpServerAddress (QString::null)
-    , mDhcpServerMask (QString::null)
-    , mDhcpLowerAddress (QString::null)
-    , mDhcpUpperAddress (QString::null)
-{
-}
-
-void NetworkItem::getFromInterface (const CHostNetworkInterface &aInterface)
-{
-    /* Initialization */
-    mInterface = aInterface;
-    mName = mInterface.GetName();
-    CDHCPServer dhcp = vboxGlobal().virtualBox().FindDHCPServerByNetworkName (mInterface.GetNetworkName());
-    if (dhcp.isNull()) vboxGlobal().virtualBox().CreateDHCPServer (mInterface.GetNetworkName());
-    dhcp = vboxGlobal().virtualBox().FindDHCPServerByNetworkName (mInterface.GetNetworkName());
-    AssertMsg (!dhcp.isNull(), ("DHCP Server creation failed!\n"));
-    setText (0, VBoxGLSettingsNetwork::tr ("%1 network", "<adapter name> network").arg (mName));
-
-    /* Host-only Interface settings */
-    mDhcpClientEnabled = mInterface.GetDhcpEnabled();
-    mInterfaceAddress = mInterface.GetIPAddress();
-    mInterfaceMask = mInterface.GetNetworkMask();
-    mIpv6Supported = mInterface.GetIPV6Supported();
-    mInterfaceAddress6 = mInterface.GetIPV6Address();
-    mInterfaceMaskLength6 = QString ("%1").arg (mInterface.GetIPV6NetworkMaskPrefixLength());
-
-    /* DHCP Server settings */
-    mDhcpServerEnabled = dhcp.GetEnabled();
-    mDhcpServerAddress = dhcp.GetIPAddress();
-    mDhcpServerMask = dhcp.GetNetworkMask();
-    mDhcpLowerAddress = dhcp.GetLowerIP();
-    mDhcpUpperAddress = dhcp.GetUpperIP();
-
-    /* Update tool-tip */
+{
+}
+
+void NetworkItem::fetchNetworkData(const UIHostNetworkData &data)
+{
+    /* Fetch from cache: */
+    m_data = data;
+
+    /* Update tool-tip: */
     updateInfo();
 }
 
-void NetworkItem::putBackToInterface()
-{
-    /* Host-only Interface settings */
-    if (mDhcpClientEnabled)
-    {
-        mInterface.EnableDynamicIpConfig();
-    }
-    else
-    {
-        AssertMsg (mInterfaceAddress.isEmpty() ||
-                   QHostAddress (mInterfaceAddress).protocol() == QAbstractSocket::IPv4Protocol,
-                   ("Interface IPv4 address must be empty or IPv4-valid!\n"));
-        AssertMsg (mInterfaceMask.isEmpty() ||
-                   QHostAddress (mInterfaceMask).protocol() == QAbstractSocket::IPv4Protocol,
-                   ("Interface IPv4 network mask must be empty or IPv4-valid!\n"));
-        mInterface.EnableStaticIpConfig (mInterfaceAddress, mInterfaceMask);
-        if (mInterface.GetIPV6Supported())
-        {
-            AssertMsg (mInterfaceAddress6.isEmpty() ||
-                       QHostAddress (mInterfaceAddress6).protocol() == QAbstractSocket::IPv6Protocol,
-                       ("Interface IPv6 address must be empty or IPv6-valid!\n"));
-            mInterface.EnableStaticIpConfigV6 (mInterfaceAddress6, mInterfaceMaskLength6.toULong());
-        }
-    }
-
-    /* DHCP Server settings */
-    CDHCPServer dhcp = vboxGlobal().virtualBox().FindDHCPServerByNetworkName (mInterface.GetNetworkName());
-    AssertMsg (!dhcp.isNull(), ("DHCP Server should be already created!\n"));
-    dhcp.SetEnabled (mDhcpServerEnabled);
-    AssertMsg (QHostAddress (mDhcpServerAddress).protocol() == QAbstractSocket::IPv4Protocol,
-               ("DHCP Server IPv4 address must be IPv4-valid!\n"));
-    AssertMsg (QHostAddress (mDhcpServerMask).protocol() == QAbstractSocket::IPv4Protocol,
-               ("DHCP Server IPv4 network mask must be IPv4-valid!\n"));
-    AssertMsg (QHostAddress (mDhcpLowerAddress).protocol() == QAbstractSocket::IPv4Protocol,
-               ("DHCP Server IPv4 lower bound must be IPv4-valid!\n"));
-    AssertMsg (QHostAddress (mDhcpUpperAddress).protocol() == QAbstractSocket::IPv4Protocol,
-               ("DHCP Server IPv4 upper bound must be IPv4-valid!\n"));
-    dhcp.SetConfiguration (mDhcpServerAddress, mDhcpServerMask, mDhcpLowerAddress, mDhcpUpperAddress);
+void NetworkItem::uploadNetworkData(UIHostNetworkData &data)
+{
+    /* Upload to cache: */
+    data = m_data;
 }
 
@@ -121,25 +53,25 @@
 {
     /* Host-only Interface validation */
-    if (!mDhcpClientEnabled)
-    {
-        if (!mInterfaceAddress.isEmpty() &&
-            (QHostAddress (mInterfaceAddress) == QHostAddress::Any ||
-             QHostAddress (mInterfaceAddress).protocol() != QAbstractSocket::IPv4Protocol))
+    if (!m_data.m_interface.m_fDhcpClientEnabled)
+    {
+        if (m_data.m_interface.m_strInterfaceAddress.isEmpty() &&
+            (QHostAddress (m_data.m_interface.m_strInterfaceAddress) == QHostAddress::Any ||
+             QHostAddress (m_data.m_interface.m_strInterfaceAddress).protocol() != QAbstractSocket::IPv4Protocol))
         {
             aWarning = VBoxGLSettingsNetwork::tr ("host IPv4 address of <b>%1</b> is wrong").arg (text (0));
             return false;
         }
-        if (!mInterfaceMask.isEmpty() &&
-            (QHostAddress (mInterfaceMask) == QHostAddress::Any ||
-             QHostAddress (mInterfaceMask).protocol() != QAbstractSocket::IPv4Protocol))
+        if (!m_data.m_interface.m_strInterfaceMask.isEmpty() &&
+            (QHostAddress (m_data.m_interface.m_strInterfaceMask) == QHostAddress::Any ||
+             QHostAddress (m_data.m_interface.m_strInterfaceMask).protocol() != QAbstractSocket::IPv4Protocol))
         {
             aWarning = VBoxGLSettingsNetwork::tr ("host IPv4 network mask of <b>%1</b> is wrong").arg (text (0));
             return false;
         }
-        if (mIpv6Supported)
-        {
-            if (!mInterfaceAddress6.isEmpty() &&
-                (QHostAddress (mInterfaceAddress6) == QHostAddress::AnyIPv6 ||
-                 QHostAddress (mInterfaceAddress6).protocol() != QAbstractSocket::IPv6Protocol))
+        if (m_data.m_interface.m_fIpv6Supported)
+        {
+            if (!m_data.m_interface.m_strInterfaceAddress6.isEmpty() &&
+                (QHostAddress (m_data.m_interface.m_strInterfaceAddress6) == QHostAddress::AnyIPv6 ||
+                 QHostAddress (m_data.m_interface.m_strInterfaceAddress6).protocol() != QAbstractSocket::IPv6Protocol))
             {
                 aWarning = VBoxGLSettingsNetwork::tr ("host IPv6 address of <b>%1</b> is wrong").arg (text (0));
@@ -150,26 +82,26 @@
 
     /* DHCP Server settings */
-    if (mDhcpServerEnabled)
-    {
-        if (QHostAddress (mDhcpServerAddress) == QHostAddress::Any ||
-            QHostAddress (mDhcpServerAddress).protocol() != QAbstractSocket::IPv4Protocol)
+    if (m_data.m_dhcpserver.m_fDhcpServerEnabled)
+    {
+        if (QHostAddress (m_data.m_dhcpserver.m_strDhcpServerAddress) == QHostAddress::Any ||
+            QHostAddress (m_data.m_dhcpserver.m_strDhcpServerAddress).protocol() != QAbstractSocket::IPv4Protocol)
         {
             aWarning = VBoxGLSettingsNetwork::tr ("DHCP server address of <b>%1</b> is wrong").arg (text (0));
             return false;
         }
-        if (QHostAddress (mDhcpServerMask) == QHostAddress::Any ||
-            QHostAddress (mDhcpServerMask).protocol() != QAbstractSocket::IPv4Protocol)
+        if (QHostAddress (m_data.m_dhcpserver.m_strDhcpServerMask) == QHostAddress::Any ||
+            QHostAddress (m_data.m_dhcpserver.m_strDhcpServerMask).protocol() != QAbstractSocket::IPv4Protocol)
         {
             aWarning = VBoxGLSettingsNetwork::tr ("DHCP server network mask of <b>%1</b> is wrong").arg (text (0));
             return false;
         }
-        if (QHostAddress (mDhcpLowerAddress) == QHostAddress::Any ||
-            QHostAddress (mDhcpLowerAddress).protocol() != QAbstractSocket::IPv4Protocol)
+        if (QHostAddress (m_data.m_dhcpserver.m_strDhcpLowerAddress) == QHostAddress::Any ||
+            QHostAddress (m_data.m_dhcpserver.m_strDhcpLowerAddress).protocol() != QAbstractSocket::IPv4Protocol)
         {
             aWarning = VBoxGLSettingsNetwork::tr ("DHCP lower address bound of <b>%1</b> is wrong").arg (text (0));
             return false;
         }
-        if (QHostAddress (mDhcpUpperAddress) == QHostAddress::Any ||
-            QHostAddress (mDhcpUpperAddress).protocol() != QAbstractSocket::IPv4Protocol)
+        if (QHostAddress (m_data.m_dhcpserver.m_strDhcpUpperAddress) == QHostAddress::Any ||
+            QHostAddress (m_data.m_dhcpserver.m_strDhcpUpperAddress).protocol() != QAbstractSocket::IPv4Protocol)
         {
             aWarning = VBoxGLSettingsNetwork::tr ("DHCP upper address bound of <b>%1</b> is wrong").arg (text (0));
@@ -182,4 +114,7 @@
 QString NetworkItem::updateInfo()
 {
+    /* Update text: */
+    setText(0, m_data.m_interface.m_strName);
+
     /* Update information label */
     QString hdr ("<tr><td><nobr>%1:&nbsp;</nobr></td>"
@@ -191,27 +126,27 @@
     /* Host-only Interface information */
     buffer = hdr.arg (VBoxGLSettingsNetwork::tr ("Adapter"))
-                .arg (mDhcpClientEnabled ? VBoxGLSettingsNetwork::tr ("Automatically configured", "interface")
-                                         : VBoxGLSettingsNetwork::tr ("Manually configured", "interface"));
+                .arg (m_data.m_interface.m_fDhcpClientEnabled ? VBoxGLSettingsNetwork::tr ("Automatically configured", "interface")
+                                                              : VBoxGLSettingsNetwork::tr ("Manually configured", "interface"));
     data += buffer;
     tip += buffer;
 
-    if (!mDhcpClientEnabled)
+    if (!m_data.m_interface.m_fDhcpClientEnabled)
     {
         buffer = sub.arg (VBoxGLSettingsNetwork::tr ("IPv4 Address"))
-                    .arg (mInterfaceAddress.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "address")
-                                                      : mInterfaceAddress) +
+                    .arg (m_data.m_interface.m_strInterfaceAddress.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "address")
+                                                                             : m_data.m_interface.m_strInterfaceAddress) +
                  sub.arg (VBoxGLSettingsNetwork::tr ("IPv4 Network Mask"))
-                    .arg (mInterfaceMask.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "mask")
-                                                   : mInterfaceMask);
+                    .arg (m_data.m_interface.m_strInterfaceMask.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "mask")
+                                                                          : m_data.m_interface.m_strInterfaceMask);
         tip += buffer;
 
-        if (mIpv6Supported)
+        if (m_data.m_interface.m_fIpv6Supported)
         {
             buffer = sub.arg (VBoxGLSettingsNetwork::tr ("IPv6 Address"))
-                        .arg (mInterfaceAddress6.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "address")
-                                                           : mInterfaceAddress6) +
+                        .arg (m_data.m_interface.m_strInterfaceAddress6.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "address")
+                                                                                  : m_data.m_interface.m_strInterfaceAddress6) +
                      sub.arg (VBoxGLSettingsNetwork::tr ("IPv6 Network Mask Length"))
-                        .arg (mInterfaceMaskLength6.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "length")
-                                                              : mInterfaceMaskLength6);
+                        .arg (m_data.m_interface.m_strInterfaceMaskLength6.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "length")
+                                                              : m_data.m_interface.m_strInterfaceMaskLength6);
             tip += buffer;
         }
@@ -220,23 +155,23 @@
     /* DHCP Server information */
     buffer = hdr.arg (VBoxGLSettingsNetwork::tr ("DHCP Server"))
-                .arg (mDhcpServerEnabled ? VBoxGLSettingsNetwork::tr ("Enabled", "server")
-                                         : VBoxGLSettingsNetwork::tr ("Disabled", "server"));
+                .arg (m_data.m_dhcpserver.m_fDhcpServerEnabled ? VBoxGLSettingsNetwork::tr ("Enabled", "server")
+                                                               : VBoxGLSettingsNetwork::tr ("Disabled", "server"));
     data += buffer;
     tip += buffer;
 
-    if (mDhcpServerEnabled)
+    if (m_data.m_dhcpserver.m_fDhcpServerEnabled)
     {
         buffer = sub.arg (VBoxGLSettingsNetwork::tr ("Address"))
-                    .arg (mDhcpServerAddress.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "address")
-                                                       : mDhcpServerAddress) +
+                    .arg (m_data.m_dhcpserver.m_strDhcpServerAddress.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "address")
+                                                                               : m_data.m_dhcpserver.m_strDhcpServerAddress) +
                  sub.arg (VBoxGLSettingsNetwork::tr ("Network Mask"))
-                    .arg (mDhcpServerMask.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "mask")
-                                                    : mDhcpServerMask) +
+                    .arg (m_data.m_dhcpserver.m_strDhcpServerMask.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "mask")
+                                                                            : m_data.m_dhcpserver.m_strDhcpServerMask) +
                  sub.arg (VBoxGLSettingsNetwork::tr ("Lower Bound"))
-                    .arg (mDhcpLowerAddress.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "bound")
-                                                      : mDhcpLowerAddress) +
+                    .arg (m_data.m_dhcpserver.m_strDhcpLowerAddress.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "bound")
+                                                                              : m_data.m_dhcpserver.m_strDhcpLowerAddress) +
                  sub.arg (VBoxGLSettingsNetwork::tr ("Upper Bound"))
-                    .arg (mDhcpUpperAddress.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "bound")
-                                                      : mDhcpUpperAddress);
+                    .arg (m_data.m_dhcpserver.m_strDhcpUpperAddress.isEmpty() ? VBoxGLSettingsNetwork::tr ("Not set", "bound")
+                                                                              : m_data.m_dhcpserver.m_strDhcpUpperAddress);
         tip += buffer;
     }
@@ -248,4 +183,5 @@
 
 VBoxGLSettingsNetwork::VBoxGLSettingsNetwork()
+    : m_fChanged(false)
 {
     /* Apply UI decorations */
@@ -257,5 +193,5 @@
         new QSpacerItem (0, 1, QSizePolicy::Expanding, QSizePolicy::Preferred);
     QGridLayout *mainLayout = static_cast <QGridLayout*> (layout());
-    mainLayout->addItem (shiftSpacer, 1, 4, 2);
+    mainLayout->addItem (shiftSpacer, 1, 4);
     static_cast <QHBoxLayout*> (mWtActions->layout())->addStretch();
 #endif
@@ -312,43 +248,202 @@
 }
 
-void VBoxGLSettingsNetwork::getFrom (const CSystemProperties &, const VBoxGlobalSettings &)
-{
-    NetworkItem *item = 0;
-    CHostNetworkInterfaceVector interfaces =
-        vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
-    for (CHostNetworkInterfaceVector::ConstIterator it = interfaces.begin();
-         it != interfaces.end(); ++ it)
-    {
-        if (it->GetInterfaceType() == KHostNetworkInterfaceType_HostOnly)
-        {
-            item = new NetworkItem();
-            item->getFromInterface (*it);
-            mTwInterfaces->addTopLevelItem (item);
-            mTwInterfaces->sortItems (0, Qt::AscendingOrder);
-        }
-    }
-
-    mTwInterfaces->setCurrentItem (item);
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsNetwork::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Load to cache: */
+    const CHostNetworkInterfaceVector &interfaces = vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
+    for (int iNetworkIndex = 0; iNetworkIndex < interfaces.size(); ++iNetworkIndex)
+    {
+        const CHostNetworkInterface &iface = interfaces[iNetworkIndex];
+        if (iface.GetInterfaceType() == KHostNetworkInterfaceType_HostOnly)
+        {
+            /* Initialization: */
+            CDHCPServer dhcp = vboxGlobal().virtualBox().FindDHCPServerByNetworkName(iface.GetNetworkName());
+            if (dhcp.isNull()) vboxGlobal().virtualBox().CreateDHCPServer(iface.GetNetworkName());
+            dhcp = vboxGlobal().virtualBox().FindDHCPServerByNetworkName(iface.GetNetworkName());
+            AssertMsg(!dhcp.isNull(), ("DHCP Server creation failed!\n"));
+            UIHostNetworkData data;
+            /* Host-only interface settings */
+            data.m_interface.m_strName = iface.GetName();
+            data.m_interface.m_fDhcpClientEnabled = iface.GetDhcpEnabled();
+            data.m_interface.m_strInterfaceAddress = iface.GetIPAddress();
+            data.m_interface.m_strInterfaceMask = iface.GetNetworkMask();
+            data.m_interface.m_fIpv6Supported = iface.GetIPV6Supported();
+            data.m_interface.m_strInterfaceAddress6 = iface.GetIPV6Address();
+            data.m_interface.m_strInterfaceMaskLength6 = QString::number(iface.GetIPV6NetworkMaskPrefixLength());
+            /* DHCP server settings: */
+            data.m_dhcpserver.m_fDhcpServerEnabled = dhcp.GetEnabled();
+            data.m_dhcpserver.m_strDhcpServerAddress = dhcp.GetIPAddress();
+            data.m_dhcpserver.m_strDhcpServerMask = dhcp.GetNetworkMask();
+            data.m_dhcpserver.m_strDhcpLowerAddress = dhcp.GetLowerIP();
+            data.m_dhcpserver.m_strDhcpUpperAddress = dhcp.GetUpperIP();
+            /* Cache: */
+            m_cache.m_items << data;
+        }
+    }
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsNetwork::getFromCache()
+{
+    /* Fetch from cache: */
+    for (int iNetworkIndex = 0; iNetworkIndex < m_cache.m_items.size(); ++iNetworkIndex)
+    {
+        const UIHostNetworkData &data = m_cache.m_items[iNetworkIndex];
+        NetworkItem *pItem = new NetworkItem;
+        pItem->fetchNetworkData(data);
+        mTwInterfaces->addTopLevelItem(pItem);
+    }
+    mTwInterfaces->setCurrentItem(mTwInterfaces->topLevelItem(0));
     updateCurrentItem();
-
 #ifdef Q_WS_MAC
-    int width = qMax (static_cast<QAbstractItemView*> (mTwInterfaces)
-        ->sizeHintForColumn (0) + 2 * mTwInterfaces->frameWidth() +
-        QApplication::style()->pixelMetric (QStyle::PM_ScrollBarExtent),
-        220);
-    mTwInterfaces->setFixedWidth (width);
-    mTwInterfaces->resizeColumnToContents (0);
+    int width = qMax(static_cast<QAbstractItemView*>(mTwInterfaces)->sizeHintForColumn(0) +
+                     2 * mTwInterfaces->frameWidth() + QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent),
+                     220);
+    mTwInterfaces->setFixedWidth(width);
+    mTwInterfaces->resizeColumnToContents(0);
 #endif /* Q_WS_MAC */
 }
 
-void VBoxGLSettingsNetwork::putBackTo (CSystemProperties &, VBoxGlobalSettings &)
-{
-    for (int i = 0; i < mTwInterfaces->topLevelItemCount(); ++ i)
-    {
-        NetworkItem *item =
-            static_cast <NetworkItem*> (mTwInterfaces->topLevelItem (i));
-        if (item->isChanged())
-            item->putBackToInterface();
-    }
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsNetwork::putToCache()
+{
+    /* Upload to cache: */
+    m_cache.m_items.clear();
+    for (int iNetworkIndex = 0; iNetworkIndex < mTwInterfaces->topLevelItemCount(); ++iNetworkIndex)
+    {
+        UIHostNetworkData data;
+        NetworkItem *pItem = static_cast<NetworkItem*>(mTwInterfaces->topLevelItem(iNetworkIndex));
+        pItem->uploadNetworkData(data);
+        m_cache.m_items << data;
+    }
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsNetwork::saveFromCacheTo(QVariant &data)
+{
+    /* Ensure settings were changed: */
+    if (!m_fChanged)
+        return;
+
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Save from cache: */
+    CVirtualBox &vbox = vboxGlobal().virtualBox();
+    CHost &host = vbox.GetHost();
+    const CHostNetworkInterfaceVector &interfaces = host.GetNetworkInterfaces();
+    /* Remove all the old interfaces first: */
+    for (int iNetworkIndex = 0; iNetworkIndex < interfaces.size(); ++iNetworkIndex)
+    {
+        /* Get iterated interface: */
+        const CHostNetworkInterface &iface = interfaces[iNetworkIndex];
+        if (iface.GetInterfaceType() == KHostNetworkInterfaceType_HostOnly)
+        {
+            /* Search for this interface's dhcp sserver: */
+            CDHCPServer &dhcp = vboxGlobal().virtualBox().FindDHCPServerByNetworkName(iface.GetNetworkName());
+            /* Delete it if its present: */
+            if (!dhcp.isNull())
+                vbox.RemoveDHCPServer(dhcp);
+            /* Delete interface finally: */
+            CProgress progress = host.RemoveHostOnlyNetworkInterface(iface.GetId());
+            if (host.isOk())
+            {
+                progress.WaitForCompletion(-1);
+                // TODO: Fix problem reporter!
+                //vboxProblem().showModalProgressDialog(progress, tr("Performing", "creating/removing host-only network"), this);
+                if (progress.GetResultCode() != 0)
+                    // TODO: Fix problem reporter!
+                    //vboxProblem().cannotRemoveHostInterface(progress, iface, this);
+                    AssertMsgFailed(("Failed to remove Host-only Network Adapter, result code is %d!\n", progress.GetResultCode()));
+            }
+            else
+                // TODO: Fix problem reporter!
+                //vboxProblem().cannotRemoveHostInterface(host, iface, this);
+                AssertMsgFailed(("Failed to remove Host-only Network Adapter!\n"));
+        }
+    }
+    /* Add all the new interfaces finally: */
+    for (int iNetworkIndex = 0; iNetworkIndex < m_cache.m_items.size(); ++iNetworkIndex)
+    {
+        /* Get iterated data: */
+        const UIHostNetworkData &data = m_cache.m_items[iNetworkIndex];
+        CHostNetworkInterface iface;
+        /* Create interface: */
+        CProgress progress = host.CreateHostOnlyNetworkInterface(iface);
+        if (host.isOk())
+        {
+            // TODO: Fix problem reporter!
+            //vboxProblem().showModalProgressDialog(progress, tr("Performing", "creating/removing host-only network"), this);
+            progress.WaitForCompletion(-1);
+            if (progress.GetResultCode() == 0)
+            {
+                /* Create DHCP server: */
+                CDHCPServer dhcp = vbox.FindDHCPServerByNetworkName(iface.GetNetworkName());
+                if (dhcp.isNull()) vbox.CreateDHCPServer(iface.GetNetworkName());
+                dhcp = vbox.FindDHCPServerByNetworkName(iface.GetNetworkName());
+                AssertMsg(!dhcp.isNull(), ("DHCP Server creation failed!\n"));
+                /* Host-only Interface configuring: */
+                if (data.m_interface.m_fDhcpClientEnabled)
+                {
+                    iface.EnableDynamicIpConfig();
+                }
+                else
+                {
+                    AssertMsg(data.m_interface.m_strInterfaceAddress.isEmpty() ||
+                              QHostAddress(data.m_interface.m_strInterfaceAddress).protocol() == QAbstractSocket::IPv4Protocol,
+                              ("Interface IPv4 address must be empty or IPv4-valid!\n"));
+                    AssertMsg(data.m_interface.m_strInterfaceMask.isEmpty() ||
+                              QHostAddress(data.m_interface.m_strInterfaceMask).protocol() == QAbstractSocket::IPv4Protocol,
+                              ("Interface IPv4 network mask must be empty or IPv4-valid!\n"));
+                    iface.EnableStaticIpConfig(data.m_interface.m_strInterfaceAddress, data.m_interface.m_strInterfaceMask);
+                    if (iface.GetIPV6Supported())
+                    {
+                        AssertMsg(data.m_interface.m_strInterfaceAddress6.isEmpty() ||
+                                  QHostAddress(data.m_interface.m_strInterfaceAddress6).protocol() == QAbstractSocket::IPv6Protocol,
+                                  ("Interface IPv6 address must be empty or IPv6-valid!\n"));
+                        iface.EnableStaticIpConfigV6(data.m_interface.m_strInterfaceAddress6, data.m_interface.m_strInterfaceMaskLength6.toULong());
+                    }
+                }
+                /* DHCP Server configuring: */
+                dhcp.SetEnabled(data.m_dhcpserver.m_fDhcpServerEnabled);
+//                AssertMsg(QHostAddress(data.m_dhcpserver.m_strDhcpServerAddress).protocol() == QAbstractSocket::IPv4Protocol,
+//                          ("DHCP Server IPv4 address must be IPv4-valid!\n"));
+//                AssertMsg(QHostAddress(data.m_dhcpserver.m_strDhcpServerMask).protocol() == QAbstractSocket::IPv4Protocol,
+//                          ("DHCP Server IPv4 network mask must be IPv4-valid!\n"));
+//                AssertMsg(QHostAddress(data.m_dhcpserver.m_strDhcpLowerAddress).protocol() == QAbstractSocket::IPv4Protocol,
+//                          ("DHCP Server IPv4 lower bound must be IPv4-valid!\n"));
+//                AssertMsg(QHostAddress(data.m_dhcpserver.m_strDhcpUpperAddress).protocol() == QAbstractSocket::IPv4Protocol,
+//                          ("DHCP Server IPv4 upper bound must be IPv4-valid!\n"));
+                if (QHostAddress(data.m_dhcpserver.m_strDhcpServerAddress).protocol() == QAbstractSocket::IPv4Protocol &&
+                    QHostAddress(data.m_dhcpserver.m_strDhcpServerMask).protocol() == QAbstractSocket::IPv4Protocol &&
+                    QHostAddress(data.m_dhcpserver.m_strDhcpLowerAddress).protocol() == QAbstractSocket::IPv4Protocol &&
+                    QHostAddress(data.m_dhcpserver.m_strDhcpUpperAddress).protocol() == QAbstractSocket::IPv4Protocol)
+                    dhcp.SetConfiguration(data.m_dhcpserver.m_strDhcpServerAddress, data.m_dhcpserver.m_strDhcpServerMask,
+                                          data.m_dhcpserver.m_strDhcpLowerAddress, data.m_dhcpserver.m_strDhcpUpperAddress);
+            }
+            else
+                // TODO: Fix problem reporter!
+                //vboxProblem().cannotCreateHostInterface(progress, this);
+                AssertMsgFailed(("Failed to create Host-only Network Adapter, result code is %d!\n", progress.GetResultCode()));
+        }
+        else
+            // TODO: Fix problem reporter!
+            //vboxProblem().cannotCreateHostInterface(host, this);
+            AssertMsgFailed(("Failed to create Host-only Network Adapter!\n"));
+    }
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
 }
 
@@ -389,73 +484,39 @@
 void VBoxGLSettingsNetwork::addInterface()
 {
-#if defined (Q_WS_WIN32)
-    /* Allow the started helper process to make itself the foreground window */
-    AllowSetForegroundWindow (ASFW_ANY);
-#endif
-    /* Creating interface */
-    CHostNetworkInterface iface;
-    CHost host = vboxGlobal().virtualBox().GetHost();
-    CProgress progress = host.CreateHostOnlyNetworkInterface (iface);
-    if (host.isOk())
-    {
-        vboxProblem().showModalProgressDialog (progress,
-            tr ("Performing", "creating/removing host-only network"), this);
-        if (progress.GetResultCode() == 0)
-        {
-            NetworkItem *item = new NetworkItem();
-            item->getFromInterface (iface);
-            mTwInterfaces->addTopLevelItem (item);
-            mTwInterfaces->sortItems (0, Qt::AscendingOrder);
-            mTwInterfaces->setCurrentItem (item);
-        }
-        else
-            vboxProblem().cannotCreateHostInterface (progress, this);
-    }
-    else
-        vboxProblem().cannotCreateHostInterface (host, this);
-#if defined (Q_WS_WIN32)
-    /* Allow the started helper process to make itself the foreground window */
-    AllowSetForegroundWindow (ASFW_ANY);
-#endif
+    /* Creating interface item: */
+    NetworkItem *pItem = new NetworkItem;
+    /* Fill item's data: */
+    UIHostNetworkData data;
+    /* Interface data: */
+    // TODO: Make unique name!
+    data.m_interface.m_strName = tr("New Host-Only Interface");
+    data.m_interface.m_fDhcpClientEnabled = true;
+    data.m_interface.m_fIpv6Supported = false;
+    /* DHCP data: */
+    data.m_dhcpserver.m_fDhcpServerEnabled = false;
+    /* Fetch item with data: */
+    pItem->fetchNetworkData(data);
+    /* Add new top-level item: */
+    mTwInterfaces->addTopLevelItem(pItem);
+    mTwInterfaces->sortItems(0, Qt::AscendingOrder);
+    mTwInterfaces->setCurrentItem(pItem);
+    /* Mark dialog as edited: */
+    m_fChanged = true;
 }
 
 void VBoxGLSettingsNetwork::remInterface()
 {
-#if defined (Q_WS_WIN32)
-    /* Allow the started helper process to make itself the foreground window */
-    AllowSetForegroundWindow (ASFW_ANY);
-#endif
-    /* Check interface presence & name */
-    NetworkItem *item = static_cast <NetworkItem*> (mTwInterfaces->currentItem());
-    AssertMsg (item, ("Current item should be selected!\n"));
-    QString name (item->name());
-
-    /* Asking user about deleting selected network interface */
-    if (vboxProblem().confirmDeletingHostInterface (name, this) ==
-        QIMessageBox::Cancel) return;
-
-    /* Removing interface */
-    CHost host = vboxGlobal().virtualBox().GetHost();
-    CHostNetworkInterface iface = host.FindHostNetworkInterfaceByName (name);
-    if (!iface.isNull())
-    {
-        /* Delete interface */
-        CProgress progress = host.RemoveHostOnlyNetworkInterface (iface.GetId());
-        if (host.isOk())
-        {
-            vboxProblem().showModalProgressDialog (progress,
-                tr ("Performing", "creating/removing host-only network"), this);
-            if (progress.GetResultCode() == 0)
-                delete item;
-            else
-                vboxProblem().cannotRemoveHostInterface (progress, iface, this);
-        }
-    }
-    if (!host.isOk())
-        vboxProblem().cannotRemoveHostInterface (host, iface, this);
-#if defined (Q_WS_WIN32)
-    /* Allow the started helper process to make itself the foreground window */
-    AllowSetForegroundWindow (ASFW_ANY);
-#endif
+    /* Get interface item: */
+    NetworkItem *pItem = static_cast<NetworkItem*>(mTwInterfaces->currentItem());
+    AssertMsg(pItem, ("Current item should present!\n"));
+    /* Get interface name: */
+    QString strInterfaceName(pItem->name());
+    /* Asking user about deleting selected network interface: */
+    if (vboxProblem().confirmDeletingHostInterface(strInterfaceName, this) == QIMessageBox::Cancel)
+        return;
+    /* Removing interface: */
+    delete pItem;
+    /* Mark dialog as edited: */
+    m_fChanged = true;
 }
 
@@ -465,5 +526,4 @@
     NetworkItem *item = static_cast <NetworkItem*> (mTwInterfaces->currentItem());
     AssertMsg (item, ("Current item should be selected!\n"));
-
     /* Edit current item data */
     VBoxGLSettingsNetworkDetails details (this);
@@ -472,10 +532,10 @@
     {
         details.putBackToItem();
-        item->setChanged (true);
         item->updateInfo();
     }
-
     updateCurrentItem();
     mValidator->revalidate();
+    /* Mark dialog as edited: */
+    m_fChanged = true;
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -23,4 +23,41 @@
 #include "VBoxGLSettingsNetwork.gen.h"
 
+/* Host interface data: */
+struct UIHostInterfaceData
+{
+    /* Host-only Interface: */
+    QString m_strName;
+    bool m_fDhcpClientEnabled;
+    QString m_strInterfaceAddress;
+    QString m_strInterfaceMask;
+    bool m_fIpv6Supported;
+    QString m_strInterfaceAddress6;
+    QString m_strInterfaceMaskLength6;
+};
+
+/* DHCP server data: */
+struct UIDHCPServerData
+{
+    /* DHCP Server */
+    bool m_fDhcpServerEnabled;
+    QString m_strDhcpServerAddress;
+    QString m_strDhcpServerMask;
+    QString m_strDhcpLowerAddress;
+    QString m_strDhcpUpperAddress;
+};
+
+/* Global network data: */
+struct UIHostNetworkData
+{
+    UIHostInterfaceData m_interface;
+    UIDHCPServerData m_dhcpserver;
+};
+
+/* Global settings / Network page / Cache: */
+struct UISettingsCacheGlobalNetwork
+{
+    QList<UIHostNetworkData> m_items;
+};
+
 class NetworkItem : public QTreeWidgetItem
 {
@@ -29,6 +66,6 @@
     NetworkItem();
 
-    void getFromInterface (const CHostNetworkInterface &aInterface);
-    void putBackToInterface();
+    void fetchNetworkData(const UIHostNetworkData &data);
+    void uploadNetworkData(UIHostNetworkData &data);
 
     bool revalidate (QString &aWarning, QString &aTitle);
@@ -36,63 +73,41 @@
     QString updateInfo();
 
-    /* Common getters */
-    bool isChanged() const { return mChanged; }
+    /* Page getters */
+    QString name() const { return m_data.m_interface.m_strName; }
+    bool isDhcpClientEnabled() const { return m_data.m_interface.m_fDhcpClientEnabled; }
+    QString interfaceAddress() const { return m_data.m_interface.m_strInterfaceAddress; }
+    QString interfaceMask() const { return m_data.m_interface.m_strInterfaceMask; }
+    bool isIpv6Supported() const { return m_data.m_interface.m_fIpv6Supported; }
+    QString interfaceAddress6() const { return m_data.m_interface.m_strInterfaceAddress6; }
+    QString interfaceMaskLength6() const { return m_data.m_interface.m_strInterfaceMaskLength6; }
 
-    /* Common setters */
-    void setChanged (bool aChanged) { mChanged = aChanged; }
-
-    /* Page getters */
-    QString name() const { return mName; }
-    bool isDhcpClientEnabled() const { return mDhcpClientEnabled; }
-    QString interfaceAddress() const { return mInterfaceAddress; }
-    QString interfaceMask() const { return mInterfaceMask; }
-    bool isIpv6Supported() const { return mIpv6Supported; }
-    QString interfaceAddress6() const { return mInterfaceAddress6; }
-    QString interfaceMaskLength6() const { return mInterfaceMaskLength6; }
-
-    bool isDhcpServerEnabled() const { return mDhcpServerEnabled; }
-    QString dhcpServerAddress() const { return mDhcpServerAddress; }
-    QString dhcpServerMask() const { return mDhcpServerMask; }
-    QString dhcpLowerAddress() const { return mDhcpLowerAddress; }
-    QString dhcpUpperAddress() const { return mDhcpUpperAddress; }
+    bool isDhcpServerEnabled() const { return m_data.m_dhcpserver.m_fDhcpServerEnabled; }
+    QString dhcpServerAddress() const { return m_data.m_dhcpserver.m_strDhcpServerAddress; }
+    QString dhcpServerMask() const { return m_data.m_dhcpserver.m_strDhcpServerMask; }
+    QString dhcpLowerAddress() const { return m_data.m_dhcpserver.m_strDhcpLowerAddress; }
+    QString dhcpUpperAddress() const { return m_data.m_dhcpserver.m_strDhcpUpperAddress; }
 
     /* Page setters */
-    void setDhcpClientEnabled (bool aEnabled) { mDhcpClientEnabled = aEnabled; }
-    void setInterfaceAddress (const QString &aValue) { mInterfaceAddress = aValue; }
-    void setInterfaceMask (const QString &aValue) { mInterfaceMask = aValue; }
-    void setIp6Supported (bool aSupported) { mIpv6Supported = aSupported; }
-    void setInterfaceAddress6 (const QString &aValue) { mInterfaceAddress6 = aValue; }
-    void setInterfaceMaskLength6 (const QString &aValue) { mInterfaceMaskLength6 = aValue; }
+    void setDhcpClientEnabled (bool aEnabled) { m_data.m_interface.m_fDhcpClientEnabled = aEnabled; }
+    void setInterfaceAddress (const QString &aValue) { m_data.m_interface.m_strInterfaceAddress = aValue; }
+    void setInterfaceMask (const QString &aValue) { m_data.m_interface.m_strInterfaceMask = aValue; }
+    void setIp6Supported (bool aSupported) { m_data.m_interface.m_fIpv6Supported = aSupported; }
+    void setInterfaceAddress6 (const QString &aValue) { m_data.m_interface.m_strInterfaceAddress6 = aValue; }
+    void setInterfaceMaskLength6 (const QString &aValue) { m_data.m_interface.m_strInterfaceMaskLength6 = aValue; }
 
-    void setDhcpServerEnabled (bool aEnabled) { mDhcpServerEnabled = aEnabled; }
-    void setDhcpServerAddress (const QString &aValue) { mDhcpServerAddress = aValue; }
-    void setDhcpServerMask (const QString &aValue) { mDhcpServerMask = aValue; }
-    void setDhcpLowerAddress (const QString &aValue) { mDhcpLowerAddress = aValue; }
-    void setDhcpUpperAddress (const QString &aValue) { mDhcpUpperAddress = aValue; }
+    void setDhcpServerEnabled (bool aEnabled) { m_data.m_dhcpserver.m_fDhcpServerEnabled = aEnabled; }
+    void setDhcpServerAddress (const QString &aValue) { m_data.m_dhcpserver.m_strDhcpServerAddress = aValue; }
+    void setDhcpServerMask (const QString &aValue) { m_data.m_dhcpserver.m_strDhcpServerMask = aValue; }
+    void setDhcpLowerAddress (const QString &aValue) { m_data.m_dhcpserver.m_strDhcpLowerAddress = aValue; }
+    void setDhcpUpperAddress (const QString &aValue) { m_data.m_dhcpserver.m_strDhcpUpperAddress = aValue; }
 
 private:
 
-    /* Common */
-    CHostNetworkInterface mInterface;
-    bool mChanged;
-
-    /* Host-only Interface */
-    QString mName;
-    bool mDhcpClientEnabled;
-    QString mInterfaceAddress;
-    QString mInterfaceMask;
-    bool mIpv6Supported;
-    QString mInterfaceAddress6;
-    QString mInterfaceMaskLength6;
-
-    /* DHCP Server */
-    bool mDhcpServerEnabled;
-    QString mDhcpServerAddress;
-    QString mDhcpServerMask;
-    QString mDhcpLowerAddress;
-    QString mDhcpUpperAddress;
+    /* Network data: */
+    UIHostNetworkData m_data;
 };
 
-class VBoxGLSettingsNetwork : public UISettingsPage,
+/* Global settings / Network page: */
+class VBoxGLSettingsNetwork : public UISettingsPageGlobal,
                               public Ui::VBoxGLSettingsNetwork
 {
@@ -105,8 +120,17 @@
 protected:
 
-    void getFrom (const CSystemProperties &aProps,
-                  const VBoxGlobalSettings &aGs);
-    void putBackTo (CSystemProperties &aProps,
-                    VBoxGlobalSettings &aGs);
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -132,4 +156,9 @@
 
     QIWidgetValidator *mValidator;
+
+    bool m_fChanged;
+
+    /* Cache: */
+    UISettingsCacheGlobalNetwork m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.ui
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.ui	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsNetwork.ui	(revision 33631)
@@ -4,5 +4,5 @@
  VBox frontends: Qt4 GUI (&quot;VirtualBox&quot;):
 
-     Copyright (C) 2009 Oracle Corporation
+     Copyright (C) 2009-2010 Oracle Corporation
 
      This file is part of VirtualBox Open Source Edition (OSE), as
@@ -25,5 +25,5 @@
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <item row="0" column="0">
+   <item row="0" column="0" rowspan="4">
     <spacer>
      <property name="orientation">
@@ -51,34 +51,7 @@
     </widget>
    </item>
-   <item row="1" column="2" rowspan="2">
-    <widget class="QTreeWidget" name="mTwInterfaces">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="minimumSize">
-      <size>
-       <width>0</width>
-       <height>150</height>
-      </size>
-     </property>
-     <property name="whatsThis">
-      <string>Lists all available host-only networks.</string>
-     </property>
-     <property name="rootIsDecorated">
-      <bool>false</bool>
-     </property>
-     <column>
-      <property name="text">
-       <string>Name</string>
-      </property>
-     </column>
-    </widget>
-   </item>
-   <item row="1" column="3">
-    <widget class="QWidget" name="mWtActions">
-     <layout class="QHBoxLayout">
+   <item row="1" column="2">
+    <widget class="QWidget" native="1" name="m_pWidNetwork" >
+     <layout class="QHBoxLayout" >
       <property name="leftMargin" >
        <number>0</number>
@@ -94,6 +67,33 @@
       </property>
       <property name="spacing" >
-       <number>0</number>
+       <number>1</number>
       </property>
+      <item>
+       <widget class="QTreeWidget" name="mTwInterfaces">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>150</height>
+         </size>
+        </property>
+        <property name="whatsThis">
+         <string>Lists all available host-only networks.</string>
+        </property>
+        <property name="rootIsDecorated">
+         <bool>false</bool>
+        </property>
+        <column>
+         <property name="text">
+          <string>Name</string>
+         </property>
+        </column>
+       </widget>
+      </item>
       <item>
        <widget class="UIToolBar" name="mTbActions">
@@ -106,5 +106,5 @@
     </widget>
    </item>
-   <item row="2" column="1">
+   <item row="1" column="1" rowspan="2">
     <spacer>
      <property name="orientation">
@@ -122,21 +122,5 @@
     </spacer>
    </item>
-   <item row="2" column="3">
-    <spacer>
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeType">
-      <enum>QSizePolicy::Expanding</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>10</width>
-       <height>0</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="3" column="2" colspan="2">
+   <item row="2" column="2" colspan="2">
     <widget class="QLabel" name="mLbInfo">
      <property name="sizePolicy">
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsUpdate.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsUpdate.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsUpdate.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -39,31 +39,70 @@
 }
 
-void VBoxGLSettingsUpdate::getFrom (const CSystemProperties &, const VBoxGlobalSettings &)
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsUpdate::loadToCacheFrom(QVariant &data)
 {
-    VBoxUpdateData data (vboxGlobal().virtualBox().GetExtraData (VBoxDefs::GUI_UpdateDate));
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
 
-    mCbCheck->setChecked (!data.isNoNeedToCheck());
+    /* Fill internal variables with corresponding values: */
+    VBoxUpdateData updateData(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateDate));
+    m_cache.m_fCheckEnabled = !updateData.isNoNeedToCheck();
+    m_cache.m_periodIndex = updateData.periodIndex();
+    m_cache.m_branchIndex = updateData.branchIndex();
+    m_cache.m_strDate = updateData.date();
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsUpdate::getFromCache()
+{
+    /* Apply internal variables data to QWidget(s): */
+    mCbCheck->setChecked(m_cache.m_fCheckEnabled);
     if (mCbCheck->isChecked())
     {
-        mCbOncePer->setCurrentIndex (data.periodIndex());
-        if (data.branchIndex() == VBoxUpdateData::BranchWithBetas)
-            mRbWithBetas->setChecked (true);
-        else if (data.branchIndex() == VBoxUpdateData::BranchAllRelease)
-            mRbAllRelease->setChecked (true);
+        mCbOncePer->setCurrentIndex(m_cache.m_periodIndex);
+        if (m_cache.m_branchIndex == VBoxUpdateData::BranchWithBetas)
+            mRbWithBetas->setChecked(true);
+        else if (m_cache.m_branchIndex == VBoxUpdateData::BranchAllRelease)
+            mRbAllRelease->setChecked(true);
         else
-            mRbStable->setChecked (true);
+            mRbStable->setChecked(true);
     }
-    mTxDate->setText (data.date());
+    mTxDate->setText(m_cache.m_strDate);
 
+    /* Reset settings altering flag: */
     mSettingsChanged = false;
 }
 
-void VBoxGLSettingsUpdate::putBackTo (CSystemProperties &, VBoxGlobalSettings &)
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxGLSettingsUpdate::putToCache()
 {
+    /* Gather internal variables data from QWidget(s): */
+    m_cache.m_periodIndex = periodType();
+    m_cache.m_branchIndex = branchType();
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxGLSettingsUpdate::saveFromCacheTo(QVariant &data)
+{
+    /* Test settings altering flag: */
     if (!mSettingsChanged)
         return;
 
-    VBoxUpdateData newData (periodType(), branchType());
-    vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateDate, newData.data());
+    /* Fetch data to properties & settings: */
+    UISettingsPageGlobal::fetchData(data);
+
+    /* Gather corresponding values from internal variables: */
+    VBoxUpdateData newData(m_cache.m_periodIndex, m_cache.m_branchIndex);
+    vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_UpdateDate, newData.data());
+
+    /* Upload properties & settings to data: */
+    UISettingsPageGlobal::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsUpdate.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsUpdate.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/global/VBoxGLSettingsUpdate.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -24,5 +24,15 @@
 #include "VBoxUpdateDlg.h"
 
-class VBoxGLSettingsUpdate : public UISettingsPage,
+/* Global settings / Update page / Cache: */
+struct UISettingsCacheGlobalUpdate
+{
+    bool m_fCheckEnabled;
+    VBoxUpdateData::PeriodType m_periodIndex;
+    VBoxUpdateData::BranchType m_branchIndex;
+    QString m_strDate;
+};
+
+/* Global settings / Update page: */
+class VBoxGLSettingsUpdate : public UISettingsPageGlobal,
                              public Ui::VBoxGLSettingsUpdate
 {
@@ -35,8 +45,17 @@
 protected:
 
-    void getFrom (const CSystemProperties &aProps,
-                  const VBoxGlobalSettings &aGs);
-    void putBackTo (CSystemProperties &aProps,
-                    VBoxGlobalSettings &aGs);
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setOrderAfter (QWidget *aWidget);
@@ -59,4 +78,7 @@
     bool mSettingsChanged;
     QRadioButton *mLastChosen;
+
+    /* Cache: */
+    UISettingsCacheGlobalUpdate m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsAudio.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsAudio.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsAudio.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -29,23 +29,56 @@
 }
 
-void VBoxVMSettingsAudio::getFrom (const CMachine &aMachine)
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsAudio::loadToCacheFrom(QVariant &data)
 {
-    mMachine = aMachine;
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
 
-    CAudioAdapter audio = aMachine.GetAudioAdapter();
-    mGbAudio->setChecked (audio.GetEnabled());
-    mCbAudioDriver->setCurrentIndex (mCbAudioDriver->
-        findText (vboxGlobal().toString (audio.GetAudioDriver())));
-    mCbAudioController->setCurrentIndex (mCbAudioController->
-        findText (vboxGlobal().toString (audio.GetAudioController())));
+    /* Fill internal variables with corresponding values: */
+    const CAudioAdapter &audio = m_machine.GetAudioAdapter();
+    m_cache.m_fAudioEnabled = audio.GetEnabled();
+    m_cache.m_audioDriverType = audio.GetAudioDriver();
+    m_cache.m_audioControllerType = audio.GetAudioController();
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
-void VBoxVMSettingsAudio::putBackTo()
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsAudio::getFromCache()
 {
-    CAudioAdapter audio = mMachine.GetAudioAdapter();
-    audio.SetAudioDriver (vboxGlobal().toAudioDriverType (mCbAudioDriver->currentText()));
-    audio.SetAudioController (vboxGlobal().toAudioControllerType (mCbAudioController->currentText()));
-    audio.SetEnabled (mGbAudio->isChecked());
-    AssertWrapperOk (audio);
+    /* Apply internal variables data to QWidget(s): */
+    mGbAudio->setChecked(m_cache.m_fAudioEnabled);
+    mCbAudioDriver->setCurrentIndex(mCbAudioDriver->findText(vboxGlobal().toString(m_cache.m_audioDriverType)));
+    mCbAudioController->setCurrentIndex(mCbAudioController->findText(vboxGlobal().toString(m_cache.m_audioControllerType)));
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsAudio::putToCache()
+{
+    /* Gather internal variables data from QWidget(s): */
+    m_cache.m_fAudioEnabled = mGbAudio->isChecked();
+    m_cache.m_audioDriverType = vboxGlobal().toAudioDriverType(mCbAudioDriver->currentText());
+    m_cache.m_audioControllerType = vboxGlobal().toAudioControllerType(mCbAudioController->currentText());
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsAudio::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Gather corresponding values from internal variables: */
+    CAudioAdapter &audio = m_machine.GetAudioAdapter();
+    audio.SetEnabled(m_cache.m_fAudioEnabled);
+    audio.SetAudioDriver(m_cache.m_audioDriverType);
+    audio.SetAudioController(m_cache.m_audioControllerType);
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsAudio.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsAudio.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsAudio.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -24,5 +24,14 @@
 #include "COMDefs.h"
 
-class VBoxVMSettingsAudio : public UISettingsPage,
+/* Machine settings / Audio page / Cache: */
+struct UISettingsCacheMachineAudio
+{
+    bool m_fAudioEnabled;
+    KAudioDriverType m_audioDriverType;
+    KAudioControllerType m_audioControllerType;
+};
+
+/* Machine settings / Audio page: */
+class VBoxVMSettingsAudio : public UISettingsPageMachine,
                             public Ui::VBoxVMSettingsAudio
 {
@@ -35,6 +44,17 @@
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setOrderAfter (QWidget *aWidget);
@@ -46,5 +66,6 @@
     void prepareComboboxes();
 
-    CMachine mMachine;
+    /* Cache: */
+    UISettingsCacheMachineAudio m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsDisplay.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsDisplay.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsDisplay.cpp	(revision 33631)
@@ -86,5 +86,5 @@
     mSlMemory->setMaximum (m_maxVRAMVisible);
     mSlMemory->setSnappingEnabled (true);
-    quint64 needMBytes = VBoxGlobal::requiredVideoMemory (&mMachine) / _1M;
+    quint64 needMBytes = VBoxGlobal::requiredVideoMemory (&m_machine) / _1M;
     mSlMemory->setErrorHint (0, 1);
     mSlMemory->setWarningHint (1, needMBytes);
@@ -108,6 +108,4 @@
     mCbVRDE->setChecked (false);
 
-    mCb3D->setEnabled (false);
-
 #ifndef VBOX_WITH_VIDEOHWACCEL
     mCb2DVideo->setVisible (false);
@@ -140,76 +138,111 @@
 #endif
 
-void VBoxVMSettingsDisplay::getFrom (const CMachine &aMachine)
-{
-    mMachine = aMachine;
-
-    int currentSize = mMachine.GetVRAMSize();
-    m_initialVRAM = RT_MIN(currentSize, m_maxVRAM);
-
-    /* Memory Size */
-    mSlMemory->setValue (currentSize);
-
-    /* Monitors Count */
-    mSlMonitors->setValue (mMachine.GetMonitorCount());
-
-    /* 3D Acceleration */
-    bool isAccelerationSupported = vboxGlobal().virtualBox().GetHost()
-                                   .GetAcceleration3DAvailable();
-    mCb3D->setEnabled (isAccelerationSupported);
-    mCb3D->setChecked (mMachine.GetAccelerate3DEnabled());
-
-    /* must come _before_ setting the initial memory value */
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsDisplay::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Fill internal variables with corresponding values: */
+    m_cache.m_iCurrentVRAM = m_machine.GetVRAMSize();
+    m_cache.m_cMonitorCount = m_machine.GetMonitorCount();
+    m_cache.m_f3dAccelerationSupported = vboxGlobal().virtualBox().GetHost().GetAcceleration3DAvailable();
+    m_cache.m_f3dAccelerationEnabled = m_machine.GetAccelerate3DEnabled();
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    m_cache.m_f2dAccelerationSupported = VBoxGlobal::isAcceleration2DVideoAvailable();
+    m_cache.m_f2dAccelerationEnabled = m_machine.GetAccelerate2DVideoEnabled();
+#endif
+    CVRDEServer &vrdeServer = m_machine.GetVRDEServer();
+    m_cache.m_fVRDEServerSupported = !vrdeServer.isNull();
+    m_cache.m_fVRDEServerEnabled = m_cache.m_fVRDEServerSupported && vrdeServer.GetEnabled();
+    m_cache.m_strVRDEPort = vrdeServer.GetVRDEProperty("TCP/Ports");
+    m_cache.m_iVRDEAuthType = vrdeServer.GetAuthType();
+    m_cache.m_uVRDETimeout = vrdeServer.GetAuthTimeout();
+    m_cache.m_fMultipleConnectionsAllowed = vrdeServer.GetAllowMultiConnection();
+
+    /* Other variables: */
+    m_initialVRAM = RT_MIN(m_cache.m_iCurrentVRAM, m_maxVRAM);
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsDisplay::getFromCache()
+{
+    /* Apply internal variables data to QWidget(s): */
+    mSlMonitors->setValue(m_cache.m_cMonitorCount);
+    mCb3D->setEnabled(m_cache.m_f3dAccelerationSupported);
+    mCb3D->setChecked(m_cache.m_f3dAccelerationEnabled);
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    mCb2DVideo->setEnabled(m_cache.m_f2dAccelerationSupported);
+    mCb2DVideo->setChecked(m_cache.m_f2dAccelerationEnabled);
+#endif
     checkVRAMRequirements();
-
-#ifdef VBOX_WITH_VIDEOHWACCEL
-    mCb2DVideo->setEnabled (VBoxGlobal::isAcceleration2DVideoAvailable());
-    mCb2DVideo->setChecked (   mMachine.GetAccelerate2DVideoEnabled()
-                            && VBoxGlobal::isAcceleration2DVideoAvailable());
-#endif
-
-    /* Remote Desktop Settings */
-    CVRDEServer vrdeServer = mMachine.GetVRDEServer();
+    mSlMemory->setValue(m_cache.m_iCurrentVRAM);
+    if (m_cache.m_fVRDEServerSupported)
+    {
+        mCbVRDE->setChecked(m_cache.m_fVRDEServerEnabled);
+        mLeVRDEPort->setText(m_cache.m_strVRDEPort);
+        mCbVRDEMethod->setCurrentIndex(mCbVRDEMethod->findText(vboxGlobal().toString(m_cache.m_iVRDEAuthType)));
+        mLeVRDETimeout->setText(QString::number(m_cache.m_uVRDETimeout));
+        mCbMultipleConn->setChecked(m_cache.m_fMultipleConnectionsAllowed);
+    }
+    else
+        mTwDisplay->removeTab(1);
+
+    /* Revalidate if possible: */
+    if (mValidator) mValidator->revalidate();
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsDisplay::putToCache()
+{
+    /* Gather internal variables data from QWidget(s): */
+    m_cache.m_iCurrentVRAM = mSlMemory->value();
+    m_cache.m_cMonitorCount = mSlMonitors->value();
+    m_cache.m_f3dAccelerationEnabled = mCb3D->isChecked();
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    m_cache.m_f2dAccelerationEnabled = mCb2DVideo->isChecked();
+#endif
+    if (m_cache.m_fVRDEServerSupported)
+    {
+        m_cache.m_fVRDEServerEnabled = mCbVRDE->isChecked();
+        m_cache.m_strVRDEPort = mLeVRDEPort->text();
+        m_cache.m_iVRDEAuthType = vboxGlobal().toAuthType(mCbVRDEMethod->currentText());
+        m_cache.m_uVRDETimeout = mLeVRDETimeout->text().toULong();
+        m_cache.m_fMultipleConnectionsAllowed = mCbMultipleConn->isChecked();
+    }
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsDisplay::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Gather corresponding values from internal variables: */
+    m_machine.SetVRAMSize(m_cache.m_iCurrentVRAM);
+    m_machine.SetMonitorCount(m_cache.m_cMonitorCount);
+    m_machine.SetAccelerate3DEnabled(m_cache.m_f3dAccelerationEnabled);
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    m_machine.SetAccelerate2DVideoEnabled(m_cache.m_f2dAccelerationEnabled);
+#endif
+    CVRDEServer &vrdeServer = m_machine.GetVRDEServer();
     if (!vrdeServer.isNull())
     {
-        mCbVRDE->setChecked (vrdeServer.GetEnabled());
-        mLeVRDEPort->setText (vrdeServer.GetVRDEProperty("TCP/Ports"));
-        mCbVRDEMethod->setCurrentIndex (mCbVRDEMethod->
-                                        findText (vboxGlobal().toString (vrdeServer.GetAuthType())));
-        mLeVRDETimeout->setText (QString::number (vrdeServer.GetAuthTimeout()));
-        mCbMultipleConn->setChecked(vrdeServer.GetAllowMultiConnection());
-    }
-    else
-    {
-        vboxProblem().cannotLoadMachineSettings (mMachine, false /* strict */);
-        mTwDisplay->setTabEnabled (1, false);
-    }
-}
-
-void VBoxVMSettingsDisplay::putBackTo()
-{
-    /* Memory Size */
-    mMachine.SetVRAMSize (mSlMemory->value());
-
-    /* Monitors Count */
-    mMachine.SetMonitorCount (mSlMonitors->value());
-
-    /* 3D Acceleration */
-    mMachine.SetAccelerate3DEnabled (mCb3D->isChecked());
-
-#ifdef VBOX_WITH_VIDEOHWACCEL
-    /* 2D Video Acceleration */
-    mMachine.SetAccelerate2DVideoEnabled (mCb2DVideo->isChecked());
-#endif
-
-    /* VRDE Settings */
-    CVRDEServer vrdeServer = mMachine.GetVRDEServer();
-    if (!vrdeServer.isNull())
-    {
-        vrdeServer.SetEnabled (mCbVRDE->isChecked());
-        vrdeServer.SetVRDEProperty("TCP/Ports", mLeVRDEPort->text());
-        vrdeServer.SetAuthType (vboxGlobal().toAuthType (mCbVRDEMethod->currentText()));
-        vrdeServer.SetAuthTimeout (mLeVRDETimeout->text().toULong());
-        vrdeServer.SetAllowMultiConnection(mCbMultipleConn->isChecked());
-    }
+        vrdeServer.SetEnabled(m_cache.m_fVRDEServerEnabled);
+        vrdeServer.SetVRDEProperty("TCP/Ports", m_cache.m_strVRDEPort);
+        vrdeServer.SetAuthType(m_cache.m_iVRDEAuthType);
+        vrdeServer.SetAuthTimeout(m_cache.m_uVRDETimeout);
+        vrdeServer.SetAllowMultiConnection(m_cache.m_fMultipleConnectionsAllowed);
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
@@ -234,5 +267,5 @@
 {
     /* Video RAM amount test */
-    quint64 needBytes = VBoxGlobal::requiredVideoMemory (&mMachine, mSlMonitors->value());
+    quint64 needBytes = VBoxGlobal::requiredVideoMemory (&m_machine, mSlMonitors->value());
     if ((quint64) mSlMemory->value() * _1M < needBytes)
     {
@@ -260,5 +293,5 @@
     {
         int cVal = mSlMonitors->value();
-        needBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(&mMachine, cVal);
+        needBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(&m_machine, cVal);
         needBytes = RT_MAX(needBytes, 128 * _1M);
         needBytes = RT_MIN(needBytes, 256 * _1M);
@@ -347,5 +380,5 @@
     int cVal = mSlMonitors->value();
     /* The memory requirements have changed too. */
-    quint64 needMBytes = VBoxGlobal::requiredVideoMemory (&mMachine, cVal) / _1M;
+    quint64 needMBytes = VBoxGlobal::requiredVideoMemory (&m_machine, cVal) / _1M;
     /* Limit the maximum memory to save careless users from setting useless big values */
 #ifdef VBOX_WITH_VIDEOHWACCEL
@@ -358,5 +391,5 @@
     if (m_bWddmMode && mCb3D->isChecked())
     {
-        needMBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(&mMachine, cVal) / _1M;
+        needMBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(&m_machine, cVal) / _1M;
         needMBytes = RT_MAX(needMBytes, 128);
         needMBytes = RT_MIN(needMBytes, 256);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsDisplay.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsDisplay.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsDisplay.h	(revision 33631)
@@ -24,5 +24,23 @@
 #include "VBoxVMSettingsDisplay.gen.h"
 
-class VBoxVMSettingsDisplay : public UISettingsPage,
+/* Machine settings / Display page / Cache: */
+struct UISettingsCacheMachineDisplay
+{
+    int m_iCurrentVRAM;
+    int m_cMonitorCount;
+    bool m_f3dAccelerationSupported;
+    bool m_f3dAccelerationEnabled;
+    bool m_f2dAccelerationSupported;
+    bool m_f2dAccelerationEnabled;
+    bool m_fVRDEServerSupported;
+    bool m_fVRDEServerEnabled;
+    QString m_strVRDEPort;
+    KAuthType m_iVRDEAuthType;
+    ulong m_uVRDETimeout;
+    bool m_fMultipleConnectionsAllowed;
+};
+
+/* Machine settings / Display page: */
+class VBoxVMSettingsDisplay : public UISettingsPageMachine,
                               public Ui::VBoxVMSettingsDisplay
 {
@@ -43,6 +61,17 @@
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -64,5 +93,4 @@
     void checkVRAMRequirements();
 
-    CMachine mMachine;
     QIWidgetValidator *mValidator;
 
@@ -77,7 +105,10 @@
     int m_initialVRAM;
 #ifdef VBOX_WITH_CRHGSMI
-    /* specifies whether the guest os is wddm-capable */
+    /* Specifies whether the guest os is wddm-capable: */
     bool m_bWddmMode;
 #endif
+
+    /* Cache: */
+    UISettingsCacheMachineDisplay m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsGeneral.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsGeneral.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsGeneral.cpp	(revision 33631)
@@ -63,83 +63,89 @@
 bool VBoxVMSettingsGeneral::isWddmSupportedForOSType() const
 {
-    const QString & id = mOSTypeSelector->type().GetId();
-    return id == "WindowsVista" || id == "Windows7";
+    const QString &strOsId = mOSTypeSelector->type().GetId();
+    return strOsId == "WindowsVista" || strOsId == "Windows7";
 }
 #endif
 
-void VBoxVMSettingsGeneral::getFrom (const CMachine &aMachine)
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsGeneral::loadToCacheFrom(QVariant &data)
 {
-    mMachine = aMachine;
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
 
-    /* Name */
-    mLeName->setText (aMachine.GetName());
+    /* Fill internal variables with corresponding values: */
+    m_cache.m_strName = m_machine.GetName();
+    m_cache.m_strGuestOsTypeId = m_machine.GetOSTypeId();
+    QString strSaveMountedAtRuntime = m_machine.GetExtraData(VBoxDefs::GUI_SaveMountedAtRuntime);
+    m_cache.m_fSaveMountedAtRuntime = strSaveMountedAtRuntime != "no";
+    QString strShowMiniToolBar = m_machine.GetExtraData(VBoxDefs::GUI_ShowMiniToolBar);
+    m_cache.m_fShowMiniToolBar = strShowMiniToolBar != "no";
+    QString strMiniToolBarAlignment = m_machine.GetExtraData(VBoxDefs::GUI_MiniToolBarAlignment);
+    m_cache.m_fMiniToolBarAtTop = strMiniToolBarAlignment == "top";
+    m_cache.m_strSnapshotsFolder = m_machine.GetSnapshotFolder();
+    m_cache.m_strSnapshotsHomeDir = QFileInfo(m_machine.GetSettingsFilePath()).absolutePath();
+    m_cache.m_clipboardMode = m_machine.GetClipboardMode();
+    m_cache.m_strDescription = m_machine.GetDescription();
 
-    /* OS type */
-    mOSTypeSelector->setType (vboxGlobal().vmGuestOSType (aMachine.GetOSTypeId()));
-
-    /* Remember mediums mounted at runtime */
-    QString saveRtimeImages = mMachine.GetExtraData (VBoxDefs::GUI_SaveMountedAtRuntime);
-    mCbSaveMounted->setChecked (saveRtimeImages != "no");
-
-    /* Show Mini ToolBar in fullscreen/seamless */
-    QString showMiniToolBar = mMachine.GetExtraData (VBoxDefs::GUI_ShowMiniToolBar);
-    mCbShowToolBar->setChecked (showMiniToolBar != "no");
-
-    /* Show Mini ToolBar at top */
-    QString miniToolBarAlignment = mMachine.GetExtraData (VBoxDefs::GUI_MiniToolBarAlignment);
-    mCbToolBarAlignment->setChecked (miniToolBarAlignment == "top");
-    mCbToolBarAlignment->setEnabled (mCbShowToolBar->isChecked());
-
-    /* Snapshot folder */
-    mPsSnapshot->setPath (aMachine.GetSnapshotFolder());
-    mPsSnapshot->setHomeDir (QFileInfo (mMachine.GetSettingsFilePath()).absolutePath());
-
-    /* Shared clipboard mode */
-    mCbClipboard->setCurrentIndex (aMachine.GetClipboardMode());
-
-    /* Description */
-    mTeDescription->setPlainText (aMachine.GetDescription());
-
-    if (mValidator)
-        mValidator->revalidate();
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
-void VBoxVMSettingsGeneral::putBackTo()
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsGeneral::getFromCache()
 {
-    /* Name */
-    mMachine.SetName (mLeName->text());
+    /* Apply internal variables data to QWidget(s): */
+    mLeName->setText(m_cache.m_strName);
+    mOSTypeSelector->setType(vboxGlobal().vmGuestOSType(m_cache.m_strGuestOsTypeId));
+    mCbSaveMounted->setChecked(m_cache.m_fSaveMountedAtRuntime);
+    mCbShowToolBar->setChecked(m_cache.m_fShowMiniToolBar);
+    mCbToolBarAlignment->setChecked(m_cache.m_fMiniToolBarAtTop);
+    mCbToolBarAlignment->setEnabled(mCbShowToolBar->isChecked());
+    mPsSnapshot->setPath(m_cache.m_strSnapshotsFolder);
+    mPsSnapshot->setHomeDir(m_cache.m_strSnapshotsHomeDir);
+    mCbClipboard->setCurrentIndex(m_cache.m_clipboardMode);
+    mTeDescription->setPlainText(m_cache.m_strDescription);
 
-    /* OS type */
-    AssertMsg (!mOSTypeSelector->type().isNull(), ("mOSTypeSelector must return non-null type"));
-    mMachine.SetOSTypeId (mOSTypeSelector->type().GetId());
+    /* Revalidate if possible: */
+    if (mValidator) mValidator->revalidate();
+}
 
-    /* Remember mediums mounted at runtime */
-    mMachine.SetExtraData (VBoxDefs::GUI_SaveMountedAtRuntime,
-                           mCbSaveMounted->isChecked() ? "yes" : "no");
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsGeneral::putToCache()
+{
+    /* Gather internal variables data from QWidget(s): */
+    m_cache.m_strName = mLeName->text();
+    m_cache.m_strGuestOsTypeId = mOSTypeSelector->type().GetId();
+    m_cache.m_fSaveMountedAtRuntime = mCbSaveMounted->isChecked();
+    m_cache.m_fShowMiniToolBar = mCbShowToolBar->isChecked();
+    m_cache.m_fMiniToolBarAtTop = mCbToolBarAlignment->isChecked();
+    m_cache.m_strSnapshotsFolder = mPsSnapshot->path();
+    m_cache.m_clipboardMode = (KClipboardMode)mCbClipboard->currentIndex();
+    m_cache.m_strDescription = mTeDescription->toPlainText().isEmpty() ?
+                               QString::null : mTeDescription->toPlainText();
+}
 
-    /* Show Mini ToolBar in fullscreen/seamless */
-    mMachine.SetExtraData (VBoxDefs::GUI_ShowMiniToolBar,
-                           mCbShowToolBar->isChecked() ? "yes" : "no");
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsGeneral::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
 
-    /* Show Mini ToolBar at top */
-    mMachine.SetExtraData (VBoxDefs::GUI_MiniToolBarAlignment,
-                           mCbToolBarAlignment->isChecked() ? "top" : "bottom");
+    /* Gather corresponding values from internal variables: */
+    m_machine.SetName(m_cache.m_strName);
+    m_machine.SetOSTypeId(m_cache.m_strGuestOsTypeId);
+    m_machine.SetExtraData(VBoxDefs::GUI_SaveMountedAtRuntime, m_cache.m_fSaveMountedAtRuntime ? "yes" : "no");
+    m_machine.SetExtraData(VBoxDefs::GUI_ShowMiniToolBar, m_cache.m_fShowMiniToolBar ? "yes" : "no");
+    m_machine.SetExtraData(VBoxDefs::GUI_MiniToolBarAlignment, m_cache.m_fMiniToolBarAtTop ? "top" : "bottom");
+    m_machine.SetSnapshotFolder(m_cache.m_strSnapshotsFolder);
+    m_machine.SetClipboardMode(m_cache.m_clipboardMode);
+    m_machine.SetDescription(m_cache.m_strDescription);
 
-    /* Saved state folder */
-    if (mPsSnapshot->isModified())
-    {
-        mMachine.SetSnapshotFolder (mPsSnapshot->path());
-        if (!mMachine.isOk())
-            vboxProblem().cannotSetSnapshotFolder (mMachine,
-                    QDir::toNativeSeparators (mPsSnapshot->path()));
-    }
-
-    /* Shared clipboard mode */
-    mMachine.SetClipboardMode ((KClipboardMode) mCbClipboard->currentIndex());
-
-    /* Description (set empty to null to avoid an empty <Description> node
-     * in the settings file) */
-    mMachine.SetDescription (mTeDescription->toPlainText().isEmpty() ?
-                             QString::null : mTeDescription->toPlainText());
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsGeneral.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsGeneral.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsGeneral.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -24,5 +24,20 @@
 #include "COMDefs.h"
 
-class VBoxVMSettingsGeneral : public UISettingsPage,
+/* Machine settings / General page / Cache: */
+struct UISettingsCacheMachineGeneral
+{
+    QString m_strName;
+    QString m_strGuestOsTypeId;
+    bool m_fSaveMountedAtRuntime;
+    bool m_fShowMiniToolBar;
+    bool m_fMiniToolBarAtTop;
+    QString m_strSnapshotsFolder;
+    QString m_strSnapshotsHomeDir;
+    KClipboardMode m_clipboardMode;
+    QString m_strDescription;
+};
+
+/* Machine settings / General page: */
+class VBoxVMSettingsGeneral : public UISettingsPageMachine,
                               public Ui::VBoxVMSettingsGeneral
 {
@@ -45,6 +60,17 @@
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -58,6 +84,8 @@
     void showEvent (QShowEvent *aEvent);
 
-    CMachine mMachine;
     QIWidgetValidator *mValidator;
+
+    /* Cache: */
+    UISettingsCacheMachineGeneral m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsHD.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsHD.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsHD.cpp	(revision 33631)
@@ -1782,98 +1782,180 @@
 }
 
-void VBoxVMSettingsHD::getFrom (const CMachine &aMachine)
-{
-    mMachine = aMachine;
-
-    /* Set the machine id for the media-combo */
-    mCbVdi->setMachineId (mMachine.GetId());
-    mStorageModel->setMachineId (mMachine.GetId());
-
-    /* Load currently present controllers & attachments */
-    CStorageControllerVector controllers = mMachine.GetStorageControllers();
-    foreach (const CStorageController &controller, controllers)
-    {
-        QString controllerName = controller.GetName();
-        QModelIndex ctrIndex = mStorageModel->addController (controllerName, controller.GetBus(), controller.GetControllerType());
-        QUuid ctrId = QUuid (mStorageModel->data (ctrIndex, StorageModel::R_ItemId).toString());
-
-        bool useIoCache = controller.GetUseHostIOCache();
-
-        mStorageModel->setData (ctrIndex, useIoCache, StorageModel::R_CtrIoCache);
-
-        CMediumAttachmentVector attachments = mMachine.GetMediumAttachmentsOfController (controllerName);
-        foreach (const CMediumAttachment &attachment, attachments)
-        {
-            QModelIndex attIndex = mStorageModel->addAttachment (ctrId, attachment.GetType());
-            mStorageModel->setData (attIndex, QVariant::fromValue (StorageSlot (controller.GetBus(), attachment.GetPort(), attachment.GetDevice())), StorageModel::R_AttSlot);
-            CMedium medium (attachment.GetMedium());
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsHD::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Fill internal variables with corresponding values: */
+    m_cache.m_strMachineId = m_machine.GetId();
+    /* Load controllers list: */
+    const CStorageControllerVector &controllers = m_machine.GetStorageControllers();
+    for (int iControllerIndex = 0; iControllerIndex < controllers.size(); ++iControllerIndex)
+    {
+        /* Prepare controller item: */
+        const CStorageController &controller = controllers[iControllerIndex];
+        UIStorageControllerData controllerData;
+        controllerData.m_strControllerName = controller.GetName();
+        controllerData.m_controllerBus = controller.GetBus();
+        controllerData.m_controllerType = controller.GetControllerType();
+        controllerData.m_fUseHostIOCache = controller.GetUseHostIOCache();
+        /* Load attachments list: */
+        const CMediumAttachmentVector &attachments = m_machine.GetMediumAttachmentsOfController(controllerData.m_strControllerName);
+        for (int iAttachmentIndex = 0; iAttachmentIndex < attachments.size(); ++iAttachmentIndex)
+        {
+            /* Prepare attachment item: */
+            const CMediumAttachment &attachment = attachments[iAttachmentIndex];
+            UIStorageAttachmentData attachmentData;
+            attachmentData.m_attachmentType = attachment.GetType();
+            attachmentData.m_iAttachmentPort = attachment.GetPort();
+            attachmentData.m_iAttachmentDevice = attachment.GetDevice();
+            attachmentData.m_fAttachmentPassthrough = attachment.GetPassthrough();
+            CMedium comMedium(attachment.GetMedium());
             VBoxMedium vboxMedium;
-            vboxGlobal().findMedium (medium, vboxMedium);
-            mStorageModel->setData (attIndex, vboxMedium.id(), StorageModel::R_AttMediumId);
-            mStorageModel->setData (attIndex, attachment.GetPassthrough(), StorageModel::R_AttIsPassthrough);
-        }
-    }
-
+            vboxGlobal().findMedium(comMedium, vboxMedium);
+            attachmentData.m_strAttachmentMediumId = vboxMedium.id();
+            controllerData.m_items << attachmentData;
+        }
+        m_cache.m_items << controllerData;
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsHD::getFromCache()
+{
+    /* Apply internal variables data to QWidget(s): */
+    mCbVdi->setMachineId(m_cache.m_strMachineId);
+    mStorageModel->setMachineId(m_cache.m_strMachineId);
+    for (int iControllerIndex = 0; iControllerIndex < m_cache.m_items.size(); ++iControllerIndex)
+    {
+        /* Get iterated controller: */
+        const UIStorageControllerData &controllerData = m_cache.m_items[iControllerIndex];
+        QModelIndex controllerIndex = mStorageModel->addController(controllerData.m_strControllerName,
+                                                                   controllerData.m_controllerBus,
+                                                                   controllerData.m_controllerType);
+        QUuid controllerId = QUuid(mStorageModel->data(controllerIndex, StorageModel::R_ItemId).toString());
+        mStorageModel->setData(controllerIndex, controllerData.m_fUseHostIOCache, StorageModel::R_CtrIoCache);
+        for (int iAttachmentIndex = 0; iAttachmentIndex < controllerData.m_items.size(); ++iAttachmentIndex)
+        {
+            /* Get iterated attachment: */
+            const UIStorageAttachmentData &attachmentData = controllerData.m_items[iAttachmentIndex];
+            QModelIndex attachmentIndex = mStorageModel->addAttachment(controllerId, attachmentData.m_attachmentType);
+            StorageSlot attachmentStorageSlot(controllerData.m_controllerBus,
+                                              attachmentData.m_iAttachmentPort,
+                                              attachmentData.m_iAttachmentDevice);
+            mStorageModel->setData(attachmentIndex, QVariant::fromValue(attachmentStorageSlot), StorageModel::R_AttSlot);
+            mStorageModel->setData(attachmentIndex, attachmentData.m_fAttachmentPassthrough, StorageModel::R_AttIsPassthrough);
+            mStorageModel->setData(attachmentIndex, attachmentData.m_strAttachmentMediumId, StorageModel::R_AttMediumId);
+        }
+    }
     /* Set the first controller as current if present */
-    if (mStorageModel->rowCount (mStorageModel->root()) > 0)
-        mTwStorageTree->setCurrentIndex (mStorageModel->index (0, 0, mStorageModel->root()));
-}
-
-void VBoxVMSettingsHD::putBackTo()
-{
+    if (mStorageModel->rowCount(mStorageModel->root()) > 0)
+        mTwStorageTree->setCurrentIndex(mStorageModel->index(0, 0, mStorageModel->root()));
+
+    /* Revalidate if possible: */
+    if (mValidator) mValidator->revalidate();
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsHD::putToCache()
+{
+    /* Gather internal variables data from QWidget(s): */
+    m_cache.m_items.clear();
+    QModelIndex rootIndex = mStorageModel->root();
+    for (int iControllerIndex = 0; iControllerIndex < mStorageModel->rowCount(rootIndex); ++iControllerIndex)
+    {
+        QModelIndex controllerIndex = mStorageModel->index(iControllerIndex, 0, rootIndex);
+        UIStorageControllerData controllerData;
+        controllerData.m_strControllerName = mStorageModel->data(controllerIndex, StorageModel::R_CtrName).toString();
+        controllerData.m_controllerBus = mStorageModel->data(controllerIndex, StorageModel::R_CtrBusType).value<KStorageBus>();
+        controllerData.m_controllerType = mStorageModel->data(controllerIndex, StorageModel::R_CtrType).value<KStorageControllerType>();
+        controllerData.m_fUseHostIOCache = mStorageModel->data(controllerIndex, StorageModel::R_CtrIoCache).toBool();
+        for (int iAttachmentIndex = 0; iAttachmentIndex < mStorageModel->rowCount(controllerIndex); ++iAttachmentIndex)
+        {
+            QModelIndex attachmentIndex = mStorageModel->index(iAttachmentIndex, 0, controllerIndex);
+            UIStorageAttachmentData attachmentData;
+            attachmentData.m_attachmentType = mStorageModel->data(attachmentIndex, StorageModel::R_AttDevice).value<KDeviceType>();
+            StorageSlot attachmentSlot = mStorageModel->data(attachmentIndex, StorageModel::R_AttSlot).value<StorageSlot>();
+            attachmentData.m_iAttachmentPort = attachmentSlot.port;
+            attachmentData.m_iAttachmentDevice = attachmentSlot.device;
+            attachmentData.m_fAttachmentPassthrough = mStorageModel->data(attachmentIndex, StorageModel::R_AttIsPassthrough).toBool();
+            attachmentData.m_strAttachmentMediumId = mStorageModel->data(attachmentIndex, StorageModel::R_AttMediumId).toString();
+            controllerData.m_items << attachmentData;
+        }
+        m_cache.m_items << controllerData;
+    }
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsHD::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
     /* Remove currently present controllers & attachments */
-    CStorageControllerVector controllers = mMachine.GetStorageControllers();
-    foreach (const CStorageController &controller, controllers)
-    {
-        QString controllerName (controller.GetName());
-        CMediumAttachmentVector attachments = mMachine.GetMediumAttachmentsOfController (controllerName);
-        foreach (const CMediumAttachment &attachment, attachments)
-            mMachine.DetachDevice (controllerName, attachment.GetPort(), attachment.GetDevice());
-        mMachine.RemoveStorageController (controllerName);
-    }
-
-    /* Save created controllers & attachments */
-    QModelIndex rootIndex = mStorageModel->root();
-    for (int i = 0; i < mStorageModel->rowCount (rootIndex); ++ i)
-    {
-        QModelIndex ctrIndex = rootIndex.child (i, 0);
-        QString ctrName = mStorageModel->data (ctrIndex, StorageModel::R_CtrName).toString();
-        KStorageBus ctrBusType = mStorageModel->data (ctrIndex, StorageModel::R_CtrBusType).value <KStorageBus>();
-        KStorageControllerType ctrType = mStorageModel->data (ctrIndex, StorageModel::R_CtrType).value <KStorageControllerType>();
-        bool useIoCache = mStorageModel->data (ctrIndex, StorageModel::R_CtrIoCache).toBool();
-        CStorageController ctr = mMachine.AddStorageController (ctrName, ctrBusType);
-        ctr.SetControllerType (ctrType);
-        ctr.SetUseHostIOCache(useIoCache);
-        int maxUsedPort = -1;
-        for (int j = 0; j < mStorageModel->rowCount (ctrIndex); ++ j)
-        {
-            QModelIndex attIndex = ctrIndex.child (j, 0);
-            StorageSlot attStorageSlot = mStorageModel->data (attIndex, StorageModel::R_AttSlot).value <StorageSlot>();
-            KDeviceType attDeviceType = mStorageModel->data (attIndex, StorageModel::R_AttDevice).value <KDeviceType>();
-            QString attMediumId = mStorageModel->data (attIndex, StorageModel::R_AttMediumId).toString();
-            QString attMediumLocation = mStorageModel->data (attIndex, StorageModel::R_AttLocation).toString();
-
-            VBoxMedium vmedium = vboxGlobal().findMedium(attMediumId);
-            CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
-            mMachine.AttachDevice(ctrName, attStorageSlot.port, attStorageSlot.device, attDeviceType, medium);
-            if (mMachine.isOk())
+    const CStorageControllerVector &controllers = m_machine.GetStorageControllers();
+    for (int iControllerIndex = 0; iControllerIndex < controllers.size(); ++iControllerIndex)
+    {
+        const CStorageController &controller = controllers[iControllerIndex];
+        QString strControllerName(controller.GetName());
+        const CMediumAttachmentVector &attachments = m_machine.GetMediumAttachmentsOfController(strControllerName);
+        for (int iAttachmentIndex = 0; iAttachmentIndex < attachments.size(); ++iAttachmentIndex)
+        {
+            const CMediumAttachment &attachment = attachments[iAttachmentIndex];
+            m_machine.DetachDevice(strControllerName, attachment.GetPort(), attachment.GetDevice());
+        }
+        m_machine.RemoveStorageController(strControllerName);
+    }
+    /* Save created controllers: */
+    for (int iControllerIndex = 0; iControllerIndex < m_cache.m_items.size(); ++iControllerIndex)
+    {
+        const UIStorageControllerData &controllerData = m_cache.m_items[iControllerIndex];
+        CStorageController &controller = m_machine.AddStorageController(controllerData.m_strControllerName, controllerData.m_controllerBus);
+        controller.SetControllerType(controllerData.m_controllerType);
+        controller.SetUseHostIOCache(controllerData.m_fUseHostIOCache);
+        int cMaxUsedPort = -1;
+        /* Save created attachments: */
+        for (int iAttachmentIndex = 0; iAttachmentIndex < controllerData.m_items.size(); ++iAttachmentIndex)
+        {
+            const UIStorageAttachmentData &attachmentData = controllerData.m_items[iAttachmentIndex];
+            VBoxMedium vboxMedium = vboxGlobal().findMedium(attachmentData.m_strAttachmentMediumId);
+            CMedium comMedium = vboxMedium.medium();
+            m_machine.AttachDevice(controllerData.m_strControllerName,
+                                   attachmentData.m_iAttachmentPort, attachmentData.m_iAttachmentDevice,
+                                   attachmentData.m_attachmentType, comMedium);
+            if (m_machine.isOk())
             {
-                if (attDeviceType == KDeviceType_DVD)
-                    mMachine.PassthroughDevice (ctrName, attStorageSlot.port, attStorageSlot.device,
-                                                mStorageModel->data (attIndex, StorageModel::R_AttIsPassthrough).toBool());
-                maxUsedPort = attStorageSlot.port > maxUsedPort ? attStorageSlot.port : maxUsedPort;
+                if (attachmentData.m_attachmentType == KDeviceType_DVD)
+                    m_machine.PassthroughDevice(controllerData.m_strControllerName,
+                                                attachmentData.m_iAttachmentPort, attachmentData.m_iAttachmentDevice,
+                                                attachmentData.m_fAttachmentPassthrough);
+                cMaxUsedPort = attachmentData.m_iAttachmentPort > cMaxUsedPort ? attachmentData.m_iAttachmentPort : cMaxUsedPort;
             }
             else
-                vboxProblem().cannotAttachDevice(this, mMachine, VBoxDefs::MediumType_HardDisk, attMediumLocation,
-                                                 attStorageSlot.bus, attStorageSlot.port, attStorageSlot.device);
-        }
-        if (ctrBusType == KStorageBus_SATA)
-        {
-            ULONG sataPortsCount = maxUsedPort + 1;
-            sataPortsCount = qMax (sataPortsCount, ctr.GetMinPortCount());
-            sataPortsCount = qMin (sataPortsCount, ctr.GetMaxPortCount());
-            ctr.SetPortCount (sataPortsCount);
-        }
-    }
+            {
+                // TODO: Fix problem reporter!
+                //vboxProblem().cannotAttachDevice(this, m_machine, VBoxDefs::MediumType_HardDisk, vboxMedium.location(),
+                //                                 controllerData.m_controllerBus, attachmentData.m_iAttachmentPort, attachmentData.m_iAttachmentDevice);
+            }
+        }
+        if (controllerData.m_controllerBus == KStorageBus_SATA)
+        {
+            ULONG uSataPortsCount = cMaxUsedPort + 1;
+            uSataPortsCount = qMax(uSataPortsCount, controller.GetMinPortCount());
+            uSataPortsCount = qMin(uSataPortsCount, controller.GetMaxPortCount());
+            controller.SetPortCount(uSataPortsCount);
+        }
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
@@ -2666,5 +2748,5 @@
                true /* do select? */,
                false /* do refresh? */,
-               mMachine,
+               m_machine,
                mCbVdi->id(),
                mCbShowDiffs->isChecked());
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsHD.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsHD.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsHD.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2009 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -530,9 +530,33 @@
 };
 
-/**
- * QWidget class reimplementation.
- * Used as HD Settings widget.
- */
-class VBoxVMSettingsHD : public UISettingsPage,
+/* Machine settings / Storage page / Attachment data: */
+struct UIStorageAttachmentData
+{
+    KDeviceType m_attachmentType;
+    LONG m_iAttachmentPort;
+    LONG m_iAttachmentDevice;
+    QString m_strAttachmentMediumId;
+    bool m_fAttachmentPassthrough;
+};
+
+/* Machine settings / Storage page / Controller data: */
+struct UIStorageControllerData
+{
+    QString m_strControllerName;
+    KStorageBus m_controllerBus;
+    KStorageControllerType m_controllerType;
+    bool m_fUseHostIOCache;
+    QList<UIStorageAttachmentData> m_items;
+};
+
+/* Machine settings / Storage page / Cache: */
+struct UISettingsCacheMachineStorage
+{
+    QString m_strMachineId;
+    QList<UIStorageControllerData> m_items;
+};
+
+/* Machine settings / Storage page: */
+class VBoxVMSettingsHD : public UISettingsPageMachine,
                          public Ui::VBoxVMSettingsHD
 {
@@ -549,6 +573,17 @@
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -611,5 +646,4 @@
     uint32_t deviceCount (KDeviceType aType) const;
 
-    CMachine mMachine;
     QIWidgetValidator *mValidator;
 
@@ -632,4 +666,7 @@
     bool mIsPolished;
     bool mDisableStaticControls;
+
+    /* Cache: */
+    UISettingsCacheMachineStorage m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.cpp	(revision 33631)
@@ -42,4 +42,5 @@
     , mParent (aParent)
     , mValidator (0)
+    , m_iSlot(-1)
     , mPolished (false)
     , mDisableStaticControls (false)
@@ -78,38 +79,40 @@
 }
 
-void VBoxVMSettingsNetwork::getFromAdapter (const CNetworkAdapter &aAdapter)
-{
-    mAdapter = aAdapter;
-
-    /* Load adapter activity state */
-    mCbEnableAdapter->setChecked (aAdapter.GetEnabled());
-
-    /* Load adapter type */
-    int adapterPos = mCbAdapterType->findData (aAdapter.GetAdapterType());
-    mCbAdapterType->setCurrentIndex (adapterPos == -1 ? 0 : adapterPos);
-
-    /* Load attachment type */
-    int attachmentPos = mCbAttachmentType->findData (aAdapter.GetAttachmentType());
-    mCbAttachmentType->setCurrentIndex (attachmentPos == -1 ? 0 : attachmentPos);
-
-    /* Load alternative name */
+void VBoxVMSettingsNetwork::fetchAdapterData(const UINetworkAdapterData &data)
+{
+    /* Load adapter & slot number: */
+    m_iSlot = data.m_iSlot;
+    m_adapter = data.m_adapter;
+
+    /* Load adapter activity state: */
+    mCbEnableAdapter->setChecked(data.m_fAdapterEnabled);
+
+    /* Load adapter type: */
+    int adapterPos = mCbAdapterType->findData(data.m_adapterType);
+    mCbAdapterType->setCurrentIndex(adapterPos == -1 ? 0 : adapterPos);
+
+    /* Load attachment type: */
+    int attachmentPos = mCbAttachmentType->findData(data.m_attachmentType);
+    mCbAttachmentType->setCurrentIndex(attachmentPos == -1 ? 0 : attachmentPos);
+
+    /* Load alternative name: */
     switch (attachmentType())
     {
         case KNetworkAttachmentType_Bridged:
-            mBrgName = mAdapter.GetHostInterface();
-            if (mBrgName.isEmpty()) mBrgName = QString::null;
+            mBrgName = data.m_strBridgedAdapterName;
+            if (mBrgName.isEmpty()) mBrgName = QString();
             break;
         case KNetworkAttachmentType_Internal:
-            mIntName = mAdapter.GetInternalNetwork();
-            if (mIntName.isEmpty()) mIntName = QString::null;
+            mIntName = data.m_strInternalNetworkName;
+            if (mIntName.isEmpty()) mIntName = QString();
             break;
         case KNetworkAttachmentType_HostOnly:
-            mHoiName = mAdapter.GetHostInterface();
-            if (mHoiName.isEmpty()) mHoiName = QString::null;
+            mHoiName = data.m_strHostInterfaceName;
+            if (mHoiName.isEmpty()) mHoiName = QString();
             break;
 #ifdef VBOX_WITH_VDE
         case KNetworkAttachmentType_VDE:
-            mVDEName = mAdapter.GetVDENetwork();
-            if (mVDEName.isEmpty()) mVDEName = QString::null;
+            mVDEName = data.m_strVDENetworkName;
+            if (mVDEName.isEmpty()) mVDEName = QString();
             break;
 #endif
@@ -119,57 +122,40 @@
     updateAttachmentAlternative();
 
-    mLeMAC->setText (mAdapter.GetMACAddress());
-    mCbCableConnected->setChecked (mAdapter.GetCableConnected());
+    /* Other options: */
+    mLeMAC->setText(data.m_strMACAddress);
+    mCbCableConnected->setChecked(data.m_fCableConnected);
 
     /* Load port forwarding rules: */
-    QVector<QString> redirects = mAdapter.GetNatDriver().GetRedirects();
-    for (int i = 0; i < redirects.size(); ++i)
-    {
-        QStringList redirectData = redirects[i].split(',');
-        AssertMsg(redirectData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
-        mPortForwardingRules << UIPortForwardingData(redirectData[0],
-                                                     (KNATProtocol)redirectData[1].toUInt(),
-                                                     redirectData[2],
-                                                     redirectData[3].toUInt(),
-                                                     redirectData[4],
-                                                     redirectData[5].toUInt());
-    }
-}
-
-void VBoxVMSettingsNetwork::putBackToAdapter()
-{
-    /* Save adapter activity state */
-    mAdapter.SetEnabled (mCbEnableAdapter->isChecked());
-
-    /* Save adapter type */
-    KNetworkAdapterType type = (KNetworkAdapterType)
-        mCbAdapterType->itemData (mCbAdapterType->currentIndex()).toInt();
-    mAdapter.SetAdapterType (type);
-
-    /* Save attachment type & alternative name */
-    switch (attachmentType())
+    mPortForwardingRules = data.m_redirects;
+}
+
+void VBoxVMSettingsNetwork::uploadAdapterData(UINetworkAdapterData &data)
+{
+    /* Save adapter activity state: */
+    data.m_fAdapterEnabled = mCbEnableAdapter->isChecked();
+
+    /* Save adapter type: */
+    data.m_adapterType = (KNetworkAdapterType)mCbAdapterType->itemData(mCbAdapterType->currentIndex()).toInt();
+
+    /* Save attachment type & alternative name: */
+    data.m_attachmentType = attachmentType();
+    switch (data.m_attachmentType)
     {
         case KNetworkAttachmentType_Null:
-            mAdapter.Detach();
             break;
         case KNetworkAttachmentType_NAT:
-            mAdapter.AttachToNAT();
             break;
         case KNetworkAttachmentType_Bridged:
-            mAdapter.SetHostInterface (alternativeName());
-            mAdapter.AttachToBridgedInterface();
+            data.m_strBridgedAdapterName = alternativeName();
             break;
         case KNetworkAttachmentType_Internal:
-            mAdapter.SetInternalNetwork (alternativeName());
-            mAdapter.AttachToInternalNetwork();
+            data.m_strInternalNetworkName = alternativeName();
             break;
         case KNetworkAttachmentType_HostOnly:
-            mAdapter.SetHostInterface (alternativeName());
-            mAdapter.AttachToHostOnlyInterface();
+            data.m_strHostInterfaceName = alternativeName();
             break;
 #ifdef VBOX_WITH_VDE
         case KNetworkAttachmentType_VDE:
-            mAdapter.SetVDENetwork (alternativeName());
-            mAdapter.AttachToVDE();
+            data.m_strVDENetworkName = alternativeName();
             break;
 #endif
@@ -178,18 +164,10 @@
     }
 
-    mAdapter.SetMACAddress (mLeMAC->text().isEmpty() ? QString::null : mLeMAC->text());
-    mAdapter.SetCableConnected (mCbCableConnected->isChecked());
+    /* Other options: */
+    data.m_strMACAddress = mLeMAC->text().isEmpty() ? QString() : mLeMAC->text();
+    data.m_fCableConnected = mCbCableConnected->isChecked();
 
     /* Save port forwarding rules: */
-    QVector<QString> redirects = mAdapter.GetNatDriver().GetRedirects();
-    for (int i = 0; i < redirects.size(); ++i)
-        mAdapter.GetNatDriver().RemoveRedirect(redirects[i].section(',', 0, 0));
-    for (int i = 0; i < mPortForwardingRules.size(); ++i)
-    {
-        UIPortForwardingData redirectData = mPortForwardingRules[i];
-        mAdapter.GetNatDriver().AddRedirect(redirectData.name, redirectData.protocol,
-                                            redirectData.hostIp, redirectData.hostPort.value(),
-                                            redirectData.guestIp, redirectData.guestPort.value());
-    }
+    data.m_redirects = mPortForwardingRules;
 }
 
@@ -269,11 +247,5 @@
 QString VBoxVMSettingsNetwork::pageTitle() const
 {
-    QString title;
-    if (!mAdapter.isNull())
-    {
-        title = VBoxGlobal::tr ("Adapter %1", "network")
-            .arg (QString ("&%1").arg (mAdapter.GetSlot() + 1));
-    }
-    return title;
+    return VBoxGlobal::tr("Adapter %1", "network").arg(QString("&%1").arg(m_iSlot + 1));;
 }
 
@@ -524,6 +496,6 @@
 void VBoxVMSettingsNetwork::generateMac()
 {
-    mAdapter.SetMACAddress (QString::null);
-    mLeMAC->setText (mAdapter.GetMACAddress());
+    m_adapter.SetMACAddress(QString::null);
+    mLeMAC->setText(m_adapter.GetMACAddress());
 }
 
@@ -663,4 +635,20 @@
 }
 
+void VBoxVMSettingsNetworkPage::loadDirectlyFrom(const CMachine &machine)
+{
+    qRegisterMetaType<UISettingsDataMachine>();
+    UISettingsDataMachine data(machine);
+    loadToCacheFrom(QVariant::fromValue(data));
+    getFromCache();
+}
+
+void VBoxVMSettingsNetworkPage::saveDirectlyTo(CMachine &machine)
+{
+    qRegisterMetaType<UISettingsDataMachine>();
+    UISettingsDataMachine data(machine);
+    putToCache();
+    saveFromCacheTo(QVariant::fromValue(data));
+}
+
 QStringList VBoxVMSettingsNetworkPage::brgList (bool aRefresh)
 {
@@ -741,57 +729,205 @@
 }
 
-void VBoxVMSettingsNetworkPage::getFrom (const CMachine &aMachine)
-{
-    /* Setup tab order */
-    Assert (m_pFirstWidget);
-    setTabOrder (m_pFirstWidget, mTwAdapters->focusProxy());
-    QWidget *lastFocusWidget = mTwAdapters->focusProxy();
-
-    /* Cache data */
-    brgList (true);
-    intList (true);
-    hoiList (true);
-
-    /* Creating Tab Pages */
-    CVirtualBox vbox = vboxGlobal().virtualBox();
-    ulong count = qMin ((ULONG) 4, vbox.GetSystemProperties().GetNetworkAdapterCount());
-    for (ulong slot = 0; slot < count; ++ slot)
-    {
-        /* Get Adapter */
-        CNetworkAdapter adapter = aMachine.GetNetworkAdapter (slot);
-
-        /* Creating Adapter's page */
-        VBoxVMSettingsNetwork *page = new VBoxVMSettingsNetwork (this, mDisableStaticControls);
-
-        /* Loading Adapter's data into page */
-        page->getFromAdapter (adapter);
-
-        /* Attach Adapter's page to Tab Widget */
-        mTwAdapters->addTab (page, page->pageTitle());
-
-        /* Disable tab page if adapter is being configured dynamically */
-        if (mDisableStaticControls && !adapter.GetEnabled())
-            mTwAdapters->setTabEnabled(slot, false);
-
-        /* Setup validation */
-        page->setValidator (mValidator);
-
-        /* Setup tab order */
-        lastFocusWidget = page->setOrderAfter (lastFocusWidget);
-    }
-
-    /* Applying language settings */
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsNetworkPage::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Cache names lists: */
+    brgList(true);
+    intList(true);
+    hoiList(true);
+
+    /* Load adapters data: */
+    ulong uCount = qMin((ULONG)4, vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount());
+    for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
+    {
+        /* Get adapter: */
+        const CNetworkAdapter &adapter = m_machine.GetNetworkAdapter(uSlot);
+
+        /* Prepare adapter's data container: */
+        UINetworkAdapterData data;
+
+        /* Load main options: */
+        data.m_iSlot = uSlot;
+        data.m_adapter = adapter;
+        data.m_fAdapterEnabled = adapter.GetEnabled();
+        data.m_adapterType = adapter.GetAdapterType();
+        data.m_attachmentType = adapter.GetAttachmentType();
+        switch (data.m_attachmentType)
+        {
+            case KNetworkAttachmentType_Bridged:
+                data.m_strBridgedAdapterName = adapter.GetHostInterface();
+                if (data.m_strBridgedAdapterName.isEmpty()) data.m_strBridgedAdapterName = QString();
+                break;
+            case KNetworkAttachmentType_Internal:
+                data.m_strInternalNetworkName = adapter.GetInternalNetwork();
+                if (data.m_strInternalNetworkName.isEmpty()) data.m_strInternalNetworkName = QString();
+                break;
+            case KNetworkAttachmentType_HostOnly:
+                data.m_strHostInterfaceName = adapter.GetHostInterface();
+                if (data.m_strHostInterfaceName.isEmpty()) data.m_strHostInterfaceName = QString();
+                break;
+#ifdef VBOX_WITH_VDE
+            case KNetworkAttachmentType_VDE:
+                data.m_strVDENetworkName = adapter.GetVDENetwork();
+                if (data.m_strVDENetworkName.isEmpty()) data.m_strVDENetworkName = QString();
+                break;
+#endif
+            default:
+                break;
+        }
+
+        /* Load advanced options: */
+        data.m_strMACAddress = adapter.GetMACAddress();
+        data.m_fCableConnected = adapter.GetCableConnected();
+
+        /* Load redirect options: */
+        QVector<QString> redirects = adapter.GetNatDriver().GetRedirects();
+        for (int i = 0; i < redirects.size(); ++i)
+        {
+            QStringList redirectData = redirects[i].split(',');
+            AssertMsg(redirectData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
+            data.m_redirects << UIPortForwardingData(redirectData[0],
+                                                     (KNATProtocol)redirectData[1].toUInt(),
+                                                     redirectData[2],
+                                                     redirectData[3].toUInt(),
+                                                     redirectData[4],
+                                                     redirectData[5].toUInt());
+        }
+
+        /* Append adapter's data container: */
+        m_cache.m_items << data;
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsNetworkPage::getFromCache()
+{
+    /* Setup tab order: */
+    Assert(m_pFirstWidget);
+    setTabOrder(m_pFirstWidget, mTwAdapters->focusProxy());
+    QWidget *pLastFocusWidget = mTwAdapters->focusProxy();
+
+    /* Apply internal variables data to QWidget(s): */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Creating adapter's page: */
+        VBoxVMSettingsNetwork *pPage = new VBoxVMSettingsNetwork(this, mDisableStaticControls);
+
+        /* Loading adapter's data into page: */
+        pPage->fetchAdapterData(m_cache.m_items[iSlot]);
+
+        /* Attach adapter's page to Tab Widget: */
+        mTwAdapters->addTab(pPage, pPage->pageTitle());
+
+        /* Disable tab page of disabled adapter if it is being configured dynamically: */
+        if (mDisableStaticControls && !m_cache.m_items[iSlot].m_fAdapterEnabled)
+            mTwAdapters->setTabEnabled(iSlot, false);
+
+        /* Setup page validation: */
+        pPage->setValidator(mValidator);
+
+        /* Setup tab order: */
+        pLastFocusWidget = pPage->setOrderAfter(pLastFocusWidget);
+    }
+
+    /* Applying language settings: */
     retranslateUi();
-}
-
-void VBoxVMSettingsNetworkPage::putBackTo()
-{
-    for (int i = 0; i < mTwAdapters->count(); ++ i)
-    {
-        VBoxVMSettingsNetwork *page =
-            qobject_cast <VBoxVMSettingsNetwork*> (mTwAdapters->widget (i));
-        Assert (page);
-        page->putBackToAdapter();
-    }
+
+    /* Revalidate if possible: */
+    if (mValidator) mValidator->revalidate();
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsNetworkPage::putToCache()
+{
+    /* Gather internal variables data from QWidget(s): */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Getting adapter's page: */
+        VBoxVMSettingsNetwork *pPage = qobject_cast<VBoxVMSettingsNetwork*>(mTwAdapters->widget(iSlot));
+
+        /* Loading Adapter's data from page: */
+        pPage->uploadAdapterData(m_cache.m_items[iSlot]);
+    }
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsNetworkPage::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Gather corresponding values from internal variables: */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Get adapter: */
+        CNetworkAdapter &adapter = m_machine.GetNetworkAdapter(iSlot);
+
+        /* Get cached data for this adapter: */
+        const UINetworkAdapterData &data = m_cache.m_items[iSlot];
+
+        /* Save main options: */
+        adapter.SetEnabled(data.m_fAdapterEnabled);
+        adapter.SetAdapterType(data.m_adapterType);
+        switch (data.m_attachmentType)
+        {
+            case KNetworkAttachmentType_Null:
+                adapter.Detach();
+                break;
+            case KNetworkAttachmentType_NAT:
+                adapter.AttachToNAT();
+                break;
+            case KNetworkAttachmentType_Bridged:
+                adapter.SetHostInterface(data.m_strBridgedAdapterName);
+                adapter.AttachToBridgedInterface();
+                break;
+            case KNetworkAttachmentType_Internal:
+                adapter.SetInternalNetwork(data.m_strInternalNetworkName);
+                adapter.AttachToInternalNetwork();
+                break;
+            case KNetworkAttachmentType_HostOnly:
+                adapter.SetHostInterface(data.m_strHostInterfaceName);
+                adapter.AttachToHostOnlyInterface();
+                break;
+    #ifdef VBOX_WITH_VDE
+            case KNetworkAttachmentType_VDE:
+                adapter.SetVDENetwork(data.m_strVDENetworkName);
+                adapter.AttachToVDE();
+                break;
+    #endif
+            default:
+                break;
+        }
+
+        /* Save advanced options: */
+        adapter.SetMACAddress(data.m_strMACAddress);
+        adapter.SetCableConnected(data.m_fCableConnected);
+
+        /* Save redirect options: */
+        QVector<QString> oldRedirects = adapter.GetNatDriver().GetRedirects();
+        for (int i = 0; i < oldRedirects.size(); ++i)
+            adapter.GetNatDriver().RemoveRedirect(oldRedirects[i].section(',', 0, 0));
+        UIPortForwardingDataList newRedirects = data.m_redirects;
+        for (int i = 0; i < newRedirects.size(); ++i)
+        {
+            UIPortForwardingData newRedirect = newRedirects[i];
+            adapter.GetNatDriver().AddRedirect(newRedirect.name, newRedirect.protocol,
+                                               newRedirect.hostIp, newRedirect.hostPort.value(),
+                                               newRedirect.guestIp, newRedirect.guestPort.value());
+        }
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsNetwork.h	(revision 33631)
@@ -30,4 +30,30 @@
 class QITabWidget;
 
+/* Machine settings / Network page / Adapter data: */
+struct UINetworkAdapterData
+{
+    int m_iSlot;
+    /* CNetworkAdapter used only for Generate MAC ability! */
+    CNetworkAdapter m_adapter;
+    bool m_fAdapterEnabled;
+    KNetworkAdapterType m_adapterType;
+    KNetworkAttachmentType m_attachmentType;
+    QString m_strBridgedAdapterName;
+    QString m_strInternalNetworkName;
+    QString m_strHostInterfaceName;
+#ifdef VBOX_WITH_VDE
+    QString m_strVDENetworkName;
+#endif /* VBOX_WITH_VDE */
+    QString m_strMACAddress;
+    bool m_fCableConnected;
+    UIPortForwardingDataList m_redirects;
+};
+
+/* Machine settings / Network page / Cache: */
+struct UISettingsCacheMachineNetwork
+{
+    QList<UINetworkAdapterData> m_items;
+};
+
 class VBoxVMSettingsNetwork : public QIWithRetranslateUI <QWidget>,
                               public Ui::VBoxVMSettingsNetwork
@@ -39,6 +65,6 @@
     VBoxVMSettingsNetwork (VBoxVMSettingsNetworkPage *aParent, bool aDisableStaticControls = false);
 
-    void getFromAdapter (const CNetworkAdapter &aAdapter);
-    void putBackToAdapter();
+    void fetchAdapterData(const UINetworkAdapterData &data);
+    void uploadAdapterData(UINetworkAdapterData &data);
 
     void setValidator (QIWidgetValidator *aValidator);
@@ -70,6 +96,7 @@
 
     VBoxVMSettingsNetworkPage *mParent;
-    CNetworkAdapter mAdapter;
     QIWidgetValidator *mValidator;
+    int m_iSlot;
+    CNetworkAdapter m_adapter;
 
     QString mBrgName;
@@ -85,5 +112,6 @@
 };
 
-class VBoxVMSettingsNetworkPage : public UISettingsPage
+/* Machine settings / Network page: */
+class VBoxVMSettingsNetworkPage : public UISettingsPageMachine
 {
     Q_OBJECT;
@@ -92,4 +120,7 @@
 
     VBoxVMSettingsNetworkPage (bool aDisableStaticControls = false);
+
+    void loadDirectlyFrom(const CMachine &machine);
+    void saveDirectlyTo(CMachine &machine);
 
     QStringList brgList (bool aRefresh = false);
@@ -102,6 +133,17 @@
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aValidator);
@@ -124,4 +166,7 @@
 
     bool mDisableStaticControls;
+
+    /* Cache: */
+    UISettingsCacheMachineNetwork m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsParallel.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsParallel.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsParallel.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -29,4 +29,5 @@
     : QIWithRetranslateUI<QWidget> (0)
     , mValidator (0)
+    , m_iSlot(-1)
 {
     /* Apply UI decorations */
@@ -57,27 +58,27 @@
 }
 
-void VBoxVMSettingsParallel::getFromPort (const CParallelPort &aPort)
-{
-    mPort = aPort;
-
-    mGbParallel->setChecked (mPort.GetEnabled());
-    ulong IRQ = mPort.GetIRQ();
-    ulong IOBase = mPort.GetIOBase();
-    mCbNumber->setCurrentIndex (mCbNumber->
-        findText (vboxGlobal().toCOMPortName (IRQ, IOBase)));
-    mLeIRQ->setText (QString::number (IRQ));
-    mLeIOPort->setText ("0x" + QString::number (IOBase, 16).toUpper());
-    mLePath->setText (mPort.GetPath());
+void VBoxVMSettingsParallel::fetchPortData(const UIParallelPortData &data)
+{
+    /* Load port slot number: */
+    m_iSlot = data.m_iSlot;
+
+    /* Fetch port data: */
+    mGbParallel->setChecked(data.m_fPortEnabled);
+    mCbNumber->setCurrentIndex(mCbNumber->findText(vboxGlobal().toCOMPortName(data.m_uIRQ, data.m_uIOBase)));
+    mLeIRQ->setText(QString::number(data.m_uIRQ));
+    mLeIOPort->setText("0x" + QString::number(data.m_uIOBase, 16).toUpper());
+    mLePath->setText(data.m_strPath);
 
     /* Ensure everything is up-to-date */
-    mGbParallelToggled (mGbParallel->isChecked());
-}
-
-void VBoxVMSettingsParallel::putBackToPort()
-{
-    mPort.SetEnabled (mGbParallel->isChecked());
-    mPort.SetIRQ (mLeIRQ->text().toULong (NULL, 0));
-    mPort.SetIOBase (mLeIOPort->text().toULong (NULL, 0));
-    mPort.SetPath (QDir::toNativeSeparators (mLePath->text()));
+    mGbParallelToggled(mGbParallel->isChecked());
+}
+
+void VBoxVMSettingsParallel::uploadPortData(UIParallelPortData &data)
+{
+    /* Upload port data: */
+    data.m_fPortEnabled = mGbParallel->isChecked();
+    data.m_uIRQ = mLeIRQ->text().toULong(NULL, 0);
+    data.m_uIOBase = mLeIOPort->text().toULong(NULL, 0);
+    data.m_strPath = QDir::toNativeSeparators(mLePath->text());
 }
 
@@ -107,9 +108,5 @@
 QString VBoxVMSettingsParallel::pageTitle() const
 {
-    QString pageTitle;
-    if (!mPort.isNull())
-        pageTitle = QString (tr ("Port %1", "parallel ports"))
-            .arg (QString ("&%1").arg (mPort.GetSlot() + 1));
-    return pageTitle;
+    return QString(tr("Port %1", "parallel ports")).arg(QString("&%1").arg(m_iSlot + 1));
 }
 
@@ -162,34 +159,110 @@
 }
 
-void VBoxVMSettingsParallelPage::getFrom (const CMachine &aMachine)
-{
-    Assert (m_pFirstWidget);
-    setTabOrder (m_pFirstWidget, mTabWidget->focusProxy());
-    QWidget *lastFocusWidget = mTabWidget->focusProxy();
-
-    /* Tab pages loading */
-    ulong count = vboxGlobal().virtualBox().
-                  GetSystemProperties().GetParallelPortCount();
-    for (ulong slot = 0; slot < count; ++ slot)
-    {
-        CParallelPort port = aMachine.GetParallelPort (slot);
-        VBoxVMSettingsParallel *page = new VBoxVMSettingsParallel();
-        page->getFromPort (port);
-        mTabWidget->addTab (page, page->pageTitle());
-        Assert (mValidator);
-        page->setValidator (mValidator);
-        lastFocusWidget = page->setOrderAfter (lastFocusWidget);
-    }
-}
-
-void VBoxVMSettingsParallelPage::putBackTo()
-{
-    for (int index = 0; index < mTabWidget->count(); ++ index)
-    {
-        VBoxVMSettingsParallel *page =
-            (VBoxVMSettingsParallel*) mTabWidget->widget (index);
-        Assert (page);
-        page->putBackToPort();
-    }
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsParallelPage::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Load port data: */
+    ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetParallelPortCount();
+    for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
+    {
+        /* Get port: */
+        const CParallelPort &port = m_machine.GetParallelPort(uSlot);
+
+        /* Prepare port's data container: */
+        UIParallelPortData data;
+
+        /* Load options: */
+        data.m_iSlot = uSlot;
+        data.m_fPortEnabled = port.GetEnabled();
+        data.m_uIRQ = port.GetIRQ();
+        data.m_uIOBase = port.GetIOBase();
+        data.m_strPath = port.GetPath();
+
+        /* Append adapter's data container: */
+        m_cache.m_items << data;
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsParallelPage::getFromCache()
+{
+    Assert(m_pFirstWidget);
+    setTabOrder(m_pFirstWidget, mTabWidget->focusProxy());
+    QWidget *pLastFocusWidget = mTabWidget->focusProxy();
+
+    /* Apply internal variables data to QWidget(s): */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Creating port's page: */
+        VBoxVMSettingsParallel *pPage = new VBoxVMSettingsParallel;
+
+        /* Loading port's data into page: */
+        pPage->fetchPortData(m_cache.m_items[iSlot]);
+
+        /* Attach port's page to Tab Widget: */
+        mTabWidget->addTab(pPage, pPage->pageTitle());
+
+        /* Setup page validation: */
+        pPage->setValidator(mValidator);
+
+        /* Setup tab order: */
+        pLastFocusWidget = pPage->setOrderAfter(pLastFocusWidget);
+    }
+
+    /* Applying language settings: */
+    retranslateUi();
+
+    /* Revalidate if possible: */
+    if (mValidator) mValidator->revalidate();
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsParallelPage::putToCache()
+{
+    /* Gather internal variables data from QWidget(s): */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Getting adapter's page: */
+        VBoxVMSettingsParallel *pPage = qobject_cast<VBoxVMSettingsParallel*>(mTabWidget->widget(iSlot));
+
+        /* Loading Adapter's data from page: */
+        pPage->uploadPortData(m_cache.m_items[iSlot]);
+    }
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsParallelPage::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Gather corresponding values from internal variables: */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Get adapter: */
+        CParallelPort &port = m_machine.GetParallelPort(iSlot);
+
+        /* Get cached data for this slot: */
+        const UIParallelPortData &data = m_cache.m_items[iSlot];
+
+        /* Save options: */
+        port.SetIRQ(data.m_uIRQ);
+        port.SetIOBase(data.m_uIOBase);
+        port.SetPath(data.m_strPath);
+        port.SetEnabled(data.m_fPortEnabled);
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsParallel.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsParallel.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsParallel.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -26,4 +26,19 @@
 class QITabWidget;
 
+struct UIParallelPortData
+{
+    int m_iSlot;
+    bool m_fPortEnabled;
+    ulong m_uIRQ;
+    ulong m_uIOBase;
+    QString m_strPath;
+};
+
+/* Machine settings / Parallel page / Cache: */
+struct UISettingsCacheMachineParallel
+{
+    QList<UIParallelPortData> m_items;
+};
+
 class VBoxVMSettingsParallel : public QIWithRetranslateUI<QWidget>,
                                public Ui::VBoxVMSettingsParallel
@@ -35,6 +50,6 @@
     VBoxVMSettingsParallel();
 
-    void getFromPort (const CParallelPort &aPort);
-    void putBackToPort();
+    void fetchPortData(const UIParallelPortData &data);
+    void uploadPortData(UIParallelPortData &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -57,8 +72,9 @@
 
     QIWidgetValidator *mValidator;
-    CParallelPort mPort;
+    int m_iSlot;
 };
 
-class VBoxVMSettingsParallelPage : public UISettingsPage
+/* Machine settings / Parallel page: */
+class VBoxVMSettingsParallelPage : public UISettingsPageMachine
 {
     Q_OBJECT;
@@ -70,6 +86,17 @@
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -82,4 +109,7 @@
     QIWidgetValidator *mValidator;
     QITabWidget *mTabWidget;
+
+    /* Internals: */
+    UISettingsCacheMachineParallel m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSF.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSF.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSF.cpp	(revision 33631)
@@ -165,7 +165,6 @@
 };
 
-VBoxVMSettingsSF::VBoxVMSettingsSF (int aType, QWidget *aParent)
-    : UISettingsPage (aParent)
-    , mDialogType (aType)
+VBoxVMSettingsSF::VBoxVMSettingsSF()
+    : m_type(WrongType)
     , mIsListViewChanged (false)
 {
@@ -209,28 +208,19 @@
              this, SLOT (showContextMenu (const QPoint &)));
 
-    /* Create mTwFolders root items */
-#if 0
-    if (aType == GlobalType)
-    {
-        QStringList fields;
-        fields << tr (" Global Folders") /* name */ << QString::number (GlobalType) /* key */;
-        new SFTreeViewItem (mTwFolders, fields, SFTreeViewItem::EllipsisEnd);
-    }
-#endif
-    if (aType & MachineType)
-    {
-        QStringList fields;
-        fields << tr (" Machine Folders") /* name */ << QString::number (MachineType) /* key */;
-        new SFTreeViewItem (mTwFolders, fields, SFTreeViewItem::EllipsisEnd);
-    }
-    if (aType & ConsoleType)
-    {
-        QStringList fields;
-        fields << tr (" Transient Folders") /* name */ << QString::number (ConsoleType) /* key */;
-        new SFTreeViewItem (mTwFolders, fields, SFTreeViewItem::EllipsisEnd);
-    }
-    mTwFolders->sortItems (0, Qt::AscendingOrder);
-
     retranslateUi();
+}
+
+void VBoxVMSettingsSF::loadDirectlyFrom(const CConsole &console)
+{
+    loadToCacheFromMachine(console.GetMachine());
+    loadToCacheFromConsole(console);
+    getFromCache();
+}
+
+void VBoxVMSettingsSF::saveDirectlyTo(CConsole &console)
+{
+    putToCache();
+    saveFromCacheToConsole(console);
+    saveFromCacheToMachine(console.GetMachine());
 }
 
@@ -241,85 +231,199 @@
 }
 
-void VBoxVMSettingsSF::getFromGlobal()
-{
-    AssertMsgFailed (("Global shared folders are not supported now!\n"));
-#if 0
-    SFTreeViewItem *root = searchRoot (true, GlobalType);
-    root->setHidden (false);
-    getFrom (vboxGlobal().virtualBox().GetSharedFolders(), root);
-#endif
-}
-
-void VBoxVMSettingsSF::getFromMachine (const CMachine &aMachine)
-{
-    mMachine = aMachine;
-    SFTreeViewItem *root = searchRoot (true, MachineType);
-    root->setHidden (false);
-    getFrom (mMachine.GetSharedFolders(), root);
-}
-
-void VBoxVMSettingsSF::getFromConsole (const CConsole &aConsole)
-{
-    mConsole = aConsole;
-    SFTreeViewItem *root = searchRoot (true, ConsoleType);
-    root->setHidden (false);
-    getFrom (mConsole.GetSharedFolders(), root);
-}
-
-void VBoxVMSettingsSF::putBackToGlobal()
-{
-    AssertMsgFailed (("Global shared folders are not supported now!\n"));
-#if 0
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsSF::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Fill internal variables with corresponding values: */
+    loadToCacheFromMachine(m_machine);
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
+}
+
+void VBoxVMSettingsSF::loadToCacheFromMachine(const CMachine &machine)
+{
+    /* Update dialog type: */
+    if (m_type == WrongType)
+        m_type = MachineType;
+    /* Load machine items into internal cache: */
+    loadToCacheFromVector(machine.GetSharedFolders(), MachineType);
+}
+
+void VBoxVMSettingsSF::loadToCacheFromConsole(const CConsole &console)
+{
+    /* Update dialog type: */
+    if (m_type == WrongType || m_type == MachineType)
+        m_type = ConsoleType;
+    /* Load console items into internal cache: */
+    loadToCacheFromVector(console.GetSharedFolders(), ConsoleType);
+}
+
+void VBoxVMSettingsSF::loadToCacheFromVector(const CSharedFolderVector &vector, UISharedFolderType type)
+{
+    /* Cache shared folders in internal variables: */
+    for (int iFolderIndex = 0; iFolderIndex < vector.size(); ++iFolderIndex)
+    {
+        const CSharedFolder &folder = vector[iFolderIndex];
+        UISharedFolderData data;
+        data.m_type = type;
+        data.m_strName = folder.GetName();
+        data.m_strHostPath = folder.GetHostPath();
+        data.m_fAutoMount = folder.GetAutoMount();
+        data.m_fWritable = folder.GetWritable();
+        m_cache.m_items << data;
+    }
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsSF::getFromCache()
+{
+    /* Apply internal variables data to QWidget(s): */
+    if (m_type == MachineType || m_type == ConsoleType)
+        root(MachineType);
+    if (m_type == ConsoleType)
+        root(ConsoleType);
+    for (int iFolderIndex = 0; iFolderIndex < m_cache.m_items.size(); ++iFolderIndex)
+    {
+        /* Get iterated folder's data: */
+        const UISharedFolderData &data = m_cache.m_items[iFolderIndex];
+        /* Prepare list item's fields: */
+        QStringList fields;
+        fields << data.m_strName << data.m_strHostPath
+               << (data.m_fAutoMount ? mTrYes : "")
+               << (data.m_fWritable ? mTrFull : mTrReadOnly);
+        /* Searching for item's root: */
+        SFTreeViewItem *pItemsRoot = root(data.m_type);
+        /* Create new folder list item: */
+        new SFTreeViewItem(pItemsRoot, fields, SFTreeViewItem::EllipsisFile);
+    }
+    /* Sort populated item's list: */
+    mTwFolders->sortItems(0, Qt::AscendingOrder);
+    /* Ensure current item fetched: */
+    mTwFolders->setCurrentItem(mTwFolders->topLevelItem(0));
+    processCurrentChanged(mTwFolders->currentItem());
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsSF::putToCache()
+{
+    /* Reset cache: */
+    m_cache.m_items.clear();
+    /* Gather internal variables data from QWidget(s): */
+    QTreeWidgetItem *pMainRootItem = mTwFolders->invisibleRootItem();
+    /* Iterate other all the list top-level items: */
+    for (int iFodlersTypeIndex = 0; iFodlersTypeIndex < pMainRootItem->childCount(); ++iFodlersTypeIndex)
+    {
+        SFTreeViewItem *pFolderTypeRoot = static_cast<SFTreeViewItem*>(pMainRootItem->child(iFodlersTypeIndex));
+        UISharedFolderType type = (UISharedFolderType)pFolderTypeRoot->text(1).toInt();
+        AssertMsg(type != WrongType, ("Incorrent folders type!"));
+        /* Iterate other all the folder items: */
+        for (int iFoldersIndex = 0; iFoldersIndex < pFolderTypeRoot->childCount(); ++iFoldersIndex)
+        {
+            SFTreeViewItem *pFolderItem = static_cast<SFTreeViewItem*>(pFolderTypeRoot->child(iFoldersIndex));
+            UISharedFolderData data;
+            data.m_type = type;
+            data.m_strName = pFolderItem->getText(0);
+            data.m_strHostPath = pFolderItem->getText(1);
+            data.m_fAutoMount = pFolderItem->getText(2) == mTrYes ? true : false;
+            data.m_fWritable = pFolderItem->getText(3) == mTrFull ? true : false;
+            m_cache.m_items << data;
+        }
+    }
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsSF::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Gather corresponding values from internal variables: */
+    saveFromCacheToMachine(m_machine);
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
+}
+
+void VBoxVMSettingsSF::saveFromCacheToMachine(CMachine &machine)
+{
+    /* Save machine items from internal cache: */
+    /* Check if items were changed: */
     if (!mIsListViewChanged)
         return;
-    /* This function is only available for GlobalType dialog */
-    Assert (mDialogType == GlobalType);
-    /* Searching for GlobalType item's root */
-    SFTreeViewItem *root = searchRoot (true, GlobalType);
-    Assert (root);
-    CSharedFolderVector vec = vboxGlobal().virtualBox().GetSharedFolders();
-    putBackTo (vec, root);
-#endif
-}
-
-void VBoxVMSettingsSF::putBackToMachine()
-{
+
+    /* Delete all machine folders first: */
+    const CSharedFolderVector &folders = machine.GetSharedFolders();
+    for (int iFolderIndex = 0; iFolderIndex < folders.size(); ++iFolderIndex)
+    {
+        const CSharedFolder &folder = folders[iFolderIndex];
+        QString strFolderName = folder.GetName();
+        QString strFolderPath = folder.GetHostPath();
+        machine.RemoveSharedFolder(strFolderName);
+        if (!machine.isOk())
+        {
+            // TODO: Fix problem reporter!
+            //vboxProblem().cannotRemoveSharedFolder(this, machine, strFolderName, strFolderPath);
+        }
+    }
+
+    /* Save all new machine folders: */
+    for (int iFolderIndex = 0; iFolderIndex < m_cache.m_items.size(); ++iFolderIndex)
+    {
+        const UISharedFolderData &data = m_cache.m_items[iFolderIndex];
+        if (data.m_type == MachineType)
+        {
+            machine.CreateSharedFolder(data.m_strName, data.m_strHostPath, data.m_fWritable, data.m_fAutoMount);
+            if (!machine.isOk())
+            {
+                // TODO: Fix problem reporter!
+                //vboxProblem().cannotCreateSharedFolder(this, machine, data.m_strName, data.m_strHostPath);
+            }
+        }
+    }
+}
+
+void VBoxVMSettingsSF::saveFromCacheToConsole(CConsole &console)
+{
+    /* Save console items from internal cache: */
+    /* Check if items were changed: */
     if (!mIsListViewChanged)
         return;
-    /* This function is only available for MachineType dialog */
-    Assert (mDialogType & MachineType);
-    /* Searching for MachineType item's root */
-    SFTreeViewItem *root = searchRoot (true,  MachineType);
-    Assert (root);
-    CSharedFolderVector sfvec = mMachine.GetSharedFolders();
-    putBackTo (sfvec, root);
-}
-
-void VBoxVMSettingsSF::putBackToConsole()
-{
-    if (!mIsListViewChanged)
-        return;
-    /* This function is only available for ConsoleType dialog */
-    Assert (mDialogType & ConsoleType);
-    /* Searching for ConsoleType item's root */
-    SFTreeViewItem *root = searchRoot (true, ConsoleType);
-    Assert (root);
-    CSharedFolderVector sfvec = mConsole.GetSharedFolders();
-    putBackTo (sfvec, root);
-}
-
-int VBoxVMSettingsSF::dialogType() const
-{
-     return mDialogType;
-}
-
-void VBoxVMSettingsSF::getFrom (const CMachine &aMachine)
-{
-    getFromMachine (aMachine);
-}
-
-void VBoxVMSettingsSF::putBackTo()
-{
-    putBackToMachine();
+
+    /* Delete all console folders first: */
+    const CSharedFolderVector &folders = console.GetSharedFolders();
+    for (int iFolderIndex = 0; iFolderIndex < folders.size(); ++iFolderIndex)
+    {
+        const CSharedFolder &folder = folders[iFolderIndex];
+        QString strFolderName = folder.GetName();
+        QString strFolderPath = folder.GetHostPath();
+        console.RemoveSharedFolder(strFolderName);
+        if (!console.isOk())
+        {
+            // TODO: Fix problem reporter!
+            //vboxProblem().cannotRemoveSharedFolder(this, console, strFolderName, strFolderPath);
+        }
+    }
+
+    /* Save all new console folders: */
+    for (int iFolderIndex = 0; iFolderIndex < m_cache.m_items.size(); ++iFolderIndex)
+    {
+        const UISharedFolderData &data = m_cache.m_items[iFolderIndex];
+        if (data.m_type == ConsoleType)
+        {
+            console.CreateSharedFolder(data.m_strName, data.m_strHostPath, data.m_fWritable, data.m_fAutoMount);
+            if (!console.isOk())
+            {
+                // TODO: Fix problem reporter!
+                //vboxProblem().cannotCreateSharedFolder(this, console, data.m_strName, data.m_strHostPath);
+            }
+        }
+    }
 }
 
@@ -357,5 +461,5 @@
 {
     /* Invoke Add-Box Dialog */
-    VBoxVMSettingsSFDetails dlg (VBoxVMSettingsSFDetails::AddType, mDialogType & ConsoleType, usedList (true), this);
+    VBoxVMSettingsSFDetails dlg (VBoxVMSettingsSFDetails::AddType, m_type == ConsoleType, usedList (true), this);
     if (dlg.exec() == QDialog::Accepted)
     {
@@ -366,13 +470,12 @@
         Assert (!name.isEmpty() && !path.isEmpty());
         /* Searching root for the new listview item */
-        SFTreeViewItem *root = searchRoot (isPermanent);
-        Assert (root);
+        SFTreeViewItem *pRoot = root(isPermanent ? MachineType : ConsoleType);
+        Assert (pRoot);
         /* Appending a new listview item to the root */
         QStringList fields;
         fields << name /* name */ << path /* path */
                << (dlg.isAutoMounted() ? mTrYes : "" /* auto mount? */)
-               << (dlg.isWriteable() ? mTrFull : mTrReadOnly /* writable? */)
-               << "edited" /* mark item as edited */;
-        SFTreeViewItem *item = new SFTreeViewItem (root, fields, SFTreeViewItem::EllipsisFile);
+               << (dlg.isWriteable() ? mTrFull : mTrReadOnly /* writable? */);
+        SFTreeViewItem *item = new SFTreeViewItem (pRoot, fields, SFTreeViewItem::EllipsisFile);
         mTwFolders->sortItems (0, Qt::AscendingOrder);
         mTwFolders->scrollToItem (item);
@@ -396,8 +499,8 @@
 
     /* Invoke Edit-Box Dialog */
-    VBoxVMSettingsSFDetails dlg (VBoxVMSettingsSFDetails::EditType, mDialogType & ConsoleType, usedList (false), this);
+    VBoxVMSettingsSFDetails dlg (VBoxVMSettingsSFDetails::EditType, m_type == ConsoleType, usedList (false), this);
     dlg.setPath (item->getText (1));
     dlg.setName (item->getText (0));
-    dlg.setPermanent ((SFDialogType)item->parent()->text (1).toInt() != ConsoleType);
+    dlg.setPermanent ((UISharedFolderType)item->parent()->text (1).toInt() != ConsoleType);
     dlg.setAutoMount (item->getText (2) == mTrYes);
     dlg.setWriteable (item->getText (3) == mTrFull);
@@ -410,19 +513,18 @@
         Assert (!name.isEmpty() && !path.isEmpty());
         /* Searching new root for the selected listview item */
-        SFTreeViewItem *root = searchRoot (isPermanent);
-        Assert (root);
+        SFTreeViewItem *pRoot = root(isPermanent ? MachineType : ConsoleType);
+        Assert (pRoot);
         /* Updating an edited listview item */
         QStringList fields;
         fields << name /* name */ << path /* path */
                << (dlg.isAutoMounted() ? mTrYes : "" /* auto mount? */)
-               << (dlg.isWriteable() ? mTrFull : mTrReadOnly /* writable? */)
-               << "edited" /* mark item as edited */;
+               << (dlg.isWriteable() ? mTrFull : mTrReadOnly /* writable? */);
         item->updateText (fields);
         mTwFolders->sortItems (0, Qt::AscendingOrder);
-        if (item->parent() != root)
+        if (item->parent() != pRoot)
         {
             /* Move the selected item into new location */
             item->parent()->takeChild (item->parent()->indexOfChild (item));
-            root->insertChild (root->childCount(), item);
+            pRoot->insertChild (pRoot->childCount(), item);
             mTwFolders->scrollToItem (item);
             mTwFolders->setCurrentItem (item);
@@ -451,5 +553,5 @@
     QString key = !aCurrentItem ? QString::null : aCurrentItem->parent() ?
                   aCurrentItem->parent()->text (1) : aCurrentItem->text (1);
-    bool addEnabled = aCurrentItem && isEditable (key);
+    bool addEnabled = aCurrentItem;
     bool removeEnabled = addEnabled && aCurrentItem->parent();
     mNewAction->setEnabled (addEnabled);
@@ -460,5 +562,5 @@
 void VBoxVMSettingsSF::processDoubleClick (QTreeWidgetItem *aItem)
 {
-    bool editEnabled = aItem && aItem->parent() && isEditable (aItem->parent()->text (1));
+    bool editEnabled = aItem && aItem->parent();
     if (editEnabled)
         edtTriggered();
@@ -540,152 +642,50 @@
 }
 
-void VBoxVMSettingsSF::createSharedFolder (const QString &aName, const QString &aPath,
-                                           bool aWritable, bool aAutoMount, SFDialogType aType)
-{
-    switch (aType)
-    {
-        case GlobalType:
-        {
-            /* This feature is not supported now */
-            AssertMsgFailed (("Global shared folders are not supported now!\n"));
+SFTreeViewItem* VBoxVMSettingsSF::root(UISharedFolderType type)
+{
+    /* Prepare empty item: */
+    SFTreeViewItem *pRootItem = 0;
+    /* Get top-level root item: */
+    QTreeWidgetItem *pMainRootItem = mTwFolders->invisibleRootItem();
+    /* Iterate other the all root items: */
+    for (int iFolderTypeIndex = 0; iFolderTypeIndex < pMainRootItem->childCount(); ++iFolderTypeIndex)
+    {
+        /* Get iterated item: */
+        QTreeWidgetItem *pIteratedItem = pMainRootItem->child(iFolderTypeIndex);
+        /* If iterated item's type is what we are looking for: */
+        if (pIteratedItem->text(1).toInt() == type)
+        {
+            /* Remember the item: */
+            pRootItem = static_cast<SFTreeViewItem*>(pIteratedItem);
+            /* And break further search: */
             break;
         }
-        case MachineType:
-        {
-            Assert (!mMachine.isNull());
-            mMachine.CreateSharedFolder (aName, aPath, aWritable, aAutoMount);
-            if (!mMachine.isOk())
-                vboxProblem().cannotCreateSharedFolder (this, mMachine, aName, aPath);
-            break;
-        }
-        case ConsoleType:
-        {
-            Assert (!mConsole.isNull());
-            mConsole.CreateSharedFolder (aName, aPath, aWritable, aAutoMount);
-            if (!mConsole.isOk())
-                vboxProblem().cannotCreateSharedFolder (this, mConsole, aName, aPath);
-            break;
-        }
-        default:
-        {
-            AssertMsgFailed (("Incorrect shared folder type\n"));
-        }
-    }
-}
-
-void VBoxVMSettingsSF::removeSharedFolder (const QString &aName, const QString &aPath, SFDialogType aType)
-{
-    switch (aType)
-    {
-        case GlobalType:
-        {
-            /* This feature is not supported now */
-            AssertMsgFailed (("Global shared folders are not supported now!\n"));
-            break;
-        }
-        case MachineType:
-        {
-            Assert (!mMachine.isNull());
-            mMachine.RemoveSharedFolder (aName);
-            if (!mMachine.isOk())
-                vboxProblem().cannotRemoveSharedFolder (this, mMachine, aName, aPath);
-            break;
-        }
-        case ConsoleType:
-        {
-            Assert (!mConsole.isNull());
-            mConsole.RemoveSharedFolder (aName);
-            if (!mConsole.isOk())
-                vboxProblem().cannotRemoveSharedFolder (this, mConsole, aName, aPath);
-            break;
-        }
-        default:
-        {
-            AssertMsgFailed (("Incorrect shared folder type\n"));
-        }
-    }
-}
-
-void VBoxVMSettingsSF::getFrom (const CSharedFolderVector &aVec, SFTreeViewItem *aRoot)
-{
-    for (int i = 0; i < aVec.size(); ++ i)
-    {
-        CSharedFolder sf = aVec [i];
+    }
+    /* If root item we are looking for still not found: */
+    if (!pRootItem)
+    {
+        /* Preparing fields: */
         QStringList fields;
-        fields << sf.GetName() /* name */ << sf.GetHostPath() /* path */
-               << (sf.GetAutoMount() ? mTrYes : "") /* auto mount? */
-               << (sf.GetWritable() ? mTrFull : mTrReadOnly) /* writable? */
-               << "not edited" /* initially not edited */;
-        new SFTreeViewItem (aRoot, fields, SFTreeViewItem::EllipsisFile);
-    }
-    aRoot->setExpanded (true);
-    mTwFolders->sortItems (0, Qt::AscendingOrder);
-    mTwFolders->setCurrentItem (aRoot->childCount() ? aRoot->child (0) : aRoot);
-    processCurrentChanged (aRoot->childCount() ? aRoot->child (0) : aRoot);
-}
-
-void VBoxVMSettingsSF::putBackTo (CSharedFolderVector &aVec, SFTreeViewItem *aRoot)
-{
-    Assert (!aRoot->text (1).isNull());
-    SFDialogType type = (SFDialogType) aRoot->text (1).toInt();
-
-    /** @todo Use enums rather than numbers for the text fields (like  item->getText (4)). */
-
-    /* Delete all changed folders from vm */
-    for (int idx = 0; idx < aVec.size(); ++ idx)
-    {
-        CSharedFolder sf = aVec [idx];
-
-        /* Iterate through this root's children */
-        int i = 0;
-        for (; i < aRoot->childCount(); ++ i)
-        {
-            SFTreeViewItem *item = aRoot->child (i);
-            if (item->getText (0) == sf.GetName() && item->getText (4) == "not edited")
+        /* Depending on folder type: */
+        switch (type)
+        {
+            case MachineType:
+                fields << tr(" Machine Folders") << QString::number(MachineType);
                 break;
-        }
-
-        if (i == aRoot->childCount())
-            removeSharedFolder (sf.GetName(), sf.GetHostPath(), type);
-    }
-
-    /* Save all edited tree widget items as folders */
-    for (int i = 0; i < aRoot->childCount(); ++ i)
-    {
-        SFTreeViewItem *item = aRoot->child (i);
-
-        if (!item->getText (0).isNull() && !item->getText (1).isNull() && item->getText (4) == "edited")
-            createSharedFolder (item->getText (0), item->getText (1),
-                                item->getText (3) == mTrFull ? true : false, item->getText (2) == mTrYes ? true : false,
-                                type);
-    }
-}
-
-SFTreeViewItem* VBoxVMSettingsSF::searchRoot (bool aIsPermanent, SFDialogType aType)
-{
-    QString type = aType != WrongType ? QString::number (aType) : !aIsPermanent ? QString::number (ConsoleType) :
-                   mDialogType & MachineType ? QString::number (MachineType) : QString::number (GlobalType);
-    QTreeWidgetItem *mainRoot = mTwFolders->invisibleRootItem();
-
-    int i = 0;
-    for (; i < mainRoot->childCount(); ++ i)
-    {
-        if (mainRoot->child (i)->text (1) == type)
-            break;
-    }
-
-    Assert (i < mainRoot->childCount());
-    return i < mainRoot->childCount() && mainRoot->child (i)->type() == SFTreeViewItem::SFTreeViewItemType ?
-           static_cast <SFTreeViewItem*> (mainRoot->child (i)) : 0;
-}
-
-bool VBoxVMSettingsSF::isEditable (const QString &aKey)
-{
-    /* mDialogType should be correct */
-    Assert (mDialogType);
-
-    SFDialogType type = (SFDialogType) aKey.toInt();
-    if (!type) return false;
-    return mDialogType & type;
+            case ConsoleType:
+                fields << tr(" Transient Folders") << QString::number(ConsoleType);
+                break;
+            default:
+                break;
+        }
+        /* Creating root: */
+        pRootItem = new SFTreeViewItem(mTwFolders, fields, SFTreeViewItem::EllipsisEnd);
+        /* We should show it (its not?): */
+        pRootItem->setHidden(false);
+        /* Expand it: */
+        pRootItem->setExpanded(true);
+    }
+    /* Return root item: */
+    return pRootItem;
 }
 
@@ -701,5 +701,5 @@
         {
             SFTreeViewItem *item = static_cast <SFTreeViewItem*> (*it);
-            SFDialogType type = (SFDialogType) item->parent()->text (1).toInt();
+            UISharedFolderType type = (UISharedFolderType) item->parent()->text (1).toInt();
             list << qMakePair (item->getText (0), type);
         }
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSF.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSF.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSF.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2008-2009 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -27,15 +27,32 @@
 class SFTreeViewItem;
 
-enum SFDialogType
+enum UISharedFolderType
 {
     WrongType   = 0x00,
-    GlobalType  = 0x01,
-    MachineType = 0x02,
-    ConsoleType = 0x04
+    MachineType = 0x01,
+    ConsoleType = 0x02
 };
-typedef QPair <QString, SFDialogType> SFolderName;
+typedef QPair <QString, UISharedFolderType> SFolderName;
 typedef QList <SFolderName> SFoldersNameList;
 
-class VBoxVMSettingsSF : public UISettingsPage, public Ui::VBoxVMSettingsSF
+/* Machine settings / Shared Folders page / Folder data: */
+struct UISharedFolderData
+{
+    UISharedFolderType m_type;
+    QString m_strName;
+    QString m_strHostPath;
+    bool m_fAutoMount;
+    bool m_fWritable;
+    bool m_fEdited;
+};
+
+/* Machine settings / Shared Folders page / Cache: */
+struct UISettingsCacheMachineSFolders
+{
+    QList<UISharedFolderData> m_items;
+};
+
+class VBoxVMSettingsSF : public UISettingsPageMachine,
+                         public Ui::VBoxVMSettingsSF
 {
     Q_OBJECT;
@@ -43,20 +60,29 @@
 public:
 
-    VBoxVMSettingsSF (int aType = WrongType, QWidget *aParent = 0);
+    VBoxVMSettingsSF();
 
-    void getFromGlobal();
-    void getFromMachine (const CMachine &aMachine);
-    void getFromConsole (const CConsole &aConsole);
-
-    void putBackToGlobal();
-    void putBackToMachine();
-    void putBackToConsole();
-
-    int dialogType() const;
+    void loadDirectlyFrom(const CConsole &console);
+    void saveDirectlyTo(CConsole &console);
 
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    void loadToCacheFromMachine(const CMachine &machine);
+    void loadToCacheFromConsole(const CConsole &console);
+    void loadToCacheFromVector(const CSharedFolderVector &vector, UISharedFolderType type);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
+    void saveFromCacheToMachine(CMachine &machine);
+    void saveFromCacheToConsole(CConsole &console);
 
     void setOrderAfter (QWidget *aWidget);
@@ -83,24 +109,19 @@
     void showEvent (QShowEvent *aEvent);
 
-    void createSharedFolder (const QString &aName, const QString &aPath, bool aWritable, bool aAutoMount, SFDialogType aType);
-    void removeSharedFolder (const QString &aName, const QString &aPath, SFDialogType aType);
-
-    void getFrom (const CSharedFolderVector &aVec, SFTreeViewItem *aItem);
-    void putBackTo (CSharedFolderVector &aVec, SFTreeViewItem *aItem);
-
-    SFTreeViewItem* searchRoot (bool aIsPermanent, SFDialogType aType = WrongType);
-    bool isEditable (const QString &aKey);
+    SFTreeViewItem* root(UISharedFolderType type);
     SFoldersNameList usedList (bool aIncludeSelected);
 
-    int       mDialogType;
+    UISharedFolderType m_type;
+
     QAction  *mNewAction;
     QAction  *mEdtAction;
     QAction  *mDelAction;
     bool      mIsListViewChanged;
-    CMachine  mMachine;
-    CConsole  mConsole;
     QString   mTrFull;
     QString   mTrReadOnly;
     QString   mTrYes;
+
+    /* Cache: */
+    UISettingsCacheMachineSFolders m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSFDetails.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSFDetails.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSFDetails.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -140,7 +140,6 @@
 void VBoxVMSettingsSFDetails::validate()
 {
-    SFDialogType resultType =
-        mCbPermanent && !mCbPermanent->isChecked() ? ConsoleType :
-        mType & MachineType ? MachineType : GlobalType;
+    UISharedFolderType resultType =
+        mUsePermanent && !mCbPermanent->isChecked() ? ConsoleType : MachineType;
     SFolderName pair = qMakePair (mLeName->text(), resultType);
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSFDetails.ui
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSFDetails.ui	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSFDetails.ui	(revision 33631)
@@ -3,5 +3,5 @@
  VBox frontends: Qt4 GUI ("VirtualBox"):
 
-     Copyright (C) 2008 Oracle Corporation
+     Copyright (C) 2008-2010 Oracle Corporation
 
      This file is part of VirtualBox Open Source Edition (OSE), as
@@ -79,4 +79,7 @@
    <item row="4" column="1" >
     <widget class="QCheckBox" name="mCbPermanent" >
+     <property name="toolTip" >
+      <string>If checked, this shared folder will be permanent.</string>
+     </property>
      <property name="text" >
       <string>&amp;Make Permanent</string>
@@ -84,5 +87,5 @@
     </widget>
    </item>
-   <item row="4" column="1" >
+   <item row="5" column="1" >
     <spacer>
      <property name="orientation" >
@@ -97,5 +100,5 @@
     </spacer>
    </item>
-   <item row="5" column="0" colspan="2" >
+   <item row="6" column="0" colspan="2" >
     <widget class="QIDialogButtonBox" name="mButtonBox" >
      <property name="standardButtons" >
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSerial.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSerial.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSerial.cpp	(revision 33631)
@@ -29,4 +29,5 @@
     : QIWithRetranslateUI<QWidget> (0)
     , mValidator (0)
+    , m_iSlot(-1)
 {
     /* Apply UI decorations */
@@ -64,35 +65,31 @@
 }
 
-void VBoxVMSettingsSerial::getFromPort (const CSerialPort &aPort)
-{
-    mPort = aPort;
-
-    mGbSerial->setChecked (mPort.GetEnabled());
-    ulong IRQ = mPort.GetIRQ();
-    ulong IOBase = mPort.GetIOBase();
-    mCbNumber->setCurrentIndex (mCbNumber->
-        findText (vboxGlobal().toCOMPortName (IRQ, IOBase)));
-    mLeIRQ->setText (QString::number (IRQ));
-    mLeIOPort->setText ("0x" + QString::number (IOBase, 16).toUpper());
-    mCbMode->setCurrentIndex (mCbMode->
-        findText (vboxGlobal().toString (mPort.GetHostMode())));
-    mCbPipe->setChecked (mPort.GetServer());
-    mLePath->setText (mPort.GetPath());
+void VBoxVMSettingsSerial::fetchPortData(const UISerialPortData &data)
+{
+    /* Load port slot number: */
+    m_iSlot = data.m_iSlot;
+
+    /* Fetch port data: */
+    mGbSerial->setChecked(data.m_fPortEnabled);
+    mCbNumber->setCurrentIndex(mCbNumber->findText(vboxGlobal().toCOMPortName(data.m_uIRQ, data.m_uIOBase)));
+    mLeIRQ->setText(QString::number(data.m_uIRQ));
+    mLeIOPort->setText("0x" + QString::number(data.m_uIOBase, 16).toUpper());
+    mCbMode->setCurrentIndex(mCbMode->findText(vboxGlobal().toString(data.m_hostMode)));
+    mCbPipe->setChecked(data.m_fServer);
+    mLePath->setText(data.m_strPath);
 
     /* Ensure everything is up-to-date */
-    mGbSerialToggled (mGbSerial->isChecked());
-}
-
-void VBoxVMSettingsSerial::putBackToPort()
-{
-    mPort.SetEnabled (mGbSerial->isChecked());
-    mPort.SetIRQ (mLeIRQ->text().toULong (NULL, 0));
-    mPort.SetIOBase (mLeIOPort->text().toULong (NULL, 0));
-    mPort.SetServer (mCbPipe->isChecked());
-    mPort.SetPath (QDir::toNativeSeparators (mLePath->text()));
-    /* This *must* be last. The host mode will be changed to disconnected if
-     * some of the necessary settings above will not meet the requirements for
-     * the selected mode. */
-    mPort.SetHostMode (vboxGlobal().toPortMode (mCbMode->currentText()));
+    mGbSerialToggled(mGbSerial->isChecked());
+}
+
+void VBoxVMSettingsSerial::uploadPortData(UISerialPortData &data)
+{
+    /* Upload port data: */
+    data.m_fPortEnabled = mGbSerial->isChecked();
+    data.m_uIRQ = mLeIRQ->text().toULong(NULL, 0);
+    data.m_uIOBase = mLeIOPort->text().toULong (NULL, 0);
+    data.m_fServer = mCbPipe->isChecked();
+    data.m_hostMode = vboxGlobal().toPortMode(mCbMode->currentText());
+    data.m_strPath = QDir::toNativeSeparators(mLePath->text());
 }
 
@@ -124,11 +121,5 @@
 QString VBoxVMSettingsSerial::pageTitle() const
 {
-    QString pageTitle;
-    if (!mPort.isNull())
-    {
-        pageTitle = QString (tr ("Port %1", "serial ports"))
-            .arg (QString ("&%1").arg (mPort.GetSlot() + 1));
-    }
-    return pageTitle;
+    return QString(tr("Port %1", "serial ports")).arg(QString("&%1").arg(m_iSlot + 1));
 }
 
@@ -202,34 +193,117 @@
 }
 
-void VBoxVMSettingsSerialPage::getFrom (const CMachine &aMachine)
-{
-    Assert (m_pFirstWidget);
-    setTabOrder (m_pFirstWidget, mTabWidget->focusProxy());
-    QWidget *lastFocusWidget = mTabWidget->focusProxy();
-
-    /* Tab pages loading */
-    ulong count = vboxGlobal().virtualBox().
-                  GetSystemProperties().GetSerialPortCount();
-    for (ulong slot = 0; slot < count; ++ slot)
-    {
-        CSerialPort port = aMachine.GetSerialPort (slot);
-        VBoxVMSettingsSerial *page = new VBoxVMSettingsSerial();
-        page->getFromPort (port);
-        mTabWidget->addTab (page, page->pageTitle());
-        Assert (mValidator);
-        page->setValidator (mValidator);
-        lastFocusWidget = page->setOrderAfter (lastFocusWidget);
-    }
-}
-
-void VBoxVMSettingsSerialPage::putBackTo()
-{
-    for (int index = 0; index < mTabWidget->count(); ++ index)
-    {
-        VBoxVMSettingsSerial *page =
-            (VBoxVMSettingsSerial*) mTabWidget->widget (index);
-        Assert (page);
-        page->putBackToPort();
-    }
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsSerialPage::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Load port data: */
+    ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetSerialPortCount();
+    for (ulong uSlot = 0; uSlot < uCount; ++uSlot)
+    {
+        /* Get port: */
+        const CSerialPort &port = m_machine.GetSerialPort(uSlot);
+
+        /* Prepare port's data container: */
+        UISerialPortData data;
+
+        /* Load options: */
+        data.m_iSlot = uSlot;
+        data.m_fPortEnabled = port.GetEnabled();
+        data.m_uIRQ = port.GetIRQ();
+        data.m_uIOBase = port.GetIOBase();
+        data.m_hostMode = port.GetHostMode();
+        data.m_fServer = port.GetServer();
+        data.m_strPath = port.GetPath();
+
+        /* Append adapter's data container: */
+        m_cache.m_items << data;
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsSerialPage::getFromCache()
+{
+    Assert(m_pFirstWidget);
+    setTabOrder(m_pFirstWidget, mTabWidget->focusProxy());
+    QWidget *pLastFocusWidget = mTabWidget->focusProxy();
+
+    /* Apply internal variables data to QWidget(s): */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Creating port's page: */
+        VBoxVMSettingsSerial *pPage = new VBoxVMSettingsSerial;
+
+        /* Loading port's data into page: */
+        pPage->fetchPortData(m_cache.m_items[iSlot]);
+
+        /* Attach port's page to Tab Widget: */
+        mTabWidget->addTab(pPage, pPage->pageTitle());
+
+        /* Setup page validation: */
+        pPage->setValidator(mValidator);
+
+        /* Setup tab order: */
+        pLastFocusWidget = pPage->setOrderAfter(pLastFocusWidget);
+    }
+
+    /* Applying language settings: */
+    retranslateUi();
+
+    /* Revalidate if possible: */
+    if (mValidator) mValidator->revalidate();
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsSerialPage::putToCache()
+{
+    /* Gather internal variables data from QWidget(s): */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Getting adapter's page: */
+        VBoxVMSettingsSerial *pPage = qobject_cast<VBoxVMSettingsSerial*>(mTabWidget->widget(iSlot));
+
+        /* Loading Adapter's data from page: */
+        pPage->uploadPortData(m_cache.m_items[iSlot]);
+    }
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsSerialPage::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Gather corresponding values from internal variables: */
+    for (int iSlot = 0; iSlot < m_cache.m_items.size(); ++iSlot)
+    {
+        /* Get adapter: */
+        CSerialPort &port = m_machine.GetSerialPort(iSlot);
+
+        /* Get cached data for this slot: */
+        const UISerialPortData &data = m_cache.m_items[iSlot];
+
+        /* Save options: */
+        port.SetEnabled(data.m_fPortEnabled);
+        port.SetIRQ(data.m_uIRQ);
+        port.SetIOBase(data.m_uIOBase);
+        port.SetServer(data.m_fServer);
+        port.SetPath(data.m_strPath);
+        /* This *must* be last. The host mode will be changed to disconnected if
+         * some of the necessary settings above will not meet the requirements for
+         * the selected mode. */
+        port.SetHostMode(data.m_hostMode);
+    }
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSerial.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSerial.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSerial.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -26,4 +26,22 @@
 class QITabWidget;
 
+/* Machine settings / Network page / Port data: */
+struct UISerialPortData
+{
+    int m_iSlot;
+    bool m_fPortEnabled;
+    ulong m_uIRQ;
+    ulong m_uIOBase;
+    KPortMode m_hostMode;
+    bool m_fServer;
+    QString m_strPath;
+};
+
+/* Machine settings / Serial page / Cache: */
+struct UISettingsCacheMachineSerial
+{
+    QList<UISerialPortData> m_items;
+};
+
 class VBoxVMSettingsSerial : public QIWithRetranslateUI<QWidget>,
                              public Ui::VBoxVMSettingsSerial
@@ -35,6 +53,6 @@
     VBoxVMSettingsSerial();
 
-    void getFromPort (const CSerialPort &aPort);
-    void putBackToPort();
+    void fetchPortData(const UISerialPortData &data);
+    void uploadPortData(UISerialPortData &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -58,8 +76,9 @@
 
     QIWidgetValidator *mValidator;
-    CSerialPort mPort;
+    int m_iSlot;
 };
 
-class VBoxVMSettingsSerialPage : public UISettingsPage
+/* Machine settings / Serial page: */
+class VBoxVMSettingsSerialPage : public UISettingsPageMachine
 {
     Q_OBJECT;
@@ -71,6 +90,17 @@
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -83,4 +113,7 @@
     QIWidgetValidator *mValidator;
     QITabWidget *mTabWidget;
+
+    /* Cache: */
+    UISettingsCacheMachineSerial m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.cpp	(revision 33631)
@@ -36,8 +36,39 @@
 
     /* Setup constants */
-    CSystemProperties sys = vboxGlobal().virtualBox().GetSystemProperties();
+    CSystemProperties properties = vboxGlobal().virtualBox().GetSystemProperties();
     uint hostCPUs = vboxGlobal().virtualBox().GetHost().GetProcessorCount();
-    mMinGuestCPU = sys.GetMinGuestCPUCount();
-    mMaxGuestCPU = RT_MIN (2 * hostCPUs, sys.GetMaxGuestCPUCount());
+    mMinGuestCPU = properties.GetMinGuestCPUCount();
+    mMaxGuestCPU = RT_MIN (2 * hostCPUs, properties.GetMaxGuestCPUCount());
+
+    /* Populate possible boot items list.
+     * Currently, it seems, we are supporting only 4 possible boot device types:
+     * 1. Floppy, 2. DVD-ROM, 3. Hard Disk, 4. Network.
+     * But maximum boot devices count supported by machine
+     * should be retreived through the ISystemProperties getter.
+     * Moreover, possible boot device types are not listed in some separate Main vector,
+     * so we should get them (randomely?) from the list of all device types.
+     * Until there will be separate Main getter for list of supported boot device types,
+     * this list will be hard-coded here... */
+    int iPossibleBootListSize = qMin((ulong)4, properties.GetMaxBootPosition());
+    for (int iBootPosition = 1; iBootPosition <= iPossibleBootListSize; ++iBootPosition)
+    {
+        switch (iBootPosition)
+        {
+            case 1:
+                m_possibleBootItems << KDeviceType_Floppy;
+                break;
+            case 2:
+                m_possibleBootItems << KDeviceType_DVD;
+                break;
+            case 3:
+                m_possibleBootItems << KDeviceType_HardDisk;
+                break;
+            case 4:
+                m_possibleBootItems << KDeviceType_Network;
+                break;
+            default:
+                break;
+        }
+    }
 
     /* Setup validators */
@@ -101,4 +132,7 @@
     /* Ensure mLeMemory value and validation is updated */
     valueChangedCPU (mSlCPU->value());
+    /* Populate chipset combo: */
+    mCbChipset->insertItem(0, vboxGlobal().toString(KChipsetType_PIIX3), QVariant(KChipsetType_PIIX3));
+    mCbChipset->insertItem(1, vboxGlobal().toString(KChipsetType_ICH9), QVariant(KChipsetType_ICH9));
 
     /* Install global event filter */
@@ -124,147 +158,153 @@
 }
 
-void VBoxVMSettingsSystem::getFrom (const CMachine &aMachine)
-{
-    mMachine = aMachine;
-    CBIOSSettings biosSettings = mMachine.GetBIOSSettings();
-
-    /* RAM size */
-    mSlMemory->setValue (aMachine.GetMemorySize());
-
-    /* Boot-order */
-    {
-        mTwBootOrder->clear();
-        /* Load boot-items of current VM */
-        QStringList uniqueList;
-        for (int i = 1; i <= 4; ++ i)
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsSystem::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Fill internal variables with corresponding values: */
+    /* Load boot-items of current VM: */
+    QList<KDeviceType> usedBootItems;
+    for (int i = 1; i <= m_possibleBootItems.size(); ++i)
+    {
+        KDeviceType type = m_machine.GetBootOrder(i);
+        if (type != KDeviceType_Null)
         {
-            KDeviceType type = mMachine.GetBootOrder (i);
-            if (type != KDeviceType_Null)
-            {
-                QString name = vboxGlobal().toString (type);
-                QTreeWidgetItem *item =
-                    new QTreeWidgetItem (mTwBootOrder, QStringList (name));
-                QVariant vtype (type);
-                item->setData (0, ITEM_TYPE_ROLE, vtype);
-                item->setCheckState (0, Qt::Checked);
-                uniqueList << name;
-            }
+            usedBootItems << type;
+            UIBootItemData data;
+            data.m_type = type;
+            data.m_fEnabled = true;
+            m_cache.m_bootItems << data;
         }
-        /* Load other unique boot-items */
-        for (int i = KDeviceType_Floppy; i < KDeviceType_USB; ++ i)
+    }
+    /* Load other unique boot-items: */
+    for (int i = 0; i < m_possibleBootItems.size(); ++i)
+    {
+        KDeviceType type = m_possibleBootItems[i];
+        if (!usedBootItems.contains(type))
         {
-            QString name = vboxGlobal().toString ((KDeviceType) i);
-            if (!uniqueList.contains (name))
-            {
-                QTreeWidgetItem *item =
-                    new QTreeWidgetItem (mTwBootOrder, QStringList (name));
-                item->setData (0, ITEM_TYPE_ROLE, i);
-                item->setCheckState (0, Qt::Unchecked);
-                uniqueList << name;
-            }
+            UIBootItemData data;
+            data.m_type = type;
+            data.m_fEnabled = false;
+            m_cache.m_bootItems << data;
         }
-        adjustBootOrderTWSize();
-    }
-
-    /* IO APIC */
-    mCbApic->setChecked (biosSettings.GetIOAPICEnabled());
-
-    /* EFI */
-    mCbEFI->setChecked (mMachine.GetFirmwareType() >= KFirmwareType_EFI && mMachine.GetFirmwareType() <= KFirmwareType_EFIDUAL);
-
-    /* RTC */
-    bool rtcUseUTC = mMachine.GetRTCUseUTC ();
-    mCbTCUseUTC->setChecked (rtcUseUTC);
-
-    /* USB tablet */
-    KPointingHidType pointingHid = mMachine.GetPointingHidType ();
-    mCbUseAbsHID->setChecked (pointingHid == KPointingHidType_USBTablet);
-
-    /* CPU count */
-    bool fVTxAMDVSupported = vboxGlobal().virtualBox().GetHost()
-                             .GetProcessorFeature (KProcessorFeature_HWVirtEx);
-    mSlCPU->setEnabled (fVTxAMDVSupported);
-    mLeCPU->setEnabled (fVTxAMDVSupported);
-    mSlCPU->setValue (fVTxAMDVSupported ? aMachine.GetCPUCount() : 1);
-
-    /* PAE/NX */
-    bool fPAESupported = vboxGlobal().virtualBox().GetHost()
-                         .GetProcessorFeature (KProcessorFeature_PAE);
-    mCbPae->setEnabled (fPAESupported);
-    mCbPae->setChecked (aMachine.GetCPUProperty(KCPUPropertyType_PAE));
-
-    /* VT-x/AMD-V page */
-    if (!fVTxAMDVSupported)
+    }
+    m_cache.m_fPFHwVirtExSupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx);
+    m_cache.m_fPFPAESupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_PAE);
+    m_cache.m_fIoApicEnabled = m_machine.GetBIOSSettings().GetIOAPICEnabled();
+    m_cache.m_fEFIEnabled = m_machine.GetFirmwareType() >= KFirmwareType_EFI && m_machine.GetFirmwareType() <= KFirmwareType_EFIDUAL;
+    m_cache.m_fUTCEnabled = m_machine.GetRTCUseUTC();
+    m_cache.m_fUseAbsHID = m_machine.GetPointingHidType() == KPointingHidType_USBTablet;
+    m_cache.m_fPAEEnabled = m_machine.GetCPUProperty(KCPUPropertyType_PAE);
+    m_cache.m_fHwVirtExEnabled = m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled);
+    m_cache.m_fNestedPagingEnabled = m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging);
+    m_cache.m_iRAMSize = m_machine.GetMemorySize();
+    m_cache.m_cCPUCount = m_cache.m_fPFHwVirtExSupported ? m_machine.GetCPUCount() : 1;
+    m_cache.m_chipsetType = m_machine.GetChipsetType();
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsSystem::getFromCache()
+{
+    /* Apply internal variables data to QWidget(s): */
+    for (int i = 0; i < m_cache.m_bootItems.size(); ++i)
+    {
+        UIBootItemData data = m_cache.m_bootItems[i];
+        QString name = vboxGlobal().toString(data.m_type);
+        QTreeWidgetItem *pItem = new QTreeWidgetItem(QStringList(name));
+        pItem->setData(0, ITEM_TYPE_ROLE, QVariant(data.m_type));
+        pItem->setCheckState(0, data.m_fEnabled ? Qt::Checked : Qt::Unchecked);
+        mTwBootOrder->addTopLevelItem(pItem);
+    }
+    mCbApic->setChecked(m_cache.m_fIoApicEnabled);
+    mCbEFI->setChecked(m_cache.m_fEFIEnabled);
+    mCbTCUseUTC->setChecked(m_cache.m_fUTCEnabled);
+    mCbUseAbsHID->setChecked(m_cache.m_fUseAbsHID);
+    mSlCPU->setEnabled(m_cache.m_fPFHwVirtExSupported);
+    mLeCPU->setEnabled(m_cache.m_fPFHwVirtExSupported);
+    mCbPae->setEnabled(m_cache.m_fPFPAESupported);
+    mCbPae->setChecked(m_cache.m_fPAEEnabled);
+    mCbVirt->setEnabled(m_cache.m_fPFHwVirtExSupported);
+    mCbVirt->setChecked(m_cache.m_fHwVirtExEnabled);
+    mCbNestedPaging->setEnabled(m_cache.m_fPFHwVirtExSupported && m_cache.m_fHwVirtExEnabled);
+    mCbNestedPaging->setChecked(m_cache.m_fNestedPagingEnabled);
+    mSlMemory->setValue(m_cache.m_iRAMSize);
+    mSlCPU->setValue(m_cache.m_cCPUCount);
+    int iChipsetPositionPos = mCbChipset->findData(m_cache.m_chipsetType);
+    mCbChipset->setCurrentIndex(iChipsetPositionPos == -1 ? 0 : iChipsetPositionPos);
+    adjustBootOrderTWSize();
+    if (!m_cache.m_fPFHwVirtExSupported)
         mTwSystem->removeTab(2);
 
-    /* VT-x/AMD-V */
-    mCbVirt->setEnabled (fVTxAMDVSupported);
-    mCbVirt->setChecked (aMachine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled));
-
-    /* Nested Paging */
-    mCbNestedPaging->setEnabled (fVTxAMDVSupported &&
-                                 aMachine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled));
-    mCbNestedPaging->setChecked (aMachine.GetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging));
-
-    if (mValidator)
-        mValidator->revalidate();
-}
-
-void VBoxVMSettingsSystem::putBackTo()
-{
-    CBIOSSettings biosSettings = mMachine.GetBIOSSettings();
-
-    /* RAM size */
-    mMachine.SetMemorySize (mSlMemory->value());
-
-    /* Boot order */
-    {
-        /* Search for checked items */
-        int index = 1;
-
-        for (int i = 0; i < mTwBootOrder->topLevelItemCount(); ++ i)
-        {
-            QTreeWidgetItem *item = mTwBootOrder->topLevelItem (i);
-            if (item->checkState (0) == Qt::Checked)
-            {
-                KDeviceType type = vboxGlobal().toDeviceType (item->text (0));
-                mMachine.SetBootOrder (index ++, type);
-            }
-        }
-
-        /* Search for non-checked items */
-        for (int i = 0; i < mTwBootOrder->topLevelItemCount(); ++ i)
-        {
-            QTreeWidgetItem *item = mTwBootOrder->topLevelItem (i);
-            if (item->checkState (0) != Qt::Checked)
-                mMachine.SetBootOrder (index ++, KDeviceType_Null);
-        }
-    }
-
-    /* IO APIC */
-    biosSettings.SetIOAPICEnabled (mCbApic->isChecked() ||
-                                   mSlCPU->value() > 1);
-
-    /* EFI */
-    mMachine.SetFirmwareType (mCbEFI->isChecked() ? KFirmwareType_EFI : KFirmwareType_BIOS);
-
-    /* RTC */
-    mMachine.SetRTCUseUTC (mCbTCUseUTC->isChecked());
-
-    /* USB tablet */
-    mMachine.SetPointingHidType (mCbUseAbsHID->isChecked() ? KPointingHidType_USBTablet : KPointingHidType_PS2Mouse );
-
-    /* RAM size */
-    mMachine.SetCPUCount (mSlCPU->value());
-
-    /* PAE/NX */
-    mMachine.SetCPUProperty(KCPUPropertyType_PAE, mCbPae->isChecked());
-
-    /* VT-x/AMD-V */
-    mMachine.SetHWVirtExProperty(KHWVirtExPropertyType_Enabled,
-                                 mCbVirt->checkState() == Qt::Checked || mSlCPU->value() > 1);
-
-    /* Nested Paging */
-    mMachine.SetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging, mCbNestedPaging->isChecked());
+    /* Revalidate if possible: */
+    if (mValidator) mValidator->revalidate();
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsSystem::putToCache()
+{
+    /* Gather internal variables data from QWidget(s): */
+    m_cache.m_bootItems.clear();
+    for (int i = 0; i < mTwBootOrder->topLevelItemCount(); ++i)
+    {
+        QTreeWidgetItem *pItem = mTwBootOrder->topLevelItem(i);
+        UIBootItemData data;
+        data.m_type = (KDeviceType)pItem->data(0, ITEM_TYPE_ROLE).toInt();
+        data.m_fEnabled = pItem->checkState(0) == Qt::Checked;
+        m_cache.m_bootItems << data;
+    }
+    m_cache.m_fIoApicEnabled = mCbApic->isChecked() || mSlCPU->value() > 1;
+    m_cache.m_fEFIEnabled = mCbEFI->isChecked();
+    m_cache.m_fUTCEnabled = mCbTCUseUTC->isChecked();
+    m_cache.m_fUseAbsHID = mCbUseAbsHID->isChecked();
+    m_cache.m_fPAEEnabled = mCbPae->isChecked();
+    m_cache.m_fHwVirtExEnabled = mCbVirt->checkState() == Qt::Checked || mSlCPU->value() > 1;
+    m_cache.m_fNestedPagingEnabled = mCbNestedPaging->isChecked();
+    m_cache.m_iRAMSize = mSlMemory->value();
+    m_cache.m_cCPUCount = mSlCPU->value();
+    m_cache.m_chipsetType = (KChipsetType)mCbChipset->itemData(mCbChipset->currentIndex()).toInt();
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsSystem::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to machine: */
+    UISettingsPageMachine::fetchData(data);
+
+    /* Gather corresponding values from internal variables: */
+    int iBootIndex = 0;
+    /* Save boot-items of current VM: */
+    for (int i = 0; i < m_cache.m_bootItems.size(); ++i)
+    {
+        if (m_cache.m_bootItems[i].m_fEnabled)
+            m_machine.SetBootOrder(++iBootIndex, m_cache.m_bootItems[i].m_type);
+    }
+    /* Save other unique boot-items: */
+    for (int i = 0; i < m_cache.m_bootItems.size(); ++i)
+    {
+        if (!m_cache.m_bootItems[i].m_fEnabled)
+            m_machine.SetBootOrder(++iBootIndex, KDeviceType_Null);
+    }
+    m_machine.GetBIOSSettings().SetIOAPICEnabled(m_cache.m_fIoApicEnabled);
+    m_machine.SetFirmwareType(m_cache.m_fEFIEnabled ? KFirmwareType_EFI : KFirmwareType_BIOS);
+    m_machine.SetRTCUseUTC(m_cache.m_fUTCEnabled);
+    m_machine.SetPointingHidType(m_cache.m_fUseAbsHID ? KPointingHidType_USBTablet : KPointingHidType_PS2Mouse);
+    m_machine.SetCPUProperty(KCPUPropertyType_PAE, m_cache.m_fPAEEnabled);
+    m_machine.SetHWVirtExProperty(KHWVirtExPropertyType_Enabled, m_cache.m_fHwVirtExEnabled);
+    m_machine.SetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging, m_cache.m_fNestedPagingEnabled);
+    m_machine.SetMemorySize(m_cache.m_iRAMSize);
+    m_machine.SetCPUCount(m_cache.m_cCPUCount);
+    m_machine.SetChipsetType(m_cache.m_chipsetType);
+
+    /* Upload machine to data: */
+    UISettingsPageMachine::uploadData(data);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2008-2009 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -24,5 +24,31 @@
 #include "VBoxVMSettingsSystem.gen.h"
 
-class VBoxVMSettingsSystem : public UISettingsPage,
+/* Machine settings / System page / Boot item: */
+struct UIBootItemData
+{
+    KDeviceType m_type;
+    bool m_fEnabled;
+};
+
+/* Machine settings / System page / Cache: */
+struct UISettingsCacheMachineSystem
+{
+    QList<UIBootItemData> m_bootItems;
+    KChipsetType m_chipsetType;
+    bool m_fPFHwVirtExSupported;
+    bool m_fPFPAESupported;
+    bool m_fIoApicEnabled;
+    bool m_fEFIEnabled;
+    bool m_fUTCEnabled;
+    bool m_fUseAbsHID;
+    bool m_fPAEEnabled;
+    bool m_fHwVirtExEnabled;
+    bool m_fNestedPagingEnabled;
+    int m_iRAMSize;
+    int m_cCPUCount;
+};
+
+/* Machine settings / System page: */
+class VBoxVMSettingsSystem : public UISettingsPageMachine,
                              public Ui::VBoxVMSettingsSystem
 {
@@ -43,6 +69,17 @@
 protected:
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
+
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -72,9 +109,13 @@
     void adjustBootOrderTWSize();
 
-    CMachine mMachine;
     QIWidgetValidator *mValidator;
 
     uint mMinGuestCPU;
     uint mMaxGuestCPU;
+
+    QList<KDeviceType> m_possibleBootItems;
+
+    /* Cache: */
+    UISettingsCacheMachineSystem m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.ui
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.ui	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsSystem.ui	(revision 33631)
@@ -54,5 +54,5 @@
         </widget>
        </item>
-       <item row="0" column="1" rowspan="2">
+       <item row="0" column="1" rowspan="2" colspan="2">
         <layout class="QVBoxLayout" name="mLtMemorySlider">
          <property name="spacing">
@@ -117,5 +117,5 @@
         </layout>
        </item>
-       <item row="0" column="2">
+       <item row="0" column="3">
         <layout class="QHBoxLayout" name="mLtMemoryUnits">
          <item>
@@ -292,5 +292,5 @@
        </item>
        <item row="4" column="0">
-        <widget class="QLabel" name="mLbMotherboardExtended">
+        <widget class="QLabel" name="mLbChipset">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -300,12 +300,44 @@
          </property>
          <property name="text">
-          <string>Extended Features:</string>
+          <string>&amp;Chipset:</string>
          </property>
          <property name="alignment">
           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
          </property>
-        </widget>
-       </item>
-       <item row="4" column="1" colspan="2">
+         <property name="buddy">
+          <cstring>mCbChipset</cstring>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="1">
+        <widget class="QComboBox" name="mCbChipset">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="whatsThis">
+          <string>Defines chipset type used in this VM.</string>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="0">
+        <widget class="QLabel" name="mLbMotherboardExtended">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text">
+          <string>Extended Features:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="1" colspan="3">
         <widget class="QCheckBox" name="mCbApic">
          <property name="sizePolicy">
@@ -323,5 +355,5 @@
         </widget>
        </item>
-       <item row="5" column="1" colspan="2">
+       <item row="6" column="1" colspan="3">
         <widget class="QCheckBox" name="mCbEFI">
          <property name="sizePolicy">
@@ -339,5 +371,5 @@
         </widget>
        </item>
-       <item row="6" column="1" >
+       <item row="7" column="1" colspan="3">
         <widget class="QCheckBox" name="mCbTCUseUTC" >
          <property name="sizePolicy" >
@@ -355,5 +387,5 @@
         </widget>
        </item>
-       <item row="7" column="1" >
+       <item row="8" column="1" colspan="3">
         <widget class="QCheckBox" name="mCbUseAbsHID" >
          <property name="sizePolicy" >
@@ -371,5 +403,5 @@
         </widget>
        </item>
-       <item row="8" column="0" colspan="3">
+       <item row="9" column="0" colspan="4">
         <spacer name="mSpVer1">
          <property name="orientation">
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSB.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSB.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSB.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -29,12 +29,7 @@
 #include <QHeaderView>
 
-inline static QString emptyToNull (const QString &str)
-{
-    return str.isEmpty() ? QString::null : str;
-}
-
-VBoxVMSettingsUSB::VBoxVMSettingsUSB (FilterType aType)
-    : mValidator (0)
-    , mType (aType)
+VBoxVMSettingsUSB::VBoxVMSettingsUSB(UISettingsPageType type)
+    : UISettingsPage(type)
+    , mValidator (0)
     , mUSBFilterListModified (false)
 {
@@ -108,5 +103,5 @@
              this, SLOT (edtClicked()));
     connect (mTwFilters, SIGNAL (itemChanged (QTreeWidgetItem *, int)),
-             this, SLOT (markSettingsChanged()));
+             this, SLOT (sltUpdateActivityState(QTreeWidgetItem *)));
 
     mUSBDevicesMenu = new VBoxUSBMenu (this);
@@ -142,95 +137,229 @@
 }
 
-void VBoxVMSettingsUSB::getFrom (const CSystemProperties &, const VBoxGlobalSettings &)
-{
-    mGbUSB->setVisible (false);
-
-    CHostUSBDeviceFilterVector filtvec = vboxGlobal().virtualBox().GetHost()
-                                        .GetUSBDeviceFilters();
-    for (int i = 0; i < filtvec.size(); ++i)
-    {
-        CHostUSBDeviceFilter hostFilter = filtvec[i];
-        CUSBDeviceFilter filter (hostFilter);
-        addUSBFilter (filter, false /* isNew */);
-    }
-
-    mTwFilters->setCurrentItem (mTwFilters->topLevelItem (0));
-    currentChanged (mTwFilters->currentItem());
-
+/* Load data to cashe from corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsUSB::loadToCacheFrom(QVariant &data)
+{
+    /* Fetch data to properties & settings or machine: */
+    fetchData(data);
+
+    /* Depending on page type: */
+    switch (type())
+    {
+        case UISettingsPageType_Global:
+        {
+            /* Fill internal variables with corresponding values: */
+            m_cache.m_fUSBEnabled = false;
+            m_cache.m_fEHCIEnabled = false;
+            const CHostUSBDeviceFilterVector &filters = vboxGlobal().virtualBox().GetHost().GetUSBDeviceFilters();
+            for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
+            {
+                const CHostUSBDeviceFilter &filter = filters[iFilterIndex];
+                UIUSBFilterData data;
+                data.m_fActive = filter.GetActive();
+                data.m_strName = filter.GetName();
+                data.m_strVendorId = filter.GetVendorId();
+                data.m_strProductId = filter.GetProductId();
+                data.m_strRevision = filter.GetRevision();
+                data.m_strManufacturer = filter.GetManufacturer();
+                data.m_strProduct = filter.GetProduct();
+                data.m_strSerialNumber = filter.GetSerialNumber();
+                data.m_strPort = filter.GetPort();
+                data.m_strRemote = filter.GetRemote();
+                data.m_action = filter.GetAction();
+                CHostUSBDevice hostUSBDevice(filter);
+                if (!hostUSBDevice.isNull())
+                {
+                    data.m_fHostUSBDevice = true;
+                    data.m_hostUSBDeviceState = hostUSBDevice.GetState();
+                }
+                else
+                {
+                    data.m_fHostUSBDevice = false;
+                    data.m_hostUSBDeviceState = KUSBDeviceState_NotSupported;
+                }
+                m_cache.m_items << data;
+            }
+            break;
+        }
+        case UISettingsPageType_Machine:
+        {
+            /* Initialize machine COM storage: */
+            m_machine = data.value<UISettingsDataMachine>().m_machine;
+            /* Fill internal variables with corresponding values: */
+            const CUSBController &ctl = m_machine.GetUSBController();
+            bool fIsControllerAvailable = !ctl.isNull();
+            m_cache.m_fUSBEnabled = fIsControllerAvailable && ctl.GetEnabled();
+            m_cache.m_fEHCIEnabled = fIsControllerAvailable && ctl.GetEnabledEhci();
+            if (fIsControllerAvailable)
+            {
+                const CUSBDeviceFilterVector &filters = ctl.GetDeviceFilters();
+                for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
+                {
+                    const CUSBDeviceFilter &filter = filters[iFilterIndex];
+                    UIUSBFilterData data;
+                    data.m_fActive = filter.GetActive();
+                    data.m_strName = filter.GetName();
+                    data.m_strVendorId = filter.GetVendorId();
+                    data.m_strProductId = filter.GetProductId();
+                    data.m_strRevision = filter.GetRevision();
+                    data.m_strManufacturer = filter.GetManufacturer();
+                    data.m_strProduct = filter.GetProduct();
+                    data.m_strSerialNumber = filter.GetSerialNumber();
+                    data.m_strPort = filter.GetPort();
+                    data.m_strRemote = filter.GetRemote();
+                    data.m_fHostUSBDevice = false;
+                    m_cache.m_items << data;
+                }
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    /* Upload properties & settings or machine to data: */
+    uploadData(data);
+}
+
+/* Load data to corresponding widgets from cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsUSB::getFromCache()
+{
+    /* Depending on page type: */
+    switch (type())
+    {
+        case UISettingsPageType_Global:
+        {
+            /* Apply internal variables data to QWidget(s): */
+            mGbUSB->setVisible(false);
+            mCbUSB2->setVisible(false);
+            break;
+        }
+        case UISettingsPageType_Machine:
+        {
+            /* Apply internal variables data to QWidget(s): */
+            mGbUSB->setChecked(m_cache.m_fUSBEnabled);
+            mCbUSB2->setChecked(m_cache.m_fEHCIEnabled);
+            usbAdapterToggled(mGbUSB->isChecked());
+            break;
+        }
+        default:
+            break;
+    }
+    /* Apply internal variables data to QWidget(s): */
+    for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
+        addUSBFilter(m_cache.m_items[iFilterIndex], false /* its new? */);
+    /* Choose first filter as current: */
+    mTwFilters->setCurrentItem(mTwFilters->topLevelItem(0));
+    currentChanged(mTwFilters->currentItem());
+    /* Mark dialog as not edited:  */
     mUSBFilterListModified = false;
-}
-
-void VBoxVMSettingsUSB::putBackTo (CSystemProperties &, VBoxGlobalSettings &)
-{
-    CHost host = vboxGlobal().virtualBox().GetHost();
-
-    if (mUSBFilterListModified)
-    {
-        /* First, remove all old filters */
-        for (ulong count = host.GetUSBDeviceFilters().size(); count; -- count)
-            host.RemoveUSBDeviceFilter (0);
-
-        /* Then add all new filters */
-        for (int i = 0; i < mFilters.size(); ++ i)
-        {
-            CUSBDeviceFilter filter = mFilters [i];
-            filter.SetActive (mTwFilters->topLevelItem (i)->
-                checkState (0) == Qt::Checked);
-            CHostUSBDeviceFilter insertedFilter (filter);
-            host.InsertUSBDeviceFilter (host.GetUSBDeviceFilters().size(),
-                                        insertedFilter);
-        }
-    }
-
-    mUSBFilterListModified = false;
-}
-
-void VBoxVMSettingsUSB::getFrom (const CMachine &aMachine)
-{
-    mMachine = aMachine;
-
-    CUSBController ctl = aMachine.GetUSBController();
-    mGbUSB->setChecked (!ctl.isNull() && ctl.GetEnabled());
-    mCbUSB2->setChecked (!ctl.isNull() && ctl.GetEnabledEhci());
-    usbAdapterToggled (mGbUSB->isChecked());
-
-    if (!ctl.isNull())
-    {
-        CUSBDeviceFilterVector filtvec = ctl.GetDeviceFilters();
-        for (int i = 0; i < filtvec.size(); ++i)
-            addUSBFilter (filtvec[i], false /* isNew */);
-    }
-
-    mTwFilters->setCurrentItem (mTwFilters->topLevelItem (0));
-    currentChanged (mTwFilters->currentItem());
-
-    mUSBFilterListModified = false;
-}
-
-void VBoxVMSettingsUSB::putBackTo()
-{
-    CUSBController ctl = mMachine.GetUSBController();
-    if (!ctl.isNull())
-    {
-        ctl.SetEnabled (mGbUSB->isChecked());
-        ctl.SetEnabledEhci (mCbUSB2->isChecked());
-
-        if (mUSBFilterListModified)
-        {
-            /* First, remove all old filters */
-            for (ulong count = ctl.GetDeviceFilters().size(); count; -- count)
-                ctl.RemoveDeviceFilter (0);
-
-            /* Then add all new filters */
-            for (int i = 0; i < mFilters.size(); ++ i)
+
+    /* Revalidate if possible: */
+    if (mValidator) mValidator->revalidate();
+}
+
+/* Save data from corresponding widgets to cache,
+ * this task SHOULD be performed in GUI thread only: */
+void VBoxVMSettingsUSB::putToCache()
+{
+    /* Depending on page type: */
+    switch (type())
+    {
+        case UISettingsPageType_Machine:
+        {
+            /* Gather internal variables data from QWidget(s): */
+            m_cache.m_fUSBEnabled = mGbUSB->isChecked();
+            m_cache.m_fEHCIEnabled = mCbUSB2->isChecked();
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+/* Save data from cache to corresponding external object(s),
+ * this task COULD be performed in other than GUI thread: */
+void VBoxVMSettingsUSB::saveFromCacheTo(QVariant &data)
+{
+    /* Fetch data to properties & settings or machine: */
+    fetchData(data);
+
+    /* Depending on page type: */
+    switch (type())
+    {
+        case UISettingsPageType_Global:
+        {
+            /* Gather corresponding values from internal variables: */
+            if (mUSBFilterListModified)
             {
-                CUSBDeviceFilter filter = mFilters [i];
-                filter.SetActive (mTwFilters->topLevelItem (i)->
-                    checkState (0) == Qt::Checked);
-                ctl.InsertDeviceFilter (~0, filter);
+                /* Get host: */
+                CHost &host = vboxGlobal().virtualBox().GetHost();
+                /* First, remove all old filters: */
+                for (ulong count = host.GetUSBDeviceFilters().size(); count; --count)
+                    host.RemoveUSBDeviceFilter(0);
+                /* Then add all new filters: */
+                for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
+                {
+                    UIUSBFilterData data = m_cache.m_items[iFilterIndex];
+                    CHostUSBDeviceFilter &hostFilter = host.CreateUSBDeviceFilter(data.m_strName);
+                    hostFilter.SetActive(data.m_fActive);
+                    hostFilter.SetVendorId(data.m_strVendorId);
+                    hostFilter.SetProductId(data.m_strProductId);
+                    hostFilter.SetRevision(data.m_strRevision);
+                    hostFilter.SetManufacturer(data.m_strManufacturer);
+                    hostFilter.SetProduct(data.m_strProduct);
+                    hostFilter.SetSerialNumber(data.m_strSerialNumber);
+                    hostFilter.SetPort(data.m_strPort);
+                    hostFilter.SetRemote(data.m_strRemote);
+                    hostFilter.SetAction(data.m_action);
+                    host.InsertUSBDeviceFilter(host.GetUSBDeviceFilters().size(), hostFilter);
+                }
             }
-        }
-    }
-    mUSBFilterListModified = false;
+            break;
+        }
+        case UISettingsPageType_Machine:
+        {
+            /* Initialize machine COM storage: */
+            m_machine = data.value<UISettingsDataMachine>().m_machine;
+            /* Get machine USB controller: */
+            CUSBController &ctl = m_machine.GetUSBController();
+            /* Gather corresponding values from internal variables: */
+            if (!ctl.isNull())
+            {
+                ctl.SetEnabled(m_cache.m_fUSBEnabled);
+                ctl.SetEnabledEhci(m_cache.m_fEHCIEnabled);
+                if (mUSBFilterListModified)
+                {
+                    /* First, remove all old filters: */
+                    for (ulong count = ctl.GetDeviceFilters().size(); count; --count)
+                        ctl.RemoveDeviceFilter(0);
+                    /* Then add all new filters: */
+                    for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
+                    {
+                        const UIUSBFilterData &data = m_cache.m_items[iFilterIndex];
+                        CUSBDeviceFilter &filter = ctl.CreateDeviceFilter(data.m_strName);
+                        filter.SetActive(data.m_fActive);
+                        filter.SetVendorId(data.m_strVendorId);
+                        filter.SetProductId(data.m_strProductId);
+                        filter.SetRevision(data.m_strRevision);
+                        filter.SetManufacturer(data.m_strManufacturer);
+                        filter.SetProduct(data.m_strProduct);
+                        filter.SetSerialNumber(data.m_strSerialNumber);
+                        filter.SetPort(data.m_strPort);
+                        filter.SetRemote(data.m_strRemote);
+                        ctl.InsertDeviceFilter(~0, filter);
+                    }
+                }
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    /* Upload properties & settings or machine to data: */
+    uploadData(data);
 }
 
@@ -330,31 +459,26 @@
     }
 
-    /* Creating new usb filter */
-    CUSBDeviceFilter filter;
-
-    if (mType == HostType)
-    {
-        CHost host = vboxGlobal().virtualBox().GetHost();
-        CHostUSBDeviceFilter hostFilter = host
-            .CreateUSBDeviceFilter (mUSBFilterName.arg (maxFilterIndex + 1));
-        hostFilter.SetAction (KUSBDeviceFilterAction_Hold);
-        filter = hostFilter;
-    }
-    else if (mType == MachineType)
-    {
-        CUSBController ctl = mMachine.GetUSBController();
-        if (ctl.isNull())
-            return;
-        filter = ctl.CreateDeviceFilter (mUSBFilterName.arg (maxFilterIndex + 1));
-    }
-    else
-    {
-        AssertMsgFailed (("Invalid VBoxVMSettingsUSB type"));
-    }
-
-    filter.SetActive (true);
-    addUSBFilter (filter, true /* isNew */);
-
-    mUSBFilterListModified = true;
+    /* Add new corresponding list item to the cache: */
+    UIUSBFilterData data;
+    switch (type())
+    {
+        case UISettingsPageType_Global:
+            data.m_action = KUSBDeviceFilterAction_Hold;
+            break;
+        default:
+            break;
+    }
+    data.m_fActive = true;
+    data.m_strName = mUSBFilterName.arg(maxFilterIndex + 1);
+    data.m_fHostUSBDevice = false;
+    m_cache.m_items << data;
+
+    /* Add new corresponding tree-widget-item to the tree-widget: */
+    addUSBFilter(data, true /* its new? */);
+    /* Mark filter's list as edited: */
+    markSettingsChanged();
+    /* Revalidate if possible: */
+    if (mValidator)
+        mValidator->revalidate();
 }
 
@@ -366,4 +490,5 @@
 void VBoxVMSettingsUSB::addConfirmed (QAction *aAction)
 {
+    /* Get USB device: */
     CUSBDevice usb = mUSBDevicesMenu->getUSB (aAction);
     /* if null then some other item but a USB device is selected */
@@ -371,30 +496,24 @@
         return;
 
-    /* Creating new usb filter */
-    CUSBDeviceFilter filter;
-
-    if (mType == HostType)
-    {
-        CHost host = vboxGlobal().virtualBox().GetHost();
-        CHostUSBDeviceFilter hostFilter = host
-            .CreateUSBDeviceFilter (vboxGlobal().details (usb));
-        hostFilter.SetAction (KUSBDeviceFilterAction_Hold);
-        filter = hostFilter;
-    }
-    else if (mType == MachineType)
-    {
-        CUSBController ctl = mMachine.GetUSBController();
-        if (ctl.isNull())
-            return;
-        filter = ctl.CreateDeviceFilter (vboxGlobal().details (usb));
-    }
-    else
-    {
-        AssertMsgFailed (("Invalid VBoxVMSettingsUSB type"));
-    }
-
-    filter.SetVendorId (QString().sprintf ("%04hX", usb.GetVendorId()));
-    filter.SetProductId (QString().sprintf ("%04hX", usb.GetProductId()));
-    filter.SetRevision (QString().sprintf ("%04hX", usb.GetRevision()));
+    /* Add new corresponding list item to the cache: */
+    UIUSBFilterData data;
+    switch (type())
+    {
+        case UISettingsPageType_Global:
+            data.m_action = KUSBDeviceFilterAction_Hold;
+            /* Check that under host (global) USB settings if they will be enabled! */
+            data.m_fHostUSBDevice = false;
+            break;
+        case UISettingsPageType_Machine:
+            data.m_fHostUSBDevice = false;
+            break;
+        default:
+            break;
+    }
+    data.m_fActive = true;
+    data.m_strName = vboxGlobal().details(usb);
+    data.m_strVendorId = QString().sprintf("%04hX", usb.GetVendorId());
+    data.m_strProductId = QString().sprintf("%04hX", usb.GetProductId());
+    data.m_strRevision = QString().sprintf("%04hX", usb.GetRevision());
     /* The port property depends on the host computer rather than on the USB
      * device itself; for this reason only a few people will want to use it
@@ -402,98 +521,101 @@
      * will not match the filter in this case. */
 #if 0
-    /// @todo set it anyway if Alt is currently pressed
-    filter.SetPort (QString().sprintf ("%04hX", usb.GetPort()));
+    data.m_strPort = QString().sprintf("%04hX", usb.GetPort());
 #endif
-    filter.SetManufacturer (usb.GetManufacturer());
-    filter.SetProduct (usb.GetProduct());
-    filter.SetSerialNumber (usb.GetSerialNumber());
-    filter.SetRemote (usb.GetRemote() ? "yes" : "no");
-
-    filter.SetActive (true);
-    addUSBFilter (filter, true /* isNew */);
-
-    mUSBFilterListModified = true;
+    data.m_strManufacturer = usb.GetManufacturer();
+    data.m_strProduct = usb.GetProduct();
+    data.m_strSerialNumber = usb.GetSerialNumber();
+    data.m_strRemote = QString::number(usb.GetRemote());
+    m_cache.m_items << data;
+
+    /* Add new corresponding tree-widget-item to the tree-widget: */
+    addUSBFilter(data, true /* its new? */);
+    /* Mark filter's list as edited: */
+    markSettingsChanged();
+    /* Revalidate if possible: */
+    if (mValidator)
+        mValidator->revalidate();
 }
 
 void VBoxVMSettingsUSB::edtClicked()
 {
-    QTreeWidgetItem *item = mTwFilters->currentItem();
-    Assert (item);
-
-    VBoxVMSettingsUSBFilterDetails fd (mType, this);
-
-    CUSBDeviceFilter filter =
-        mFilters [mTwFilters->indexOfTopLevelItem (item)];
-
-    fd.mLeName->setText (filter.isNull() ? QString::null : filter.GetName());
-    fd.mLeVendorID->setText (filter.isNull() ? QString::null : filter.GetVendorId());
-    fd.mLeProductID->setText (filter.isNull() ? QString::null : filter.GetProductId());
-    fd.mLeRevision->setText (filter.isNull() ? QString::null : filter.GetRevision());
-    fd.mLePort->setText (filter.isNull() ? QString::null : filter.GetPort());
-    fd.mLeManufacturer->setText (filter.isNull() ? QString::null : filter.GetManufacturer());
-    fd.mLeProduct->setText (filter.isNull() ? QString::null : filter.GetProduct());
-    fd.mLeSerialNo->setText (filter.isNull() ? QString::null : filter.GetSerialNumber());
-
-    switch (mType)
-    {
-        case MachineType:
-        {
-            QString remote = filter.isNull() ? QString::null : filter.GetRemote().toLower();
-            if (remote == "yes" || remote == "true" || remote == "1")
-                fd.mCbRemote->setCurrentIndex (ModeOn);
-            else if (remote == "no" || remote == "false" || remote == "0")
-                fd.mCbRemote->setCurrentIndex (ModeOff);
+    /* Get current USB filter item: */
+    QTreeWidgetItem *pItem = mTwFilters->currentItem();
+    Assert(pItem);
+    UIUSBFilterData &data = m_cache.m_items[mTwFilters->indexOfTopLevelItem(pItem)];
+
+    /* Configure USB filter details dialog: */
+    VBoxVMSettingsUSBFilterDetails dlgFilterDetails(type(), this);
+    dlgFilterDetails.mLeName->setText(data.m_strName);
+    dlgFilterDetails.mLeVendorID->setText(data.m_strVendorId);
+    dlgFilterDetails.mLeProductID->setText(data.m_strProductId);
+    dlgFilterDetails.mLeRevision->setText(data.m_strRevision);
+    dlgFilterDetails.mLePort->setText(data.m_strPort);
+    dlgFilterDetails.mLeManufacturer->setText(data.m_strManufacturer);
+    dlgFilterDetails.mLeProduct->setText(data.m_strProduct);
+    dlgFilterDetails.mLeSerialNo->setText(data.m_strSerialNumber);
+    switch (type())
+    {
+        case UISettingsPageType_Global:
+        {
+            if (data.m_action == KUSBDeviceFilterAction_Ignore)
+                dlgFilterDetails.mCbAction->setCurrentIndex(0);
+            else if (data.m_action == KUSBDeviceFilterAction_Hold)
+                dlgFilterDetails.mCbAction->setCurrentIndex(1);
             else
-                fd.mCbRemote->setCurrentIndex (ModeAny);
-            break;
-        }
-        case HostType:
-        {
-            CHostUSBDeviceFilter hostFilter (filter);
-            KUSBDeviceFilterAction action = hostFilter.isNull() ?
-                KUSBDeviceFilterAction_Ignore : hostFilter.GetAction();
-            if (action == KUSBDeviceFilterAction_Ignore)
-                fd.mCbAction->setCurrentIndex (0);
-            else if (action == KUSBDeviceFilterAction_Hold)
-                fd.mCbAction->setCurrentIndex (1);
+                AssertMsgFailed(("Invalid USBDeviceFilterAction type"));
+            break;
+        }
+        case UISettingsPageType_Machine:
+        {
+            QString strRemote = data.m_strRemote.toLower();
+            if (strRemote == "yes" || strRemote == "true" || strRemote == "1")
+                dlgFilterDetails.mCbRemote->setCurrentIndex(ModeOn);
+            else if (strRemote == "no" || strRemote == "false" || strRemote == "0")
+                dlgFilterDetails.mCbRemote->setCurrentIndex(ModeOff);
             else
-                AssertMsgFailed (("Invalid USBDeviceFilterAction type"));
-            break;
-        }
-        default:
-        {
-            AssertMsgFailed (("Invalid VBoxVMSettingsUSB type"));
-            break;
-        }
-    }
-
-    if (fd.exec() == QDialog::Accepted)
-    {
-        filter.SetName (fd.mLeName->text().isEmpty() ? QString::null : fd.mLeName->text());
-        item->setText (0, fd.mLeName->text());
-        filter.SetVendorId (fd.mLeVendorID->text().isEmpty() ? QString::null : fd.mLeVendorID->text());
-        filter.SetProductId (fd.mLeProductID->text().isEmpty() ? QString::null : fd.mLeProductID->text());
-        filter.SetRevision (fd.mLeRevision->text().isEmpty() ? QString::null : fd.mLeRevision->text());
-        filter.SetManufacturer (fd.mLeManufacturer->text().isEmpty() ? QString::null : fd.mLeManufacturer->text());
-        filter.SetProduct (fd.mLeProduct->text().isEmpty() ? QString::null : fd.mLeProduct->text());
-        filter.SetSerialNumber (fd.mLeSerialNo->text().isEmpty() ? QString::null : fd.mLeSerialNo->text());
-        filter.SetPort (fd.mLePort->text().isEmpty() ? QString::null : fd.mLePort->text());
-        if (mType == MachineType)
-        {
-            switch (fd.mCbRemote->currentIndex())
-             {
-                 case ModeAny: filter.SetRemote (QString::null); break;
-                 case ModeOn:  filter.SetRemote ("yes"); break;
-                 case ModeOff: filter.SetRemote ("no"); break;
-                 default: AssertMsgFailed (("Invalid combo box index"));
-             }
-        }
-        else
-        if (mType == HostType)
-        {
-            CHostUSBDeviceFilter hostFilter (filter);
-            hostFilter.SetAction (vboxGlobal().toUSBDevFilterAction (fd.mCbAction->currentText()));
-        }
-        item->setToolTip (0, vboxGlobal().toolTip (filter));
+                dlgFilterDetails.mCbRemote->setCurrentIndex(ModeAny);
+            break;
+        }
+        default:
+            break;
+    }
+
+    /* Run USB filter details dialog: */
+    if (dlgFilterDetails.exec() == QDialog::Accepted)
+    {
+        data.m_strName = dlgFilterDetails.mLeName->text().isEmpty() ? QString::null : dlgFilterDetails.mLeName->text();
+        data.m_strVendorId = dlgFilterDetails.mLeVendorID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeVendorID->text();
+        data.m_strProductId = dlgFilterDetails.mLeProductID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProductID->text();
+        data.m_strRevision = dlgFilterDetails.mLeRevision->text().isEmpty() ? QString::null : dlgFilterDetails.mLeRevision->text();
+        data.m_strManufacturer = dlgFilterDetails.mLeManufacturer->text().isEmpty() ? QString::null : dlgFilterDetails.mLeManufacturer->text();
+        data.m_strProduct = dlgFilterDetails.mLeProduct->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProduct->text();
+        data.m_strSerialNumber = dlgFilterDetails.mLeSerialNo->text().isEmpty() ? QString::null : dlgFilterDetails.mLeSerialNo->text();
+        data.m_strPort = dlgFilterDetails.mLePort->text().isEmpty() ? QString::null : dlgFilterDetails.mLePort->text();
+        switch (type())
+        {
+            case UISettingsPageType_Global:
+            {
+                data.m_action = vboxGlobal().toUSBDevFilterAction(dlgFilterDetails.mCbAction->currentText());
+                break;
+            }
+            case UISettingsPageType_Machine:
+            {
+                switch (dlgFilterDetails.mCbRemote->currentIndex())
+                {
+                    case ModeAny: data.m_strRemote = QString(); break;
+                    case ModeOn:  data.m_strRemote = QString::number(1); break;
+                    case ModeOff: data.m_strRemote = QString::number(0); break;
+                    default: AssertMsgFailed(("Invalid combo box index"));
+                }
+                break;
+            }
+            default:
+                break;
+        }
+        pItem->setText(0, data.m_strName);
+        pItem->setToolTip(0, toolTipFor(data));
+        /* Mark filter's list as edited: */
+        markSettingsChanged();
     }
 }
@@ -501,12 +623,17 @@
 void VBoxVMSettingsUSB::delClicked()
 {
-    QTreeWidgetItem *item = mTwFilters->currentItem();
-    Assert (item);
-    int index = mTwFilters->indexOfTopLevelItem (item);
-
-    delete item;
-    mFilters.removeAt (index);
-
-    /* Setup validators */
+    /* Get current USB filter item: */
+    QTreeWidgetItem *pItem = mTwFilters->currentItem();
+    Assert(pItem);
+
+    /* Delete corresponding items: */
+    m_cache.m_items.removeAt(mTwFilters->indexOfTopLevelItem(pItem));
+    delete pItem;
+
+    /* Update current item: */
+    currentChanged(mTwFilters->currentItem());
+    /* Mark filter's list as edited: */
+    markSettingsChanged();
+    /* Revalidate if possible: */
     if (!mTwFilters->topLevelItemCount())
     {
@@ -517,7 +644,4 @@
         }
     }
-
-    currentChanged (mTwFilters->currentItem());
-    mUSBFilterListModified = true;
 }
 
@@ -531,8 +655,8 @@
     Assert (item == takenItem);
     mTwFilters->insertTopLevelItem (index - 1, takenItem);
-    mFilters.swap (index, index - 1);
+    m_cache.m_items.swap (index, index - 1);
 
     mTwFilters->setCurrentItem (takenItem);
-    mUSBFilterListModified = true;
+    markSettingsChanged();
 }
 
@@ -546,42 +670,128 @@
     Assert (item == takenItem);
     mTwFilters->insertTopLevelItem (index + 1, takenItem);
-    mFilters.swap (index, index + 1);
+    m_cache.m_items.swap (index, index + 1);
 
     mTwFilters->setCurrentItem (takenItem);
+    markSettingsChanged();
+}
+
+void VBoxVMSettingsUSB::showContextMenu (const QPoint &aPos)
+{
+    mMenu->exec (mTwFilters->mapToGlobal (aPos));
+}
+
+void VBoxVMSettingsUSB::sltUpdateActivityState(QTreeWidgetItem *pChangedItem)
+{
+    /* Check changed USB filter item: */
+    Assert(pChangedItem);
+
+    /* Delete corresponding items: */
+    UIUSBFilterData &data = m_cache.m_items[mTwFilters->indexOfTopLevelItem(pChangedItem)];
+    data.m_fActive = pChangedItem->checkState(0) == Qt::Checked;
+
+    markSettingsChanged();
+}
+
+void VBoxVMSettingsUSB::markSettingsChanged()
+{
     mUSBFilterListModified = true;
 }
 
-void VBoxVMSettingsUSB::showContextMenu (const QPoint &aPos)
-{
-    mMenu->exec (mTwFilters->mapToGlobal (aPos));
-}
-
-void VBoxVMSettingsUSB::markSettingsChanged()
-{
-    mUSBFilterListModified = true;
-}
-
-void VBoxVMSettingsUSB::addUSBFilter (const CUSBDeviceFilter &aFilter,
-                                      bool isNew)
-{
-    QTreeWidgetItem *currentItem = isNew ?
-        mTwFilters->currentItem() :
-        mTwFilters->topLevelItem (mTwFilters->topLevelItemCount() - 1);
-
-    int pos = currentItem ? mTwFilters->indexOfTopLevelItem (currentItem) : -1;
-    mFilters.insert (pos + 1, aFilter);
-
-    QTreeWidgetItem *item = pos >= 0 ?
-        new QTreeWidgetItem (mTwFilters, mTwFilters->topLevelItem (pos)) :
-        new QTreeWidgetItem (mTwFilters);
-    item->setCheckState (0, aFilter.GetActive() ? Qt::Checked : Qt::Unchecked);
-    item->setText (0, aFilter.GetName());
-    item->setToolTip (0, vboxGlobal().toolTip (aFilter));
-
-    if (isNew)
-        mTwFilters->setCurrentItem (item);
-
-    if (mValidator)
-        mValidator->revalidate();
-}
-
+void VBoxVMSettingsUSB::addUSBFilter(const UIUSBFilterData &data, bool fIsNew)
+{
+    /* Append tree-widget with item: */
+    QTreeWidgetItem *pItem = new QTreeWidgetItem;
+    pItem->setCheckState(0, data.m_fActive ? Qt::Checked : Qt::Unchecked);
+    pItem->setText(0, data.m_strName);
+    pItem->setToolTip(0, toolTipFor(data));
+    mTwFilters->addTopLevelItem(pItem);
+
+    /* Select this item if its new: */
+    if (fIsNew)
+        mTwFilters->setCurrentItem(pItem);
+}
+
+/* Fetch data to m_properties & m_settings or m_machine: */
+void VBoxVMSettingsUSB::fetchData(const QVariant &data)
+{
+    switch (type())
+    {
+        case UISettingsPageType_Global:
+        {
+            m_properties = data.value<UISettingsDataGlobal>().m_properties;
+            m_settings = data.value<UISettingsDataGlobal>().m_settings;
+            break;
+        }
+        case UISettingsPageType_Machine:
+        {
+            m_machine = data.value<UISettingsDataMachine>().m_machine;
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+/* Upload m_properties & m_settings or m_machine to data: */
+void VBoxVMSettingsUSB::uploadData(QVariant &data) const
+{
+    switch (type())
+    {
+        case UISettingsPageType_Global:
+        {
+            data = QVariant::fromValue(UISettingsDataGlobal(m_properties, m_settings));
+            break;
+        }
+        case UISettingsPageType_Machine:
+        {
+            data = QVariant::fromValue(UISettingsDataMachine(m_machine));
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+/* static */ QString VBoxVMSettingsUSB::toolTipFor(const UIUSBFilterData &data)
+{
+    /* Prepare tool-tip: */
+    QString strToolTip;
+
+    QString strVendorId = data.m_strVendorId;
+    if (!strVendorId.isEmpty())
+        strToolTip += tr("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip").arg(strVendorId);
+
+    QString strProductId = data.m_strProductId;
+    if (!strProductId.isEmpty())
+        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product ID: %2</nobr>", "USB filter tooltip").arg(strProductId);
+
+    QString strRevision = data.m_strRevision;
+    if (!strRevision.isEmpty())
+        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Revision: %3</nobr>", "USB filter tooltip").arg(strRevision);
+
+    QString strProduct = data.m_strProduct;
+    if (!strProduct.isEmpty())
+        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product: %4</nobr>", "USB filter tooltip").arg(strProduct);
+
+    QString strManufacturer = data.m_strManufacturer;
+    if (!strManufacturer.isEmpty())
+        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip").arg(strManufacturer);
+
+    QString strSerial = data.m_strSerialNumber;
+    if (!strSerial.isEmpty())
+        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Serial No.: %1</nobr>", "USB filter tooltip").arg(strSerial);
+
+    QString strPort = data.m_strPort;
+    if (!strPort.isEmpty())
+        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Port: %1</nobr>", "USB filter tooltip").arg(strPort);
+
+    /* Add the state field if it's a host USB device: */
+    if (data.m_fHostUSBDevice)
+    {
+        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>State: %1</nobr>", "USB filter tooltip")
+                                                          .arg(vboxGlobal().toString(data.m_hostUSBDeviceState));
+    }
+
+    return strToolTip;
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSB.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSB.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSB.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -26,4 +26,34 @@
 class VBoxUSBMenu;
 
+/* Common settings / USB page / Filter data: */
+struct UIUSBFilterData
+{
+    /* Common: */
+    bool m_fActive;
+    QString m_strName;
+    QString m_strVendorId;
+    QString m_strProductId;
+    QString m_strRevision;
+    QString m_strManufacturer;
+    QString m_strProduct;
+    QString m_strSerialNumber;
+    QString m_strPort;
+    QString m_strRemote;
+
+    /* Host only: */
+    KUSBDeviceFilterAction m_action;
+    bool m_fHostUSBDevice;
+    KUSBDeviceState m_hostUSBDeviceState;
+};
+
+/* Common settings / USB page / Cache: */
+struct UISettingsCacheCommonUSB
+{
+    bool m_fUSBEnabled;
+    bool m_fEHCIEnabled;
+    QList<UIUSBFilterData> m_items;
+};
+
+/* Common settings / USB page: */
 class VBoxVMSettingsUSB : public UISettingsPage,
                           public Ui::VBoxVMSettingsUSB
@@ -32,11 +62,4 @@
 
 public:
-
-    enum FilterType
-    {
-        WrongType = 0,
-        HostType = 1,
-        MachineType = 2
-    };
 
     enum RemoteMode
@@ -47,5 +70,5 @@
     };
 
-    VBoxVMSettingsUSB (FilterType aType);
+    VBoxVMSettingsUSB(UISettingsPageType type);
 
     bool isOHCIEnabled() const;
@@ -53,11 +76,17 @@
 protected:
 
-    void getFrom (const CSystemProperties &aProps,
-                  const VBoxGlobalSettings &aGs);
-    void putBackTo (CSystemProperties &aProps,
-                    VBoxGlobalSettings &aGs);
+    /* Load data to cashe from corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void loadToCacheFrom(QVariant &data);
+    /* Load data to corresponding widgets from cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void getFromCache();
 
-    void getFrom (const CMachine &aMachine);
-    void putBackTo();
+    /* Save data from corresponding widgets to cache,
+     * this task SHOULD be performed in GUI thread only: */
+    void putToCache();
+    /* Save data from cache to corresponding external object(s),
+     * this task COULD be performed in other than GUI thread: */
+    void saveFromCacheTo(QVariant &data);
 
     void setValidator (QIWidgetValidator *aVal);
@@ -81,13 +110,29 @@
     void mdnClicked();
     void showContextMenu (const QPoint &aPos);
+    void sltUpdateActivityState(QTreeWidgetItem *pChangedItem);
     void markSettingsChanged();
 
 private:
 
-    void addUSBFilter (const CUSBDeviceFilter &aFilter, bool isNew);
+    void addUSBFilter(const UIUSBFilterData &data, bool fIsNew);
 
-    CMachine mMachine;
+    /* Fetch data to m_properties, m_settings or m_machine: */
+    void fetchData(const QVariant &data);
+
+    /* Upload m_properties, m_settings or m_machine to data: */
+    void uploadData(QVariant &data) const;
+
+    /* Returns the multi-line description of the given USB filter: */
+    static QString toolTipFor(const UIUSBFilterData &data);
+
+    /* Global data source: */
+    CSystemProperties m_properties;
+    VBoxGlobalSettings m_settings;
+
+    /* Machine data source: */
+    CMachine m_machine;
+
+    /* Other variables: */
     QIWidgetValidator *mValidator;
-    FilterType mType;
     QAction *mNewAction;
     QAction *mAddAction;
@@ -99,7 +144,8 @@
     VBoxUSBMenu *mUSBDevicesMenu;
     bool mUSBFilterListModified;
-    QList<CUSBDeviceFilter> mFilters;
+    QString mUSBFilterName;
 
-    QString mUSBFilterName;
+    /* Cache: */
+    UISettingsCacheCommonUSB m_cache;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSBFilterDetails.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSBFilterDetails.cpp	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSBFilterDetails.cpp	(revision 33631)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -21,7 +21,7 @@
 #include "VBoxGlobal.h"
 
-VBoxVMSettingsUSBFilterDetails::VBoxVMSettingsUSBFilterDetails (VBoxVMSettingsUSB::FilterType aType, QWidget *aParent /* = NULL */)
-    : QIWithRetranslateUI2<QIDialog> (aParent, Qt::Sheet)
-    , mType (aType)
+VBoxVMSettingsUSBFilterDetails::VBoxVMSettingsUSBFilterDetails(UISettingsPageType type, QWidget *pParent /* = 0 */)
+    : QIWithRetranslateUI2<QIDialog>(pParent, Qt::Sheet)
+    , m_type(type)
 {
     /* Apply UI decorations */
@@ -31,11 +31,11 @@
     mCbRemote->insertItem (VBoxVMSettingsUSB::ModeOn,  ""); /* Yes */
     mCbRemote->insertItem (VBoxVMSettingsUSB::ModeOff, ""); /* No */
-    mLbRemote->setHidden (mType != VBoxVMSettingsUSB::MachineType);
-    mCbRemote->setHidden (mType != VBoxVMSettingsUSB::MachineType);
+    mLbRemote->setHidden (m_type != UISettingsPageType_Machine);
+    mCbRemote->setHidden (m_type != UISettingsPageType_Machine);
 
     mCbAction->insertItem (0, ""); /* KUSBDeviceFilterAction_Ignore */
     mCbAction->insertItem (1, ""); /* KUSBDeviceFilterAction_Hold */
-    mLbAction->setHidden (mType != VBoxVMSettingsUSB::HostType);
-    mCbAction->setHidden (mType != VBoxVMSettingsUSB::HostType);
+    mLbAction->setHidden (m_type != UISettingsPageType_Global);
+    mCbAction->setHidden (m_type != UISettingsPageType_Global);
 
     mLeName->setValidator (new QRegExpValidator (QRegExp (".+"), this));
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSBFilterDetails.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSBFilterDetails.h	(revision 33630)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSBFilterDetails.h	(revision 33631)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -32,5 +32,5 @@
 public:
 
-    VBoxVMSettingsUSBFilterDetails (VBoxVMSettingsUSB::FilterType aType, QWidget *aParent = NULL);
+    VBoxVMSettingsUSBFilterDetails(UISettingsPageType type, QWidget *pParent = 0);
 
 protected:
@@ -41,5 +41,5 @@
 
     /* Private member vars */
-    VBoxVMSettingsUSB::FilterType mType;
+    UISettingsPageType m_type;
 };
 
