Index: /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h	(revision 36010)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIMessageBox.h	(revision 36011)
@@ -70,5 +70,7 @@
 
         Default = 0x100, Escape = 0x200,
-        FlagMask = 0x300
+        FlagMask = 0x300,
+
+        OptionChosen = 0x400
     };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp	(revision 36010)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp	(revision 36011)
@@ -254,4 +254,105 @@
  */
 
+int VBoxProblemReporter::messageWithOption(QWidget *pParent,
+                                           Type type,
+                                           const QString &strMessage,
+                                           const QString &strOptionText,
+                                           bool fDefaultOptionValue /* = true */,
+                                           const QString &strDetails /* = QString::null */,
+                                           int iButton1 /* = 0 */,
+                                           int iButton2 /* = 0 */,
+                                           int iButton3 /* = 0 */,
+                                           const QString &strButtonName1 /* = QString::null */,
+                                           const QString &strButtonName2 /* = QString::null */,
+                                           const QString &strButtonName3 /* = QString::null */) const
+{
+    /* If no buttons are set, using single 'OK' button: */
+    if (iButton1 == 0 && iButton2 == 0 && iButton3 == 0)
+        iButton1 = QIMessageBox::Ok | QIMessageBox::Default;
+
+    /* Assign corresponding title and icon: */
+    QString strTitle;
+    QIMessageBox::Icon icon;
+    switch (type)
+    {
+        default:
+        case Info:
+            strTitle = tr("VirtualBox - Information", "msg box title");
+            icon = QIMessageBox::Information;
+            break;
+        case Question:
+            strTitle = tr("VirtualBox - Question", "msg box title");
+            icon = QIMessageBox::Question;
+            break;
+        case Warning:
+            strTitle = tr("VirtualBox - Warning", "msg box title");
+            icon = QIMessageBox::Warning;
+            break;
+        case Error:
+            strTitle = tr("VirtualBox - Error", "msg box title");
+            icon = QIMessageBox::Critical;
+            break;
+        case Critical:
+            strTitle = tr("VirtualBox - Critical Error", "msg box title");
+            icon = QIMessageBox::Critical;
+            break;
+        case GuruMeditation:
+            strTitle = "VirtualBox - Guru Meditation"; /* don't translate this */
+            icon = QIMessageBox::GuruMeditation;
+            break;
+    }
+
+    /* Create message-box: */
+    if (QPointer<QIMessageBox> pBox = new QIMessageBox(strTitle, strMessage, icon,
+                                                       iButton1, iButton2, iButton3, pParent))
+    {
+        /* Append the list of all warnings with current: */
+        m_warnings << pBox;
+
+        /* Setup message-box connections: */
+        connect(this, SIGNAL(sigToCloseAllWarnings()), pBox, SLOT(deleteLater()));
+
+        /* Assign other text values: */
+        if (!strOptionText.isNull())
+        {
+            pBox->setFlagText(strOptionText);
+            pBox->setFlagChecked(fDefaultOptionValue);
+        }
+        if (!strButtonName1.isNull())
+            pBox->setButtonText(0, strButtonName1);
+        if (!strButtonName2.isNull())
+            pBox->setButtonText(1, strButtonName2);
+        if (!strButtonName3.isNull())
+            pBox->setButtonText(2, strButtonName3);
+        if (!strDetails.isEmpty())
+            pBox->setDetailsText(strDetails);
+
+        /* Show the message box: */
+        int iResultCode = pBox->exec();
+
+        /* Its possible what message-box will be deleted during some event-processing procedure,
+         * in that case pBox will be null right after pBox->exec() returns from it's event-pool,
+         * so we have to check this too: */
+        if (pBox)
+        {
+            /* Cleanup the list of all warnings from current: */
+            if (m_warnings.contains(pBox))
+                m_warnings.removeAll(pBox);
+
+            /* Check if option was chosen: */
+            if (pBox->isFlagChecked())
+                iResultCode |= QIMessageBox::OptionChosen;
+
+            /* Destroy message-box: */
+            if (pBox)
+                delete pBox;
+
+            /* Return final result: */
+            return iResultCode;
+        }
+    }
+    return 0;
+}
+
 /**
  *  Shows a modal progress dialog using a CProgress object passed as an
@@ -840,13 +941,22 @@
 }
 
-bool VBoxProblemReporter::askAboutSnapshotRestoring (const QString &aSnapshotName)
-{
-    return messageOkCancel (mainWindowShown(), Question,
-        tr ("<p>Are you sure you want to restore snapshot <b>%1</b>? "
-            "This will cause you to lose your current machine state, which cannot be recovered.</p>")
-            .arg (aSnapshotName),
-        /* Do NOT allow this message to be disabled! */
-        NULL /* aAutoConfirmId */,
-        tr ("Restore"), tr ("Cancel"));
+int VBoxProblemReporter::askAboutSnapshotRestoring(const QString &strSnapshotName, bool fAlsoCreateNewSnapshot)
+{
+    return fAlsoCreateNewSnapshot ?
+           messageWithOption(mainWindowShown(), Question,
+                             tr("<p>You are about to restore snapshot <b>%1</b>.</p>"
+                                "<p>You can create a snapshot of the current state of the virtual machine first by checking the box below; "
+                                "if you do not do this the current state will be permanently lost. Do you wish to proceed?</p>")
+                                .arg(strSnapshotName),
+                             tr("Create a snapshot of the current machine state"),
+                             true /* choose option by default */,
+                             QString::null /* details */,
+                             QIMessageBox::Ok, QIMessageBox::Cancel, 0 /* 3rd button */,
+                             tr("Restore"), tr("Cancel"), QString::null /* 3rd button text */) :
+           message(mainWindowShown(), Question,
+                   tr("<p>Are you sure you want to restore snapshot <b>%1</b>?</p>").arg(strSnapshotName),
+                   0 /* auto-confirmation token */,
+                   QIMessageBox::Ok, QIMessageBox::Cancel, 0 /* 3rd button */,
+                   tr("Restore"), tr("Cancel"), QString::null /* 3rd button text */);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h	(revision 36010)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h	(revision 36011)
@@ -138,4 +138,17 @@
     }
 
