Index: /trunk/src/VBox/Frontends/VBoxShell/vboxshell.py
===================================================================
--- /trunk/src/VBox/Frontends/VBoxShell/vboxshell.py	(revision 30344)
+++ /trunk/src/VBox/Frontends/VBoxShell/vboxshell.py	(revision 30345)
@@ -426,4 +426,24 @@
         pass
     vbox.unregisterCallback(cb)
+
+def monitorVBox2(ctx, dur):
+    vbox = ctx['vb']
+    print vbox.eventSource
+    listener = vbox.eventSource.createListener()
+    if dur == -1:
+        # not infinity, but close enough
+        dur = 100000
+    try:
+        vbox.eventSource.registerListener(listener, [ctx['global'].constants.VBoxEventType_All], False)
+        end = time.time() + dur
+        while  time.time() < end:
+            ev = vbox.eventSource.getEvent(500)
+            if ev:
+                print "got event: %s %s" %(ev, str(ev.type))
+    # We need to catch all exceptions here, otherwise callback will never be unregistered
+    except:
+        traceback.print_exc()
+        pass
+    vbox.eventSource.unregisterListener(listener)
 
 
@@ -1387,4 +1407,14 @@
         dur = float(args[1])
     monitorVBox(ctx, dur)
+    return 0
+
+def monitorVBox2Cmd(ctx, args):
+    if (len(args) > 2):
+        print "usage: monitorVBox2 (duration)"
+        return 0
+    dur = 5
+    if len(args) > 1:
+        dur = float(args[1])
+    monitorVBox2(ctx, dur)
     return 0
 
@@ -2856,4 +2886,5 @@
             'monitorGuest':['Monitor what happens with the guest for some time: monitorGuest Win32 10', monitorGuestCmd, 0],
             'monitorVBox':['Monitor what happens with Virtual Box for some time: monitorVBox 10', monitorVBoxCmd, 0],
+            'monitorVBox2':['(temp)Monitor what happens with Virtual Box for some time: monitorVBox2 10', monitorVBox2Cmd, 0],
             'portForward':['Setup permanent port forwarding for a VM, takes adapter number host port and guest port: portForward Win32 0 8080 80', portForwardCmd, 0],
             'showLog':['Show log file of the VM, : showLog Win32', showLogCmd, 0],
Index: /trunk/src/VBox/Main/EventImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/EventImpl.cpp	(revision 30344)
+++ /trunk/src/VBox/Main/EventImpl.cpp	(revision 30345)
@@ -61,4 +61,9 @@
     HRESULT rc = S_OK;
 
+    AssertReturn(aSource != NULL, E_INVALIDARG);
+     
+    AutoInitSpan autoInitSpan(this);
+    AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
     m->mSource = aSource;
     m->mType = aType;
@@ -74,10 +79,12 @@
             {
                 AssertFailed ();
-                rc = setError(E_FAIL,
-                              tr("Internal error (%Rrc)"), vrc);
-                break;
+                return setError(E_FAIL,
+                                tr("Internal error (%Rrc)"), vrc);
             }
         }
     } while (0);
+
+    /* Confirm a successful initialization */
+    autoInitSpan.setSucceeded();
 
     return rc;
@@ -231,5 +238,7 @@
             return TRUE;
         case VBoxEventType_MachineEvent:
-            return (what == VBoxEventType_OnMachineStateChange) || (what == VBoxEventType_OnMachineDataChange);
+            return     (what == VBoxEventType_OnMachineStateChange)
+                    || (what == VBoxEventType_OnMachineDataChange)
+                    || (what == VBoxEventType_OnMachineRegistered);
         case VBoxEventType_Invalid:
             return FALSE;
@@ -262,6 +271,9 @@
     }
 
-    ::RTCritSectInitEx(&mcsQLock, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL);
-    ::RTSemEventCreate (&mQEvent);
+    if (!mActive)
+    {
+        ::RTCritSectInitEx(&mcsQLock, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL);
+        ::RTSemEventCreate (&mQEvent);
+    }
 }
 
