Index: /trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 33958)
+++ /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 33959)
@@ -255,13 +255,8 @@
 inline static const char *networkAdapterTypeToName(NetworkAdapterType_T adapterType);
 
-class VmEventListener :
-  VBOX_SCRIPTABLE_IMPL(IEventListener)
-{
+class VmEventListener {
 public:
     VmEventListener(Console *aConsole)
     {
-#ifndef VBOX_WITH_XPCOM
-        refcnt = 0;
-#endif
         mfNoLoggedInUsers = true;
         mConsole = aConsole;
@@ -272,25 +267,6 @@
     }
 
-#ifndef VBOX_WITH_XPCOM
-    STDMETHOD_(ULONG, AddRef)()
-    {
-        return ::InterlockedIncrement(&refcnt);
-    }
-    STDMETHOD_(ULONG, Release)()
-    {
-        long cnt = ::InterlockedDecrement(&refcnt);
-        if (cnt == 0)
-            delete this;
-        return cnt;
-    }
-#endif
-    VBOX_SCRIPTABLE_DISPATCH_IMPL(IEventListener)
-
-    NS_DECL_ISUPPORTS
-
-    STDMETHOD(HandleEvent)(IEvent * aEvent)
-    {
-        VBoxEventType_T aType = VBoxEventType_Invalid;
-        aEvent->COMGETTER(Type)(&aType);
+    STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent * aEvent)
+    {
         switch(aType)
         {
@@ -337,16 +313,11 @@
     }
 private:
-#ifndef VBOX_WITH_XPCOM
-    long refcnt;
-#endif
-
     bool mfNoLoggedInUsers;
     Console *mConsole;
 };
 
-#ifdef VBOX_WITH_XPCOM
-NS_DECL_CLASSINFO(VmEventListener)
-NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VmEventListener, IEventListener)
-#endif
+typedef ListenerImpl<VmEventListener, Console*> VmEventListenerImpl;
+
+VBOX_LISTENER_DECLARE(VmEventListenerImpl)
 
 // ConsoleCallbackRegistration
@@ -600,6 +571,5 @@
         rc = virtualbox->COMGETTER(EventSource)(es.asOutParam());
         AssertComRC(rc);
-        mVmListner = new VmEventListener(this);
-        mVmListner->AddRef();
+        mVmListner = new VmEventListenerImpl(this);
         com::SafeArray <VBoxEventType_T> eventTypes;
         eventTypes.push_back(VBoxEventType_OnNATRedirectEvent);
Index: /trunk/src/VBox/Main/ConsoleVRDPServer.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleVRDPServer.cpp	(revision 33958)
+++ /trunk/src/VBox/Main/ConsoleVRDPServer.cpp	(revision 33959)
@@ -35,6 +35,5 @@
 #include <VBox/RemoteDesktop/VRDEOrders.h>
 
-class VRDPConsoleListener :
-    VBOX_SCRIPTABLE_IMPL(IEventListener)
+class VRDPConsoleListener
 {
 public:
@@ -42,47 +41,8 @@
         : m_server(server)
     {
-#ifndef VBOX_WITH_XPCOM
-        refcnt = 0;
-#endif /* !VBOX_WITH_XPCOM */
-    }
-
-    virtual ~VRDPConsoleListener() {}
-
-    NS_DECL_ISUPPORTS
-
-#ifndef VBOX_WITH_XPCOM
-    STDMETHOD_(ULONG, AddRef)() {
-        return ::InterlockedIncrement(&refcnt);
-    }
-    STDMETHOD_(ULONG, Release)()
-    {
-        long cnt = ::InterlockedDecrement(&refcnt);
-        if (cnt == 0)
-            delete this;
-        return cnt;
-    }
-    STDMETHOD(QueryInterface)(REFIID riid , void **ppObj)
-    {
-        if (riid == IID_IUnknown) {
-            *ppObj = (IUnknown*)this;
-            AddRef();
-            return S_OK;
-        }
-        if (riid == IID_IEventListener) {
-            *ppObj = (IEventListener*)this;
-            AddRef();
-            return S_OK;
-        }
-        *ppObj = NULL;
-        return E_NOINTERFACE;
-    }
-#endif /* !VBOX_WITH_XPCOM */
-
-
-    STDMETHOD(HandleEvent)(IEvent * aEvent)
-    {
-        VBoxEventType_T aType = VBoxEventType_Invalid;
-
-        aEvent->COMGETTER(Type)(&aType);
+    }
+
+    STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent * aEvent)
+    {
         switch (aType)
         {
@@ -145,14 +105,9 @@
                                          ULONG width, ULONG height, ComSafeArrayIn(BYTE,shape));
     ConsoleVRDPServer *m_server;
-#ifndef VBOX_WITH_XPCOM
-    long refcnt;
-#endif /* !VBOX_WITH_XPCOM */
 };
 
-#ifdef VBOX_WITH_XPCOM
-#include <nsMemory.h>
-NS_DECL_CLASSINFO(VRDPConsoleListener)
-NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VRDPConsoleListener, IEventListener)
-#endif /* VBOX_WITH_XPCOM */
+typedef ListenerImpl<VRDPConsoleListener, ConsoleVRDPServer*> VRDPConsoleListenerImpl;
+
+VBOX_LISTENER_DECLARE(VRDPConsoleListenerImpl)
 
 #ifdef DEBUG_sunlover
