Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp	(revision 66565)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp	(revision 66566)
@@ -58,4 +58,5 @@
 /* COM includes: */
 # include "CAudioAdapter.h"
+# include "CNATEngine.h"
 # include "CParallelPort.h"
 # include "CSerialPort.h"
@@ -1228,4 +1229,11 @@
           tr("Cannot save network adapter settings."),
           formatErrorInfo(comAdapter));
+}
+
+void UIMessageCenter::cannotSaveNATEngineSettings(const CNATEngine &comEngine, QWidget *pParent /* = 0 */)
+{
+    error(pParent, MessageType_Error,
+          tr("Cannot save NAT engine settings."),
+          formatErrorInfo(comEngine));
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h	(revision 66565)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h	(revision 66566)
@@ -249,4 +249,5 @@
     void cannotSaveNetworkSettings(const CMachine &comMachine, QWidget *pParent = 0);
     void cannotSaveNetworkAdapterSettings(const CNetworkAdapter &comAdapter, QWidget *pParent = 0);
+    void cannotSaveNATEngineSettings(const CNATEngine &comEngine, QWidget *pParent = 0);
     void cannotSaveParallelSettings(const CMachine &comMachine, QWidget *pParent = 0);
     void cannotSaveParallelPortSettings(const CParallelPort &comPort, QWidget *pParent = 0);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp	(revision 66565)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp	(revision 66566)
@@ -74,5 +74,4 @@
         , m_strMACAddress(QString())
         , m_fCableConnected(false)
-        , m_redirects(UIPortForwardingDataList())
     {}
 
@@ -94,5 +93,4 @@
                && (m_strMACAddress == other.m_strMACAddress)
                && (m_fCableConnected == other.m_fCableConnected)
-               && (m_redirects == other.m_redirects)
                ;
     }
@@ -129,6 +127,4 @@
     /** Holds whether the network adapter is connected. */
     bool                              m_fCableConnected;
-    /** Holds the set of network redirection rules. */
-    UIPortForwardingDataList          m_redirects;
 };
 
@@ -159,6 +155,6 @@
 
     /* Load / Save API: */
-    void loadAdapterData(const UIDataSettingsMachineNetworkAdapter &adapterData);
-    void saveAdapterData(UIDataSettingsMachineNetworkAdapter &adapterData);
+    void getAdapterDataFromCache(const UISettingsCacheMachineNetworkAdapter &adapterCache);
+    void putAdapterDataToCache(UISettingsCacheMachineNetworkAdapter &adapterCache);
 
     /** Performs validation, updates @a messages list if something is wrong. */
@@ -274,48 +270,56 @@
 }
 