+    int messageWithOption(QWidget *pParent,
+                          Type type,
+                          const QString &strMessage,
+                          const QString &strOptionText,
+                          bool fDefaultOptionValue = true,
+                          const QString &strDetails = QString::null,
+                          int iButton1 = 0,
+                          int iButton2 = 0,
+                          int iButton3 = 0,
+                          const QString &strButtonName1 = QString::null,
+                          const QString &strButtonName2 = QString::null,
+                          const QString &strButtonName3 = QString::null) const;
+
     bool showModalProgressDialog(CProgress &progress, const QString &strTitle,
                                  const QString &strImage = "", QWidget *pParent = 0,
@@ -208,5 +221,5 @@
     bool warnAboutVirtNotEnabledGuestRequired(bool fHWVirtExSupported);
 
-    bool askAboutSnapshotRestoring (const QString &aSnapshotName);
+    int askAboutSnapshotRestoring (const QString &aSnapshotName, bool fAlsoCreateNewSnapshot);
     bool askAboutSnapshotDeleting (const QString &aSnapshotName);
     bool askAboutSnapshotDeletingFreeSpace (const QString &aSnapshotName,
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp	(revision 36010)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp	(revision 36011)
@@ -397,8 +397,8 @@
              this, SLOT (onItemChanged (QTreeWidgetItem*)));
 
-    connect (mRestoreSnapshotAction, SIGNAL (triggered()), this, SLOT (restoreSnapshot()));
-    connect (mDeleteSnapshotAction, SIGNAL (triggered()), this, SLOT (deleteSnapshot()));
-    connect (mShowSnapshotDetailsAction, SIGNAL (triggered()), this, SLOT (showSnapshotDetails()));
-    connect (mTakeSnapshotAction, SIGNAL (triggered()), this, SLOT (takeSnapshot()));
+    connect (mTakeSnapshotAction, SIGNAL (triggered()), this, SLOT (sltTakeSnapshot()));
+    connect (mRestoreSnapshotAction, SIGNAL (triggered()), this, SLOT (sltRestoreSnapshot()));
+    connect (mDeleteSnapshotAction, SIGNAL (triggered()), this, SLOT (sltDeleteSnapshot()));
+    connect (mShowSnapshotDetailsAction, SIGNAL (triggered()), this, SLOT (sltShowSnapshotDetails()));
 
     connect (gVBoxEvents, SIGNAL(sigMachineDataChange(QString)),
@@ -432,4 +432,28 @@
 }
 
+void VBoxSnapshotsWgt::retranslateUi()
+{
+    /* Translate uic generated strings */
+    Ui::VBoxSnapshotsWgt::retranslateUi (this);
+
+    mRestoreSnapshotAction->setText (tr ("&Restore Snapshot"));
+    mDeleteSnapshotAction->setText (tr ("&Delete Snapshot"));
+    mShowSnapshotDetailsAction->setText (tr ("S&how Details"));
+    mTakeSnapshotAction->setText (tr ("Take &Snapshot"));
+
+    mRestoreSnapshotAction->setStatusTip (tr ("Restore the selected snapshot of the virtual machine"));
+    mDeleteSnapshotAction->setStatusTip (tr ("Delete the selected snapshot of the virtual machine"));
+    mShowSnapshotDetailsAction->setStatusTip (tr ("Show the details of the selected snapshot"));
+    mTakeSnapshotAction->setStatusTip (tr ("Take a snapshot of the current virtual machine state"));
+
+    mRestoreSnapshotAction->setToolTip (mRestoreSnapshotAction->text().remove ('&').remove ('.') +
+        QString (" (%1)").arg (mRestoreSnapshotAction->shortcut().toString()));
+    mDeleteSnapshotAction->setToolTip (mDeleteSnapshotAction->text().remove ('&').remove ('.') +
+        QString (" (%1)").arg (mDeleteSnapshotAction->shortcut().toString()));
+    mShowSnapshotDetailsAction->setToolTip (mShowSnapshotDetailsAction->text().remove ('&').remove ('.') +
+        QString (" (%1)").arg (mShowSnapshotDetailsAction->shortcut().toString()));
+    mTakeSnapshotAction->setToolTip (mTakeSnapshotAction->text().remove ('&').remove ('.') +
+        QString (" (%1)").arg (mTakeSnapshotAction->shortcut().toString()));
+}
 
 void VBoxSnapshotsWgt::onCurrentChanged (QTreeWidgetItem *aItem)
@@ -513,40 +537,59 @@
 }
 