@@ -1220,6 +1175,5 @@
         ComPtr<IEventSource> es;
         console->COMGETTER(EventSource)(es.asOutParam());
-        mConsoleListener = new VRDPConsoleListener(this);
-        mConsoleListener->AddRef();
+        mConsoleListener = new VRDPConsoleListenerImpl(this);
         com::SafeArray <VBoxEventType_T> eventTypes;
         eventTypes.push_back(VBoxEventType_OnMousePointerShapeChanged);
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 33958)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 33959)
@@ -15595,6 +15595,6 @@
 
   <interface
-    name="INATRedirectEvent" extends="IEvent"
-    uuid="b566336e-ec24-11df-8fbd-f71b6f29dd03"
+    name="INATRedirectEvent" extends="IMachineEvent"
+    uuid="57DE97D7-3CBB-42A0-888F-610D5832D16B"
     wsmap="managed" autogen="VBoxEvent" id="OnNATRedirectEvent"
     >
@@ -15602,9 +15602,4 @@
       Notification when NAT redirect rule added or removed.
    </desc>
-     <attribute name="machineId" type="uuid" mod="string" readonly="yes">
-       <desc>
-        Machine id where redirect event is occured.
-       </desc>
-     </attribute>
      <attribute name="slot"  type="unsigned long" readonly="yes">
        <desc>
Index: /trunk/src/VBox/Main/include/EventImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/EventImpl.h	(revision 33958)
+++ /trunk/src/VBox/Main/include/EventImpl.h	(revision 33959)
@@ -20,4 +20,5 @@
 
 #include "VirtualBoxBase.h"
+#include <iprt/asm.h>
 
 class ATL_NO_VTABLE VBoxEvent :
@@ -229,3 +230,76 @@
 };
 
+#define NS_IMPL_QUERY_HEAD_INLINE()                                   \
+NS_IMETHODIMP QueryInterface(REFNSIID aIID, void** aInstancePtr)      \
+{                                                                     \
+  NS_ASSERTION(aInstancePtr,                                          \
+               "QueryInterface requires a non-NULL destination!");    \
+  nsISupports* foundInterface;
+
+#ifndef RT_OS_WINDOWS
+#define NS_INTERFACE_MAP_BEGIN_INLINE()      NS_IMPL_QUERY_HEAD_INLINE()
+#define NS_IMPL_QUERY_INTERFACE1_INLINE(_i1)                                 \
+  NS_INTERFACE_MAP_BEGIN_INLINE()                                            \
+    NS_INTERFACE_MAP_ENTRY(_i1)                                              \
+    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1)                       \
+  NS_INTERFACE_MAP_END
+#endif
+
+template <class T, class TParam = void* >
+class ListenerImpl : VBOX_SCRIPTABLE_IMPL(IEventListener)
+{
+    T                 mListener;
+    volatile uint32_t mRefCnt;
+
+    virtual ~ListenerImpl()
+    {}
+
+public:
+    ListenerImpl(TParam param)
+    : mListener(param), mRefCnt(1)
+    {
+    }
+
+    /* On Windows QI implemented by VBOX_SCRIPTABLE_DISPATCH_IMPL */
+#ifndef RT_OS_WINDOWS
+    NS_IMPL_QUERY_INTERFACE1_INLINE(IEventListener)
+#endif
+
+#ifdef RT_OS_WINDOWS
+    STDMETHOD_(ULONG, AddRef)()
+#else
+    NS_IMETHOD_(nsrefcnt) AddRef(void)
+#endif
+    {
+        return ASMAtomicIncU32(&mRefCnt);
+    }
+
+#ifdef RT_OS_WINDOWS
+    STDMETHOD_(ULONG, Release)()
+#else
+    NS_IMETHOD_(nsrefcnt) Release(void)
+#endif
+    {
+        uint32_t cnt = ::ASMAtomicDecU32(&mRefCnt);
+        if (cnt == 0)
+            delete this;
+        return cnt;
+    }
+
+    VBOX_SCRIPTABLE_DISPATCH_IMPL(IEventListener)
+
+    STDMETHOD(HandleEvent)(IEvent * aEvent)
+    {
+        VBoxEventType_T aType = VBoxEventType_Invalid;
+        aEvent->COMGETTER(Type)(&aType);
+        return mListener.HandleEvent(aType, aEvent);
+    }
+};
+
+#ifdef VBOX_WITH_XPCOM
+#define VBOX_LISTENER_DECLARE(klazz) NS_DECL_CLASSINFO(klazz)
+#else
+#define VBOX_LISTENER_DECLARE(klazz)
+#endif
+
 #endif // ____H_EVENTIMPL