-void UIMachineSettingsNetwork::loadAdapterData(const UIDataSettingsMachineNetworkAdapter &adapterData)
-{
+void UIMachineSettingsNetwork::getAdapterDataFromCache(const UISettingsCacheMachineNetworkAdapter &adapterCache)
+{
+    /* Get old adapter data: */
+    const UIDataSettingsMachineNetworkAdapter &oldAdapterData = adapterCache.base();
+
     /* Load slot number: */
-    m_iSlot = adapterData.m_iSlot;
+    m_iSlot = oldAdapterData.m_iSlot;
 
     /* Load adapter activity state: */
-    m_pEnableAdapterCheckBox->setChecked(adapterData.m_fAdapterEnabled);
+    m_pEnableAdapterCheckBox->setChecked(oldAdapterData.m_fAdapterEnabled);
     /* Handle adapter activity change: */
     sltHandleAdapterActivityChange();
 
     /* Load attachment type: */
-    m_pAttachmentTypeComboBox->setCurrentIndex(position(m_pAttachmentTypeComboBox, adapterData.m_attachmentType));
+    m_pAttachmentTypeComboBox->setCurrentIndex(position(m_pAttachmentTypeComboBox, oldAdapterData.m_attachmentType));
     /* Load alternative name: */
-    m_strBridgedAdapterName = wipedOutString(adapterData.m_strBridgedAdapterName);
-    m_strInternalNetworkName = wipedOutString(adapterData.m_strInternalNetworkName);
-    m_strHostInterfaceName = wipedOutString(adapterData.m_strHostInterfaceName);
-    m_strGenericDriverName = wipedOutString(adapterData.m_strGenericDriverName);
-    m_strNATNetworkName = wipedOutString(adapterData.m_strNATNetworkName);
+    m_strBridgedAdapterName = wipedOutString(oldAdapterData.m_strBridgedAdapterName);
+    m_strInternalNetworkName = wipedOutString(oldAdapterData.m_strInternalNetworkName);
+    m_strHostInterfaceName = wipedOutString(oldAdapterData.m_strHostInterfaceName);
+    m_strGenericDriverName = wipedOutString(oldAdapterData.m_strGenericDriverName);
+    m_strNATNetworkName = wipedOutString(oldAdapterData.m_strNATNetworkName);
     /* Handle attachment type change: */
     sltHandleAttachmentTypeChange();
 
     /* Load adapter type: */
-    m_pAdapterTypeCombo->setCurrentIndex(position(m_pAdapterTypeCombo, adapterData.m_adapterType));
+    m_pAdapterTypeCombo->setCurrentIndex(position(m_pAdapterTypeCombo, oldAdapterData.m_adapterType));
 
     /* Load promiscuous mode type: */
-    m_pPromiscuousModeCombo->setCurrentIndex(position(m_pPromiscuousModeCombo, adapterData.m_promiscuousMode));
+    m_pPromiscuousModeCombo->setCurrentIndex(position(m_pPromiscuousModeCombo, oldAdapterData.m_promiscuousMode));
 
     /* Other options: */
-    m_pMACEditor->setText(adapterData.m_strMACAddress);
-    m_pGenericPropertiesTextEdit->setText(adapterData.m_strGenericProperties);
-    m_pCableConnectedCheckBox->setChecked(adapterData.m_fCableConnected);
+    m_pMACEditor->setText(oldAdapterData.m_strMACAddress);
+    m_pGenericPropertiesTextEdit->setText(oldAdapterData.m_strGenericProperties);
+    m_pCableConnectedCheckBox->setChecked(oldAdapterData.m_fCableConnected);
 
     /* Load port forwarding rules: */
-    m_portForwardingRules = adapterData.m_redirects;
-}
-
-void UIMachineSettingsNetwork::saveAdapterData(UIDataSettingsMachineNetworkAdapter &adapterData)
-{
+    m_portForwardingRules.clear();
+    for (int i = 0; i < adapterCache.childCount(); ++i)
+        m_portForwardingRules << adapterCache.child(i).base();
+}
+
+void UIMachineSettingsNetwork::putAdapterDataToCache(UISettingsCacheMachineNetworkAdapter &adapterCache)
+{
+    /* Prepare new adapter data: */
+    UIDataSettingsMachineNetworkAdapter newAdapterData;
+
     /* Save adapter activity state: */
-    adapterData.m_fAdapterEnabled = m_pEnableAdapterCheckBox->isChecked();
+    newAdapterData.m_fAdapterEnabled = m_pEnableAdapterCheckBox->isChecked();
 
     /* Save attachment type & alternative name: */
-    adapterData.m_attachmentType = attachmentType();
-    switch (adapterData.m_attachmentType)
+    newAdapterData.m_attachmentType = attachmentType();
+    switch (newAdapterData.m_attachmentType)
     {
         case KNetworkAttachmentType_Null:
@@ -324,18 +328,18 @@
             break;
         case KNetworkAttachmentType_Bridged:
-            adapterData.m_strBridgedAdapterName = alternativeName();
+            newAdapterData.m_strBridgedAdapterName = alternativeName();
             break;
         case KNetworkAttachmentType_Internal:
-            adapterData.m_strInternalNetworkName = alternativeName();
+            newAdapterData.m_strInternalNetworkName = alternativeName();
             break;
         case KNetworkAttachmentType_HostOnly:
-            adapterData.m_strHostInterfaceName = alternativeName();
+            newAdapterData.m_strHostInterfaceName = alternativeName();
             break;
         case KNetworkAttachmentType_Generic:
-            adapterData.m_strGenericDriverName = alternativeName();
-            adapterData.m_strGenericProperties = m_pGenericPropertiesTextEdit->toPlainText();
+            newAdapterData.m_strGenericDriverName = alternativeName();
+            newAdapterData.m_strGenericProperties = m_pGenericPropertiesTextEdit->toPlainText();
             break;
         case KNetworkAttachmentType_NATNetwork:
-            adapterData.m_strNATNetworkName = alternativeName();
+            newAdapterData.m_strNATNetworkName = alternativeName();
             break;
         default:
@@ -344,15 +348,19 @@
 
     /* Save adapter type: */
-    adapterData.m_adapterType = (KNetworkAdapterType)m_pAdapterTypeCombo->itemData(m_pAdapterTypeCombo->currentIndex()).toInt();
+    newAdapterData.m_adapterType = (KNetworkAdapterType)m_pAdapterTypeCombo->itemData(m_pAdapterTypeCombo->currentIndex()).toInt();
 
     /* Save promiscuous mode type: */
-    adapterData.m_promiscuousMode = (KNetworkAdapterPromiscModePolicy)m_pPromiscuousModeCombo->itemData(m_pPromiscuousModeCombo->currentIndex()).toInt();
+    newAdapterData.m_promiscuousMode = (KNetworkAdapterPromiscModePolicy)m_pPromiscuousModeCombo->itemData(m_pPromiscuousModeCombo->currentIndex()).toInt();
 
     /* Other options: */
-    adapterData.m_strMACAddress = m_pMACEditor->text().isEmpty() ? QString() : m_pMACEditor->text();
-    adapterData.m_fCableConnected = m_pCableConnectedCheckBox->isChecked();
+    newAdapterData.m_strMACAddress = m_pMACEditor->text().isEmpty() ? QString() : m_pMACEditor->text();
+    newAdapterData.m_fCableConnected = m_pCableConnectedCheckBox->isChecked();
 
     /* Save port forwarding rules: */
-    adapterData.m_redirects = m_portForwardingRules;
+    foreach (const UIDataPortForwardingRule &rule, m_portForwardingRules)
+        adapterCache.child(rule.name).cacheCurrentData(rule);
+
+    /* Cache new adapter data: */
+    adapterCache.cacheCurrentData(newAdapterData);
 }
 
@@ -605,5 +613,5 @@
     m_pGenericPropertiesTextEdit->setVisible(attachmentType() == KNetworkAttachmentType_Generic &&
                                              m_pAdvancedArrow->isExpanded());
-    /* Update forwarding-rules button availability: */
+    /* Update forwarding rules button availability: */
     m_pPortForwardingButton->setEnabled(attachmentType() == KNetworkAttachmentType_NAT);
     /* Update alternative-name combo-box whats-this and editable state: */
@@ -1054,14 +1062,19 @@
             oldAdapterData.m_strGenericProperties = loadGenericProperties(comAdapter);
             oldAdapterData.m_fCableConnected = comAdapter.GetCableConnected();
-            foreach (const QString &redirect, comAdapter.GetNATEngine().GetRedirects())
-            {
-                const QStringList redirectData = redirect.split(',');
-                AssertMsg(redirectData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
-                oldAdapterData.m_redirects << UIDataPortForwardingRule(redirectData.at(0),
-                                                                       (KNATProtocol)redirectData.at(1).toUInt(),
-                                                                       redirectData.at(2),
-                                                                       redirectData.at(3).toUInt(),
-                                                                       redirectData.at(4),
-                                                                       redirectData.at(5).toUInt());
+            foreach (const QString &strRedirect, comAdapter.GetNATEngine().GetRedirects())
+            {
+                /* Gather old forwarding data & cache key: */
+                const QStringList &forwardingData = strRedirect.split(',');
+                AssertMsg(forwardingData.size() == 6, ("Redirect rule should be composed of 6 parts!\n"));
+                const UIDataPortForwardingRule oldForwardingData(forwardingData.at(0),
+                                                                 (KNATProtocol)forwardingData.at(1).toUInt(),
+                                                                 forwardingData.at(2),
+                                                                 forwardingData.at(3).toUInt(),
+                                                                 forwardingData.at(4),
+                                                                 forwardingData.at(5).toUInt());
+
+                const QString &strForwardingKey = forwardingData.at(0);
+                /* Cache old forwarding data: */
+                m_pCache->child(iSlot).child(strForwardingKey).cacheInitialData(oldForwardingData);
             }
         }
@@ -1092,5 +1105,5 @@
 
         /* Load old adapter data from the cache: */
-        pTab->loadAdapterData(m_pCache->child(iSlot).base());
+        pTab->getAdapterDataFromCache(m_pCache->child(iSlot));
 
         /* Setup tab order: */
@@ -1119,12 +1132,6 @@
         UIMachineSettingsNetwork *pTab = qobject_cast<UIMachineSettingsNetwork*>(m_pTabWidget->widget(iSlot));
 
-        /* Prepare new adapter data: */
-        UIDataSettingsMachineNetworkAdapter newAdapterData;
-
         /* Gather new adapter data: */
-        pTab->saveAdapterData(newAdapterData);
-
-        /* Cache new adapter data: */
-        m_pCache->child(iSlot).cacheCurrentData(newAdapterData);
+        pTab->putAdapterDataToCache(m_pCache->child(iSlot));
     }
 
@@ -1583,15 +1590,11 @@
                 fSuccess = comAdapter.isOk();
             }
-            /* Save adapter redirect options: */
-            if (   fSuccess && newAdapterData.m_redirects != oldAdapterData.m_redirects
-                && (   oldAdapterData.m_attachmentType == KNetworkAttachmentType_NAT
-                    || newAdapterData.m_attachmentType == KNetworkAttachmentType_NAT))
-            {
-                foreach (const QString &strOldRedirect, comAdapter.GetNATEngine().GetRedirects())
-                    comAdapter.GetNATEngine().RemoveRedirect(strOldRedirect.section(',', 0, 0));
-                foreach (const UIDataPortForwardingRule &newRedirect, newAdapterData.m_redirects)
-                    comAdapter.GetNATEngine().AddRedirect(newRedirect.name, newRedirect.protocol,
-                                                          newRedirect.hostIp, newRedirect.hostPort.value(),
-                                                          newRedirect.guestIp, newRedirect.guestPort.value());
+
+            /* Get NAT engine for further activities: */
+            CNATEngine comEngine;
+            if (fSuccess)
+            {
+                comEngine = comAdapter.GetNATEngine();
+                fSuccess = comAdapter.isOk() && comEngine.isNotNull();
             }
 
@@ -1599,4 +1602,38 @@
             if (!fSuccess)
                 msgCenter().cannotSaveNetworkAdapterSettings(comAdapter, this);
+            else
+            {
+                /* Save adapter port forwarding rules: */
+                if (   oldAdapterData.m_attachmentType == KNetworkAttachmentType_NAT
+                    || newAdapterData.m_attachmentType == KNetworkAttachmentType_NAT)
+                {
+                    /* For each rule: */
+                    for (int iRule = 0; fSuccess && iRule < m_pCache->child(iSlot).childCount(); ++iRule)
+                    {
+                        /* Get rule cache: */
+                        const UISettingsCachePortForwardingRule &ruleCache = m_pCache->child(iSlot).child(iRule);
+
+                        /* Remove rule marked for 'remove' or 'update': */
+                        if (fSuccess && (ruleCache.wasRemoved() || ruleCache.wasUpdated()))
+                        {
+                            comEngine.RemoveRedirect(ruleCache.base().name);
+                            fSuccess = comEngine.isOk();
+                        }
+
+                        /* Create rule marked for 'create' or 'update': */
+                        if (fSuccess && (ruleCache.wasCreated() || ruleCache.wasUpdated()))
+                        {
+                            comEngine.AddRedirect(ruleCache.data().name, ruleCache.data().protocol,
+                                                  ruleCache.data().hostIp, ruleCache.data().hostPort.value(),
+                                                  ruleCache.data().guestIp, ruleCache.data().guestPort.value());
+                            fSuccess = comEngine.isOk();
+                        }
+
+                        /* Show error message if necessary: */
+                        if (!fSuccess)
+                            msgCenter().cannotSaveNATEngineSettings(comEngine, this);
+                    }
+                }
+            }
         }
     }
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.h	(revision 66565)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.h	(revision 66566)
@@ -28,5 +28,6 @@
 struct UIDataSettingsMachineNetwork;
 struct UIDataSettingsMachineNetworkAdapter;
-typedef UISettingsCache<UIDataSettingsMachineNetworkAdapter> UISettingsCacheMachineNetworkAdapter;
+typedef UISettingsCache<UIDataPortForwardingRule> UISettingsCachePortForwardingRule;
+typedef UISettingsCachePool<UIDataSettingsMachineNetworkAdapter, UISettingsCachePortForwardingRule> UISettingsCacheMachineNetworkAdapter;
 typedef UISettingsCachePool<UIDataSettingsMachineNetwork, UISettingsCacheMachineNetworkAdapter> UISettingsCacheMachineNetwork;
 