-void VBoxSnapshotsWgt::restoreSnapshot()
-{
-    SnapshotWgtItem *item = !mTreeWidget->currentItem() ? 0 :
-        static_cast <SnapshotWgtItem*> (mTreeWidget->currentItem());
-    AssertReturn (item, (void) 0);
-
-    QString snapId = item->snapshotId();
-    AssertReturn (!snapId.isNull(), (void) 0);
-    CSnapshot snapshot = mMachine.FindSnapshot(snapId);
-
-    if (!vboxProblem().askAboutSnapshotRestoring (snapshot.GetName()))
-        return;
-
-    /* Open a direct session (this call will handle all errors) */
-    CSession session = vboxGlobal().openSession (mMachineId);
-    if (session.isNull())
-        return;
-
-    CConsole console = session.GetConsole();
-    CProgress progress = console.RestoreSnapshot (snapshot);
-    if (console.isOk())
-    {
-        /* Show the progress dialog */
-        vboxProblem().showModalProgressDialog (progress, mMachine.GetName(), ":/progress_snapshot_restore_90px.png",
-                                               vboxProblem().mainWindowShown(), true);
-
-        if (progress.GetResultCode() != 0)
-            vboxProblem().cannotRestoreSnapshot (progress, snapshot.GetName());
-    }
-    else
-        vboxProblem().cannotRestoreSnapshot (progress, snapshot.GetName());
-
-    session.UnlockMachine();
-}
-
-void VBoxSnapshotsWgt::deleteSnapshot()
+void VBoxSnapshotsWgt::sltTakeSnapshot()
+{
+    takeSnapshot();
+}
+
+void VBoxSnapshotsWgt::sltRestoreSnapshot()
+{
+    /* Get currently chosen item: */
+    SnapshotWgtItem *pItem = mTreeWidget->currentItem() ? static_cast<SnapshotWgtItem*>(mTreeWidget->currentItem()) : 0;
+    AssertReturn(pItem, (void)0);
+    /* Detemine snapshot id: */
+    QString strSnapshotId = pItem->snapshotId();
+    AssertReturn(!strSnapshotId.isNull(), (void)0);
+    /* Get currently desired snapshot: */
+    CSnapshot snapshot = mMachine.FindSnapshot(strSnapshotId);
+
+    /* Ask the user if he really wants to restore the snapshot: */
+    int iResultCode = vboxProblem().askAboutSnapshotRestoring(snapshot.GetName(), mMachine.GetCurrentStateModified());
+
+    /* If user confirmed other snapshot restoring: */
+    if (iResultCode & QIMessageBox::Ok)
+    {
+        /* If user also confirmed new snapshot creation: */
+        if (iResultCode & QIMessageBox::OptionChosen)
+        {
+            /* Take snapshot of changed current state: */
+            mTreeWidget->setCurrentItem(curStateItem());
+            if (!takeSnapshot())
+                return;
+        }
+
+        /* Open a direct session (this call will handle all errors): */
+        CSession session = vboxGlobal().openSession(mMachineId);
+        if (session.isNull())
+            return;
+
+        /* Restore chosen snapshot: */
+        CConsole console = session.GetConsole();
+        CProgress progress = console.RestoreSnapshot(snapshot);
+        if (console.isOk())
+        {
+            vboxProblem().showModalProgressDialog(progress, mMachine.GetName(), ":/progress_snapshot_restore_90px.png",
+                                                  vboxProblem().mainWindowShown(), true);
+            if (progress.GetResultCode() != 0)
+                vboxProblem().cannotRestoreSnapshot(progress, snapshot.GetName());
+        }
+        else
+            vboxProblem().cannotRestoreSnapshot(progress, snapshot.GetName());
+
+        /* Unlock machine finally: */
+        session.UnlockMachine();
+    }
+}
+
+void VBoxSnapshotsWgt::sltDeleteSnapshot()
 {
     SnapshotWgtItem *item = !mTreeWidget->currentItem() ? 0 :
@@ -594,5 +637,5 @@
 }
 