@@ -275,6 +287,9 @@
     }
 
-    ::RTCritSectDelete(&mcsQLock);
-    ::RTSemEventDestroy(mQEvent);
+    if (!mActive)
+    {
+        ::RTCritSectDelete(&mcsQLock);
+        ::RTSemEventDestroy(mQEvent);
+    }
 }
 
@@ -343,4 +358,11 @@
 }
 
+
+EventSource::EventSource()
+{}
+
+EventSource::~EventSource()
+{}
+
 HRESULT EventSource::FinalConstruct()
 {
@@ -355,8 +377,13 @@
 }
 
-
-HRESULT EventSource::init()
+HRESULT EventSource::init(IUnknown * aParent)
 {
     HRESULT rc = S_OK;
+
+    AutoInitSpan autoInitSpan(this);
+    AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
+    /* Confirm a successful initialization */
+    autoInitSpan.setSucceeded();
     return rc;
 }
@@ -366,4 +393,21 @@
     m->mListeners.clear();
     // m->mEvMap shall be cleared at this point too by destructors
+}
+
+STDMETHODIMP EventSource::CreateListener(IEventListener ** aListener)
+{
+    CheckComArgOutPointerValid(aListener);
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    ComPtr<IEventListener> listener;
+
+    HRESULT rc = listener.createLocalObject(CLSID_CallbackWrapper);
+    ComAssertMsgRet(SUCCEEDED(rc), ("Could not create wrapper object (%Rrc)", rc),
+                    E_FAIL);
+
+    listener.queryInterfaceTo(aListener);
+    return S_OK;
 }
 
@@ -487,12 +531,8 @@
 
     if (it != m->mListeners.end())
-    {
         rc = it->second.dequeue(aEvent, aTimeout);
-    }
-    else
-    {
+    else
         rc = setError(VBOX_E_OBJECT_NOT_FOUND,
                       tr("Listener was never registered"));
-    }
 
     return rc;
Index: /trunk/src/VBox/Main/VirtualBoxCallbackImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/VirtualBoxCallbackImpl.cpp	(revision 30344)
+++ /trunk/src/VBox/Main/VirtualBoxCallbackImpl.cpp	(revision 30345)
@@ -18,4 +18,5 @@
 #include "VirtualBoxCallbackImpl.h"
 #include "Logging.h"
+#include "AutoCaller.h"
 
 HRESULT CallbackWrapper::FinalConstruct()
@@ -31,4 +32,8 @@
 HRESULT CallbackWrapper::init()
 {
+    AutoInitSpan autoInitSpan(this);
+    AssertReturn(autoInitSpan.isOk(), E_FAIL);
+    /* Confirm a successful initialization */
+    autoInitSpan.setSucceeded();
     return S_OK;
 }
@@ -316,2 +321,8 @@
     return mConsoleCallback->OnShowWindow(winId);
 }
+
+STDMETHODIMP CallbackWrapper::HandleEvent(IEvent * aEvent)
+{
+    ComAssertMsgRet(false, ("HandleEvent() of wrapper shall never be called"),
+                    E_FAIL);
+}
Index: /trunk/src/VBox/Main/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 30344)
+++ /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 30345)
@@ -67,4 +67,5 @@
 #include "PerformanceImpl.h"
 #endif /* VBOX_WITH_RESOURCE_USAGE_API */
+#include "EventImpl.h"
 
 #include "AutoCaller.h"
@@ -355,4 +356,5 @@
     ComEventsHelper                     mComEvHelper;
 #endif
+    const ComObjPtr<EventSource>        pEventSource;
 };
 
@@ -532,4 +534,10 @@
             if (FAILED(rc)) throw rc;
         }
+
+        /* events */
+        if (SUCCEEDED(rc = unconst(m->pEventSource).createObject()))
+            rc = m->pEventSource->init(this);
+        if (FAILED(rc)) throw rc;
+
     }
     catch (HRESULT err)
