Index: /trunk/src/VBox/Main/HostPower.cpp
===================================================================
--- /trunk/src/VBox/Main/HostPower.cpp	(revision 13704)
+++ /trunk/src/VBox/Main/HostPower.cpp	(revision 13705)
@@ -24,9 +24,10 @@
 *   Header Files                                                               *
 *******************************************************************************/
+#include <iprt/mem.h>
 #include <VBox/com/ptr.h>
 #include "HostPower.h"
 #include "Logging.h"
 
-HostPowerService::HostPowerService(VirtualBox *aVirtualBox)
+HostPowerService::HostPowerService(VirtualBox *aVirtualBox) : aMachineSuspended(NULL), cbMachineSuspended(0)
 {
     mVirtualBox = aVirtualBox;
@@ -40,7 +41,18 @@
 void HostPowerService::notify(HostPowerEvent event)
 {
+    VirtualBox::SessionMachineVector machines;
+    mVirtualBox->getOpenedMachines (machines);
+
     switch (event)
     {
     case HostPowerEvent_Suspend:
+        if (machines.size())
+            aMachineSuspended = (BOOL *)RTMemAllocZ(sizeof(BOOL) * machines.size());
+
+        cbMachineSuspended = machines.size();
+
+        for (size_t i = 0; i < machines.size(); i++)
+            processEvent(machines[i], HostPowerEvent_Suspend, (aMachineSuspended) ? &aMachineSuspended[i] : NULL);
+
         Log(("HostPowerService::notify SUSPEND\n"));
         break;
@@ -48,21 +60,32 @@
     case HostPowerEvent_Resume:
         Log(("HostPowerService::notify RESUME\n"));
+
+        if (aMachineSuspended)
+        {
+            /* It's possible (in theory) that machines are created or destroyed between the suspend notification and the actual host suspend.
+             * Ignore this edge case and just make sure not to access invalid data.
+             */
+            cbMachineSuspended = RT_MIN(machines.size(), cbMachineSuspended);
+
+            for (size_t i = 0; i < cbMachineSuspended; i++)
+                processEvent(machines[i], HostPowerEvent_Resume, &aMachineSuspended[i]);
+
+            RTMemFree(aMachineSuspended);
+            cbMachineSuspended = 0;
+            aMachineSuspended  = NULL;
+        }
         break;
 
     case HostPowerEvent_BatteryLow:
         Log(("HostPowerService::notify BATTERY LOW\n"));
+        for (size_t i = 0; i < machines.size(); i++)
+            processEvent(machines[i], HostPowerEvent_BatteryLow, NULL);
         break;
     }
-
-    VirtualBox::SessionMachineVector machines;
-    mVirtualBox->getOpenedMachines (machines);
-
-    for (size_t i = 0; i < machines.size(); i++)
-        processEvent(machines[i], event);
 
     machines.clear();
 }
 
-HRESULT HostPowerService::processEvent(SessionMachine *machine, HostPowerEvent event)
+HRESULT HostPowerService::processEvent(SessionMachine *machine, HostPowerEvent event, BOOL *pMachineSuspended)
 {
     MachineState_T state;
@@ -72,5 +95,10 @@
     CheckComRCReturnRC (rc);
 
-    if (state == MachineState_Running)
+    /* Valid combinations:
+     * running & suspend or battery low notification events
+     * pause   & resume or battery low notification events
+     */
+    if (    (state == MachineState_Running && event != HostPowerEvent_Resume)
+        ||  (state == MachineState_Paused  && event != HostPowerEvent_Suspend))
     {
         ComPtr <ISession> session;
@@ -100,14 +128,37 @@
                 case HostPowerEvent_Suspend:
                     rc = console->Pause();
+                    if (    SUCCEEDED(rc)
+                        &&  pMachineSuspended)
+                        *pMachineSuspended = TRUE;
                     break;
+
                 case HostPowerEvent_Resume:
+                    Assert(pMachineSuspended);
+                    if (*pMachineSuspended == TRUE)
+                        rc = console->Resume();
+                    break;
+
                 case HostPowerEvent_BatteryLow:
+                {
+                    ComPtr<IProgress> progress;
+
+                    rc = console->SaveState(progress.asOutParam());
+                    if (SUCCEEDED(rc))
+                    {
+                        /* Wait until the operation has been completed. */
+                        progress->WaitForCompletion(-1); 
+
+                        progress->COMGETTER(ResultCode)(&rc);
+                        AssertMsg(SUCCEEDED(rc), ("SaveState WaitForCompletion failed with %x\n", rc));
+                    }
+
                     break;
                 }
+
+                } /* switch (event) */
             }
         }
 fail:
         session->Close();
-
     }
     return rc;
Index: /trunk/src/VBox/Main/include/HostPower.h
===================================================================
--- /trunk/src/VBox/Main/include/HostPower.h	(revision 13704)
+++ /trunk/src/VBox/Main/include/HostPower.h	(revision 13705)
@@ -42,8 +42,11 @@
 
     void    notify(HostPowerEvent event);
-    HRESULT processEvent(SessionMachine *machine, HostPowerEvent event);
+    HRESULT processEvent(SessionMachine *machine, HostPowerEvent event, BOOL *paMachineSuspended);
 
 protected:
     ComObjPtr <VirtualBox, ComWeakRef> mVirtualBox;
+
+    BOOL    *aMachineSuspended;
+    size_t   cbMachineSuspended;
 };
 
