Index: /trunk/src/VBox/Main/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 29873)
+++ /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 29874)
@@ -4463,4 +4463,5 @@
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -4498,16 +4499,60 @@
 #if 0
     // WIP
+
+    LPTYPEINFO       ptinfo;
+    HRESULT          hr;
+    LPTYPELIB        ptlib;
+    DISPID           dispid;
+
+    /* Real solution must cache all needed dispids once, ofc */
+    hr = ::LoadRegTypeLib(LIBID_VirtualBox, kTypeLibraryMajorVersion, kTypeLibraryMinorVersion, LOCALE_SYSTEM_DEFAULT, &ptlib);
+    hr = ptlib->GetTypeInfoOfGuid(IID_IVirtualBoxCallback, &ptinfo);
+    ptlib->Release();
+
+    OLECHAR FAR* szMember = L"OnMachineStateChange";
+
+    hr = ::DispGetIDsOfNames(ptinfo, &szMember, 1, &dispid);
+    ptinfo->Release();
+
     int nConnections = mVirtualBox->m_vec.GetSize();
     for (int i=0; i<nConnections; i++)
     {
-        CComPtr<IUnknown> sp = mVirtualBox->m_vec.GetAt(i);
-        IVirtualBoxCallback* cb = reinterpret_cast<IVirtualBoxCallback*>(sp.p);
-        if (cb != NULL)
-        {
-            HRESULT hrc = handleCallback(cb);
+        ComPtr<IUnknown> sp = mVirtualBox->m_vec.GetAt(i);
+        ComPtr<IVirtualBoxCallback> cbI;
+        ComPtr<IDispatch> cbD;
+    
+        cbI = sp;
+        cbD = sp;
+
+        /**
+         * Would be like this in ideal world, unfortunately our consumers want to be invoked via IDispatch, 
+         * thus going the hard way.
+         */
+#if 0	
+        if (cbI != NULL)
+        {    
+            HRESULT hrc = handleCallback(cbI);
             if (hrc == VBOX_E_DONT_CALL_AGAIN)
             {
                 // need to handle that somehow, maybe just set element to 0
             }
+        }
+#endif
+        if (cbI != NULL && cbD != NULL)
+        {
+             CComVariant varResult, arg1, arg2;
+
+             ::VariantClear(&varResult);
+             ::VariantClear(&arg1); 
+             ::VariantClear(&arg2);
+             
+             VARIANTARG args[] = {arg1, arg2};
+             DISPPARAMS disp = { args, NULL, sizeof(args)/sizeof(args[0]), 0};
+
+             cbD->Invoke(dispid, IID_NULL,
+                         LOCALE_USER_DEFAULT, 
+                         DISPATCH_METHOD, 
+                         &disp, &varResult, 
+                         NULL, NULL);
         }
     }
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 29873)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 29874)
@@ -14529,4 +14529,5 @@
            namespace="virtualbox.org">
       <interface name="IVirtualBox" default="yes"/>
+      <eventsink name="IVirtualBoxCallback" default="yes"/>
     </class>
   </module>
@@ -14536,4 +14537,6 @@
            namespace="virtualbox.org">
       <interface name="ISession" default="yes"/>
+      <eventsink name="IConsoleCallback" default="yes"/>
+
     </class>
     <class name="CallbackWrapper" uuid="49EE8561-5563-4715-B18C-A4B1A490DAFE"
Index: /trunk/src/VBox/Main/idl/midl.xsl
===================================================================
--- /trunk/src/VBox/Main/idl/midl.xsl	(revision 29873)
+++ /trunk/src/VBox/Main/idl/midl.xsl	(revision 29874)
@@ -630,4 +630,14 @@
     </xsl:if>
     <xsl:text>interface </xsl:text>
+    <xsl:value-of select="@name"/>
+    <xsl:text>;&#x0A;</xsl:text>
+  </xsl:for-each>
+  <xsl:for-each select="eventsink">
+    <xsl:text>    </xsl:text>
+    <xsl:choose>
+      <xsl:when test="@default='yes'"><xsl:text>[default,source]</xsl:text></xsl:when>
+      <xsl:otherwise><xsl:text>[source]</xsl:text></xsl:otherwise>
+    </xsl:choose>
+    <xsl:text> interface </xsl:text>
     <xsl:value-of select="@name"/>
     <xsl:text>;&#x0A;</xsl:text>