@@ -595,5 +603,4 @@
         rc = m->mComEvHelper.init(IID_IVirtualBoxCallback);
 #endif
-
     /* Confirm a successful initialization when it's the case */
     if (SUCCEEDED(rc))
@@ -736,4 +743,11 @@
         m->pHost->uninit();
         unconst(m->pHost).setNull();
+    }
+
+    LogFlowThisFunc(("Releasing event source...\n"));
+    if (m->pEventSource)
+    {
+        m->pEventSource->uninit();
+        unconst(m->pEventSource).setNull();
     }
 
@@ -1041,4 +1055,18 @@
     SafeIfaceArray<IDHCPServer> svrs(m->ollDHCPServers.getList());
     svrs.detachTo(ComSafeArrayOutArg(aDHCPServers));
+
+    return S_OK;
+}
+
+STDMETHODIMP
+VirtualBox::COMGETTER(EventSource)(IEventSource ** aEventSource)
+{
+    CheckComArgOutPointerValid(aEventSource);
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    /* event source is const, no need to lock */
+    m->pEventSource.queryInterfaceTo(aEventSource);
 
     return S_OK;
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 30344)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 30345)
@@ -1605,5 +1605,5 @@
   <interface
     name="IVirtualBox" extends="$unknown"
-    uuid="3f36e024-7fed-4f20-a02c-9158a82b44e6"
+    uuid="f0c2e058-8c72-4d56-95e7-3107627aba6e"
     wsmap="managed"
   >
@@ -1738,4 +1738,11 @@
       </desc>
     </attribute>
+
+    <attribute name="eventSource" type="IEventSource" readonly="yes">
+      <desc>
+        Event source for VirtualBox events.
+      </desc>
+    </attribute>
+
 
     <method name="createMachine">
@@ -13979,5 +13986,5 @@
       <param name="return" type="ISession" dir="return"/>
     </method>
-
+    
     <method name="logoff">
       <desc>
@@ -14595,6 +14602,41 @@
       </desc>
     </const>
-
-    <const name="Last" value="35">
+    <const name="OnMediumRegistered" value="35">
+      <desc>
+        <see>IVirtualBoxCallback::onMediumRegistered</see>
+      </desc>
+    </const>
+    <const name="OnMachineRegistered" value="36">
+      <desc>
+        <see>IVirtualBoxCallback::onMachineRegistered</see>
+      </desc>
+    </const>
+    <const name="OnSessionStateChange" value="37">
+      <desc>
+        <see>IVirtualBoxCallback::onSessionStateChange</see>
+      </desc>
+    </const>
+    <const name="OnSnapshotTaken" value="38">
+      <desc>
+        <see>IVirtualBoxCallback::onSnapshotTaken</see>
+      </desc>
+    </const>
+    <const name="OnSnapshotDeleted" value="39">
+      <desc>
+        <see>IVirtualBoxCallback::onSnapshotDeleted</see>
+      </desc>
+    </const>
+    <const name="OnSnapshotChange" value="40">
+      <desc>
+        <see>IVirtualBoxCallback::onSnapshotChange</see>
+      </desc>
+    </const>
+    <const name="OnGuestPropertyChange" value="42">
+      <desc>
+        <see>IVirtualBoxCallback::onGuestPropertyChange</see>
+      </desc>
+    </const>
+
+    <const name="Last" value="43">
       <desc>
         Must be last event, used for iterations.
@@ -14617,4 +14659,12 @@
     </desc>
 
+    <method name="createListener">
+      <desc>
+        Creates new listener object, useful for passive mode.
+        <see>IEventListener</see>
+      </desc>
+      <param name="listener" type="IEventListener" dir="return"/>
+    </method>
+
     <method name="registerListener">
       <desc>
@@ -14644,5 +14694,5 @@
     <method name="unregisterListener">
       <desc>
-        Unregister an event listener. If listener is passive, and some waitable events are still 
+        Unregister an event listener. If listener is passive, and some waitable events are still
         in queue they are marked as processed automatically.
       </desc>