-void VBoxSnapshotsWgt::showSnapshotDetails()
+void VBoxSnapshotsWgt::sltShowSnapshotDetails()
 {
     SnapshotWgtItem *item = !mTreeWidget->currentItem() ? 0 :
@@ -611,59 +654,4 @@
         dlg.putBackToSnapshot();
 }
-
-void VBoxSnapshotsWgt::takeSnapshot()
-{
-    SnapshotWgtItem *item = !mTreeWidget->currentItem() ? 0 :
-        static_cast <SnapshotWgtItem*> (mTreeWidget->currentItem());
-    AssertReturn (item, (void) 0);
-
-    VBoxTakeSnapshotDlg dlg (this, mMachine);
-
-    QString typeId = mMachine.GetOSTypeId();
-    dlg.mLbIcon->setPixmap (vboxGlobal().vmGuestOSTypeIcon (typeId));
-
-    /* Search for the max available filter index */
-    int maxSnapShotIndex = 0;
-    QString snapShotName = tr ("Snapshot %1");
-    QRegExp regExp (QString ("^") + snapShotName.arg ("([0-9]+)") + QString ("$"));
-    QTreeWidgetItemIterator iterator (mTreeWidget);
-    while (*iterator)
-    {
-        QString snapShot = static_cast <SnapshotWgtItem*> (*iterator)->text (0);
-        int pos = regExp.indexIn (snapShot);
-        if (pos != -1)
-            maxSnapShotIndex = regExp.cap (1).toInt() > maxSnapShotIndex ?
-                               regExp.cap (1).toInt() : maxSnapShotIndex;
-        ++ iterator;
-    }
-    dlg.mLeName->setText (snapShotName.arg (maxSnapShotIndex + 1));
-
-    if (dlg.exec() == QDialog::Accepted)
-    {
-        /* Open a direct session (this call will handle all errors) */
-        bool busy = mSessionState != KSessionState_Unlocked;
-        CSession session = vboxGlobal().openSession (mMachineId, busy /* aExisting */);
-        if (session.isNull())
-            return;
-
-        CConsole console = session.GetConsole();
-        CProgress progress = console.TakeSnapshot (dlg.mLeName->text().trimmed(),
-                                                   dlg.mTeDescription->toPlainText());
-        if (console.isOk())
-        {
-            /* Show the progress dialog */
-            vboxProblem().showModalProgressDialog (progress, mMachine.GetName(), ":/progress_snapshot_create_90px.png",
-                                                   vboxProblem().mainWindowShown(), true);
-
-            if (progress.GetResultCode() != 0)
-                vboxProblem().cannotTakeSnapshot (progress);
-        }
-        else
-            vboxProblem().cannotTakeSnapshot (console);
-
-        session.UnlockMachine();
-    }
-}
-
 
 void VBoxSnapshotsWgt::machineDataChanged(QString strId)
@@ -729,27 +717,58 @@
 }
 