@@ -14688,6 +14738,6 @@
     <method name="eventProcessed">
       <desc>
-        Must be called for waitable events when particular listener finished event processing. 
-        When all listeners who this event was aimed to call eventProcessed() event source 
+        Must be called for waitable events when particular listener finished event processing.
+        When all listeners who this event was aimed to call eventProcessed() event source
         can call event's setProcessed().
       </desc>
@@ -14773,6 +14823,20 @@
   </interface>
 
+
   <interface
-      name="IMachineStateChangeEvent" extends="IEvent"
+      name="IMachineEvent" extends="IEvent"
+      uuid="92ed7b1a-0d96-40ed-ae46-a564d484325e"
+      wsmap="managed"
+      >
+    <desc>Base interface for all machine events.</desc>
+
+    <attribute name="machineId" readonly="yes" type="uuid" mod="string">
+      <desc>ID of the machine this event relates to.</desc>
+    </attribute>
+
+  </interface>
+
+  <interface
+      name="IMachineStateChangeEvent" extends="IMachineEvent"
       uuid="5748F794-48DF-438D-85EB-98FFD70D18C9"
       wsmap="managed"
@@ -14780,15 +14844,11 @@
     <desc>Machine state change event.</desc>
 
-    <attribute name="machineId" readonly="yes" type="uuid" mod="string">
-      <desc>ID of the machine this event relates to.</desc>
-    </attribute>
-
-     <attribute name="state" readonly="yes" type="MachineState">
-       <desc>New execution state.</desc>
-     </attribute>
+    <attribute name="state" readonly="yes" type="MachineState">
+      <desc>New execution state.</desc>
+    </attribute>
   </interface>
 
   <interface
-      name="IMachineDataChangeEvent" extends="IEvent"
+      name="IMachineDataChangeEvent" extends="IMachineEvent"
       uuid="6AA70A6C-0DCA-4810-8C5C-457B278E3D49"
       wsmap="managed"
@@ -14797,9 +14857,121 @@
       Any of the settings of the given machine has changed.
     </desc>
-
-    <attribute name="machineId" readonly="yes" type="uuid" mod="string">
-      <desc>ID of the machine this event relates to.</desc>
-    </attribute>
-
+  </interface>
+
+  <interface
+      name="IMachineRegisteredEvent" extends="IMachineEvent"
+      uuid="c354a762-3ff2-4f2e-8f09-07382ee25088"
+      wsmap="managed"
+      >
+    <desc>
+      The given machine was registered or unregistered
+      within this VirtualBox installation.
+    </desc>
+
+    <attribute name="registered" type="boolean" readonly="yes">
+      <desc>
+        If @c true, the machine was registered, otherwise it was
+        unregistered.
+      </desc>
+    </attribute>
+  </interface>
+
+  <interface
+      name="IMachineSessionStateEvent" extends="IMachineEvent"
+      uuid="714a3eef-799a-4489-86cd-fe8e45b2ff8e"
+      wsmap="managed"
+      >
+    <desc>
+      The state of the session for the given machine was changed.
+      <see>IMachine::sessionState</see>
+    </desc>
+
+    <attribute name="state" type="SessionState" readonly="yes">
+      <desc>
+        New session state.
+      </desc>
+    </attribute>
+  </interface>
+
+  <interface
+      name="IGuestPropertyChangeEvent" extends="IMachineEvent"
+      uuid="3f63597a-26f1-4edb-8dd2-6bddd0912368"
+      wsmap="managed"
+      >
+    <desc>
+      Notification when a guest property has changed.
+    </desc>
+
+    <attribute name="name" readonly="yes" type="wstring">
+      <desc>
+        The name of the property that has changed.
+      </desc>
+    </attribute>
+
+    <attribute name="value" readonly="yes" type="wstring">
+      <desc>
+        The new property value.
+      </desc>
+    </attribute>
+
+     <attribute name="flags" readonly="yes" type="wstring">
+      <desc>
+        The new property flags.
+      </desc>
+    </attribute>
+
+  </interface>
+
+  <interface
+      name="ISnapshotEvent" extends="IMachineEvent"
+      uuid="21637b0e-34b8-42d3-acfb-7e96daf77c22"
+      wsmap="managed"
+      >
+    <desc>Base interface for all snapshot events.</desc>
+
+    <attribute name="snapshotId" readonly="yes" type="uuid" mod="string">
+      <desc>ID of the snapshot this event relates to.</desc>
+    </attribute>
+
+  </interface>
+
+  <interface
+     name="ISnapshotTakenEvent" extends="ISnapshotEvent"
+     uuid="d27c0b3d-6038-422c-b45e-6d4a0503d9f1"
+     wsmap="managed"
+     >
+    <desc>
+      A new snapshot of the machine has been taken.
+      <see>ISnapshot</see>
+    </desc>
+  </interface>
+
+  <interface
+     name="ISnapshotDeletedEvent" extends="ISnapshotEvent"
+     uuid="c48f3401-4a9e-43f4-b7a7-54bd285e22f4"
+     wsmap="managed"
+     >
+    <desc>
+      Snapshot of the given machine has been deleted.
+
+      <note>
+        This notification is delivered <b>after</b> the snapshot
+        object has been uninitialized on the server (so that any
+        attempt to call its methods will return an error).
+      </note>
+
+      <see>ISnapshot</see>
+    </desc>
+  </interface>
+
+   <interface
+     name="ISnapshotChangedEvent" extends="ISnapshotEvent"
+     uuid="07541941-8079-447a-a33e-47a69c7980db"
+     wsmap="managed"
+     >
+    <desc>
+      Snapshot properties (name and/or description) have been changed.
+      <see>ISnapshot</see>
+    </desc>
   </interface>
 
@@ -14851,9 +15023,10 @@
     </class>
 
-    <class name="CallbackWrapper" uuid="49EE8561-5563-4715-B18C-A4B1A490DAFE"
+    <class name="CallbackWrapper" uuid="bcacd681-7f53-4409-a2a5-8534911f9358"
            namespace="virtualbox.org">
       <interface name="ILocalOwner" default="yes"/>
       <interface name="IVirtualBoxCallback"/>
       <interface name="IConsoleCallback"/>
+      <interface name="IEventListener"/>
     </class>
   </module>
Index: /trunk/src/VBox/Main/include/EventImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/EventImpl.h	(revision 30344)
+++ /trunk/src/VBox/Main/include/EventImpl.h	(revision 30345)
@@ -69,7 +69,7 @@
 
 class ATL_NO_VTABLE EventSource :
+    public VirtualBoxBase,
     public VirtualBoxSupportErrorInfoImpl<EventSource, IEventSource>,
     public VirtualBoxSupportTranslation<EventSource>,
-    public VirtualBoxBase,
     VBOX_SCRIPTABLE_IMPL(IEventSource)
 {
@@ -88,6 +88,5 @@
     END_COM_MAP()
 
-    EventSource() {}
-    virtual ~EventSource() {}
+    DECLARE_EMPTY_CTOR_DTOR (EventSource)
 
     HRESULT FinalConstruct();
@@ -95,8 +94,9 @@
 
     // public initializer/uninitializer for internal purposes only
-    HRESULT init ();
+    HRESULT init (IUnknown * aParent);
     void uninit();
 
     // IEventSource methods
+    STDMETHOD(CreateListener)(IEventListener ** aListener);
     STDMETHOD(RegisterListener)(IEventListener * aListener, 
                                 ComSafeArrayIn(VBoxEventType_T, aInterested),
Index: /trunk/src/VBox/Main/include/VirtualBoxCallbackImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxCallbackImpl.h	(revision 30344)
+++ /trunk/src/VBox/Main/include/VirtualBoxCallbackImpl.h	(revision 30345)
@@ -25,5 +25,6 @@
     VBOX_SCRIPTABLE_IMPL(ILocalOwner),
     VBOX_SCRIPTABLE_IMPL(IConsoleCallback),
-    VBOX_SCRIPTABLE_IMPL(IVirtualBoxCallback)
+    VBOX_SCRIPTABLE_IMPL(IVirtualBoxCallback),
+    VBOX_SCRIPTABLE_IMPL(IEventListener)
 #ifdef RT_OS_WINDOWS
     , public CComCoClass<CallbackWrapper, &CLSID_CallbackWrapper>
@@ -45,4 +46,5 @@
         COM_INTERFACE_ENTRY(IVirtualBoxCallback)
         COM_INTERFACE_ENTRY(IConsoleCallback)
+        COM_INTERFACE_ENTRY(IEventListener)
     END_COM_MAP()
 
@@ -95,4 +97,7 @@
     STDMETHOD(OnShowWindow)(ULONG64 *winId);
 
+    // IEventListener
+    STDMETHOD(HandleEvent)(IEvent *aEvent);
+
     // for VirtualBoxSupportErrorInfoImpl
     static const wchar_t *getComponentName() { return L"CallbackWrapper"; }
Index: /trunk/src/VBox/Main/include/VirtualBoxImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 30344)
+++ /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 30345)
@@ -96,5 +96,5 @@
          CONNECTION_POINT_ENTRY(IID_IVirtualBoxCallback)
     END_CONNECTION_POINT_MAP()