-void VBoxSnapshotsWgt::retranslateUi()
-{
-    /* Translate uic generated strings */
-    Ui::VBoxSnapshotsWgt::retranslateUi (this);
-
-    mRestoreSnapshotAction->setText (tr ("&Restore Snapshot"));
-    mDeleteSnapshotAction->setText (tr ("&Delete Snapshot"));
-    mShowSnapshotDetailsAction->setText (tr ("S&how Details"));
-    mTakeSnapshotAction->setText (tr ("Take &Snapshot"));
-
-    mRestoreSnapshotAction->setStatusTip (tr ("Restore the selected snapshot of the virtual machine"));
-    mDeleteSnapshotAction->setStatusTip (tr ("Delete the selected snapshot of the virtual machine"));
-    mShowSnapshotDetailsAction->setStatusTip (tr ("Show the details of the selected snapshot"));
-    mTakeSnapshotAction->setStatusTip (tr ("Take a snapshot of the current virtual machine state"));
-
-    mRestoreSnapshotAction->setToolTip (mRestoreSnapshotAction->text().remove ('&').remove ('.') +
-        QString (" (%1)").arg (mRestoreSnapshotAction->shortcut().toString()));
-    mDeleteSnapshotAction->setToolTip (mDeleteSnapshotAction->text().remove ('&').remove ('.') +
-        QString (" (%1)").arg (mDeleteSnapshotAction->shortcut().toString()));
-    mShowSnapshotDetailsAction->setToolTip (mShowSnapshotDetailsAction->text().remove ('&').remove ('.') +
-        QString (" (%1)").arg (mShowSnapshotDetailsAction->shortcut().toString()));
-    mTakeSnapshotAction->setToolTip (mTakeSnapshotAction->text().remove ('&').remove ('.') +
-        QString (" (%1)").arg (mTakeSnapshotAction->shortcut().toString()));
+bool VBoxSnapshotsWgt::takeSnapshot()
+{
+    /* Get currently chosen item: */
+    SnapshotWgtItem *pItem = mTreeWidget->currentItem() ? static_cast <SnapshotWgtItem*>(mTreeWidget->currentItem()) : 0;
+    AssertReturn(pItem, (bool)0);
+
+    /* Create 'take new snapshot' dialog: */
+    VBoxTakeSnapshotDlg dlg(this, mMachine);
+    dlg.mLbIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(mMachine.GetOSTypeId()));
+
+    /* Search for the max available filter index: */
+    int iMaxSnapShotIndex = 0;
+    QString snapShotName = tr("Snapshot %1");
+    QRegExp regExp(QString("^") + snapShotName.arg("([0-9]+)") + QString("$"));
+    QTreeWidgetItemIterator iterator(mTreeWidget);
+    while (*iterator)
+    {
+        QString snapShot = static_cast<SnapshotWgtItem*>(*iterator)->text(0);
+        int pos = regExp.indexIn(snapShot);
+        if (pos != -1)
+            iMaxSnapShotIndex = regExp.cap(1).toInt() > iMaxSnapShotIndex ? regExp.cap(1).toInt() : iMaxSnapShotIndex;
+        ++iterator;
+    }
+    dlg.mLeName->setText(snapShotName.arg(iMaxSnapShotIndex + 1));
+
+    /* Show 'take new snapshot' dialog: */
+    if (dlg.exec() == QDialog::Accepted)
+    {
+        /* Open a direct session (this call will handle all errors): */
+        bool busy = mSessionState != KSessionState_Unlocked;
+        CSession session = vboxGlobal().openSession(mMachineId, busy /* aExisting */);
+        if (session.isNull())
+            return false;
+
+        /* Take new snapshot: */
+        CConsole console = session.GetConsole();
+        CProgress progress = console.TakeSnapshot(dlg.mLeName->text().trimmed(), dlg.mTeDescription->toPlainText());
+        if (console.isOk())
+        {
+            /* Show the progress dialog */
+            vboxProblem().showModalProgressDialog(progress, mMachine.GetName(), ":/progress_snapshot_create_90px.png",
+                                                  vboxProblem().mainWindowShown(), true);
+            if (progress.GetResultCode() != 0)
+                vboxProblem().cannotTakeSnapshot(progress);
+        }
+        else
+            vboxProblem().cannotTakeSnapshot(console);
+
+        /* Unlock machine finally: */
+        session.UnlockMachine();
+
+        return true;
+    }
+    return false;
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.h	(revision 36010)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.h	(revision 36011)
@@ -57,13 +57,16 @@
 private slots:
 
+    /* Snapshot tree slots: */
     void onCurrentChanged (QTreeWidgetItem *aItem = 0);
     void onContextMenuRequested (const QPoint &aPoint);
     void onItemChanged (QTreeWidgetItem *aItem);
 
-    void restoreSnapshot();
-    void deleteSnapshot();
-    void showSnapshotDetails();
-    void takeSnapshot();
+    /* Snapshot functionality slots: */
+    void sltTakeSnapshot();
+    void sltRestoreSnapshot();
+    void sltDeleteSnapshot();
+    void sltShowSnapshotDetails();
 
+    /* Main API event handlers: */
     void machineDataChanged(QString strId);
     void machineStateChanged(QString strId, KMachineState state);
@@ -73,4 +76,10 @@
 
 private:
+
+    /* Snapshot private functions: */
+    bool takeSnapshot();
+    //bool restoreSnapshot();
+    //bool deleteSnapshot();
+    //bool showSnapshotDetails();
 
     void refreshAll();