-   
+
     typedef CComDynamicUnkArray EventListenersList;
 #endif
@@ -130,4 +130,5 @@
     STDMETHOD(COMGETTER(PerformanceCollector)) (IPerformanceCollector **aPerformanceCollector);
     STDMETHOD(COMGETTER(DHCPServers)) (ComSafeArrayOut (IDHCPServer *, aDHCPServers));
+    STDMETHOD(COMGETTER(EventSource)) (IEventSource ** aEventSource);
 
     /* IVirtualBox methods */
Index: /trunk/src/VBox/Main/xpcom/module.cpp
===================================================================
--- /trunk/src/VBox/Main/xpcom/module.cpp	(revision 30344)
+++ /trunk/src/VBox/Main/xpcom/module.cpp	(revision 30345)
@@ -46,4 +46,5 @@
 #include "ConsoleVRDPServer.h"
 #include "VirtualBoxCallbackImpl.h"
+#include "EventImpl.h"
 
 #include "Logging.h"
@@ -73,4 +74,6 @@
 NS_DECL_CLASSINFO(RemoteDisplayInfo)
 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(RemoteDisplayInfo, IRemoteDisplayInfo)
+NS_DECL_CLASSINFO(EventSource)
+NS_IMPL_THREADSAFE_ISUPPORTS1_CI(EventSource, IEventSource)
 
 NS_DECL_CLASSINFO(Session)
@@ -80,4 +83,5 @@
 NS_DECL_CLASSINFO(CallbackWrapper)
 NS_IMPL_THREADSAFE_ISUPPORTS3_CI(CallbackWrapper, IVirtualBoxCallback, IConsoleCallback, ILocalOwner)
+
 /**
  *  Singleton class factory that holds a reference to the created instance
Index: /trunk/src/VBox/Main/xpcom/server.cpp
===================================================================
--- /trunk/src/VBox/Main/xpcom/server.cpp	(revision 30344)
+++ /trunk/src/VBox/Main/xpcom/server.cpp	(revision 30345)
@@ -87,4 +87,5 @@
 #include <AudioAdapterImpl.h>
 #include <SystemPropertiesImpl.h>
+#include <EventImpl.h>
 
 /* implement nsISupports parts of our objects with support for nsIClassInfo */
@@ -197,4 +198,7 @@
 NS_DECL_CLASSINFO(BIOSSettings)
 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(BIOSSettings, IBIOSSettings)
+
+NS_DECL_CLASSINFO(EventSource)
+NS_IMPL_THREADSAFE_ISUPPORTS1_CI(EventSource, IEventSource)
 
 ////////////////////////////////////////////////////////////////////////////////
