diff --git a/pykd/dbgclient.cpp b/pykd/dbgclient.cpp
index ba96444..e792676 100644
--- a/pykd/dbgclient.cpp
+++ b/pykd/dbgclient.cpp
@@ -295,7 +295,12 @@ void DebugClient::waitForEvent()
     } while( false );
 
     if ( FAILED( hres ) )
+    {
+        if (E_UNEXPECTED == hres)
+            throw WaitEventException();
+
         throw  DbgException( "IDebugControl::WaitForEvent  failed" );
+    }
 }
 
 void waitForEvent()
@@ -317,6 +322,8 @@ ULONG DebugClient::ptrSize()
     return S_OK == hres ? 8 : 4;
 }
 
+///////////////////////////////////////////////////////////////////////////////////
+
 ULONG ptrSize()
 { 
     return g_dbgClient->ptrSize();
diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h
index cb6db3a..507ced2 100644
--- a/pykd/dbgclient.h
+++ b/pykd/dbgclient.h
@@ -222,6 +222,10 @@ public:
         return m_symSymbols->removeByMask(moduleName, symName);
     }
 
+    SynSymbolsPtr getSynSymbols() {
+        return m_symSymbols;
+    }
+
 private:
 
     template<typename T>
diff --git a/pykd/dbgevent.cpp b/pykd/dbgevent.cpp
index bf26aa4..0644d59 100644
--- a/pykd/dbgevent.cpp
+++ b/pykd/dbgevent.cpp
@@ -177,25 +177,8 @@ HRESULT EventHandler::LoadModule(
     __in ULONG TimeDateStamp
 )
 {
-    //PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
-
-    //return onLoadModule( module );
-
-    //std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
-
-    //ULONG64         moduleBase;
-    //ULONG           moduleSize;
-    //std::string     moduleName;       
-    //
-    //queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
-    //dbgModuleClass module(moduleName, moduleBase, moduleSize);
-    //silentMode.reset(); 
-
-    //PyThread_StateSave pyThreadSave;
-    //return onLoadModule( module );
-
-    return S_OK;
-
+    PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
+    return onLoadModule( m_parentClient->loadModuleByOffset(BaseOffset) );
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -205,19 +188,9 @@ HRESULT EventHandler::UnloadModule(
     __in ULONG64 BaseOffset
 )
 {
-    //std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
-
-    //ULONG64         moduleBase;
-    //ULONG           moduleSize;
-    //std::string     moduleName;       
-    //
-    //queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
-    //dbgModuleClass module(moduleName, moduleBase, moduleSize);
-    //silentMode.reset(); 
-
-    //PyThread_StateSave pyThreadSave;
-    //return onUnloadModule( module );
-    return S_OK;
+    PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
+    BaseOffset = m_parentClient->addr64(BaseOffset);
+    return onUnloadModule( BaseOffset );
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/dbgevent.h b/pykd/dbgevent.h
index aaacaf4..d20a127 100644
--- a/pykd/dbgevent.h
+++ b/pykd/dbgevent.h
@@ -75,7 +75,7 @@ protected:
 
     virtual ULONG onLoadModule(const Module &/* module */)  = 0;
 
-    virtual ULONG onUnloadModule(const Module &/* module */)  = 0;
+    virtual ULONG onUnloadModule(ULONG64 /*modBase*/)  = 0;
     
     virtual ULONG onChangeSessionStatus( ULONG status ) = 0;
     
@@ -113,8 +113,8 @@ public:
         return handler<const Module&>("onLoadModule", module );
     }
 
-    ULONG onUnloadModule(const Module &module) {
-        return handler<const Module&>("onUnloadModule", module );
+    ULONG onUnloadModule(ULONG64 modBase) {
+        return handler<ULONG64>("onUnloadModule", modBase );
     }
 
     ULONG onChangeSessionStatus( ULONG status ) {
diff --git a/pykd/dbgexcept.cpp b/pykd/dbgexcept.cpp
index d557cd4..f2494a6 100644
--- a/pykd/dbgexcept.cpp
+++ b/pykd/dbgexcept.cpp
@@ -7,6 +7,7 @@ namespace pykd {
 
 PyObject *DbgException::baseExceptTypeObject = NULL;
 PyObject *MemoryException::memoryExceptionTypeObject = NULL;
+PyObject *WaitEventException::waitEventExceptTypeObject = NULL;
 
 /////////////////////////////////////////////////////////////////////////////////
 
@@ -36,6 +37,16 @@ std::string buildExceptDesc(PCSTR routineName, HRESULT hres)
     return sstream.str();
 }
 
+/////////////////////////////////////////////////////////////////////////////////
+
+void WaitEventException::exceptionTranslate( const WaitEventException &e )
+{
+    python::object pyExcept(e);
+
+    PyErr_SetObject( waitEventExceptTypeObject, pyExcept.ptr() );
+}
+
+
 /////////////////////////////////////////////////////////////////////////////////
 
 }; // end namespace pykd
diff --git a/pykd/dbgexcept.h b/pykd/dbgexcept.h
index f5033ea..078394d 100644
--- a/pykd/dbgexcept.h
+++ b/pykd/dbgexcept.h
@@ -116,6 +116,25 @@ private:
 std::string buildExceptDesc(PCSTR routineName, HRESULT hres);
 
 
+///////////////////////////////////////////////////////////////////////////////////
+
+class WaitEventException : public DbgException
+{
+public:
+    WaitEventException()
+        : DbgException( "None of the targets could generate events" )
+    {
+    }
+
+    static void exceptionTranslate(const WaitEventException &e);
+
+    static void setTypeObject(PyObject *p) {
+        waitEventExceptTypeObject = p;
+    }
+private:
+    static PyObject *waitEventExceptTypeObject;
+};
+
 ///////////////////////////////////////////////////////////////////////////////////
 
 }; // namespace pykd
diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index ad7cfce..61258ba 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -448,10 +448,10 @@ BOOST_PYTHON_MODULE( pykd )
             "Detailed information: http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx \n"
             "For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
         .def( "onLoadModule", &pykd::EventHandlerWrap::onLoadModule,
-            "Load module event. Parameter is instance of dbgModuleClass.\n"
+            "Load module event. Parameter is instance of module.\n"
             "For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
         .def( "onUnloadModule", &pykd::EventHandlerWrap::onUnloadModule,
-            "Unload module event. Parameter is instance of dbgModuleClass.\n"
+            "Unload module event. Parameter is base address of unloaded module.\n"
             "For ignore event method must return DEBUG_STATUS_NO_CHANGE value" );
 
     python::class_<Disasm>("disasm", "Class disassemble a processor instructions" )
@@ -662,6 +662,15 @@ BOOST_PYTHON_MODULE( pykd )
     python::register_exception_translator<pykd::MemoryException>(
         &pykd::MemoryException::exceptionTranslate );
 
+    // Wait debug event exception
+    python::class_<WaitEventException, python::bases<DbgException> > waitEventException( 
+        "WaitEventException", "Debug interface access exception", python::no_init);
+    waitEventException
+        _DECL_BASE_EXCEPT_STR;
+    WaitEventException::setTypeObject( waitEventException.ptr() );
+    python::register_exception_translator<WaitEventException>( 
+        &WaitEventException::exceptionTranslate );
+
     DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED );
     DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL );
     DEF_PY_CONST_ULONG( DEBUG_CLASS_USER_WINDOWS );
diff --git a/test/scripts/ehloadtest.py b/test/scripts/ehloadtest.py
new file mode 100644
index 0000000..2a0915f
--- /dev/null
+++ b/test/scripts/ehloadtest.py
@@ -0,0 +1,51 @@
+"""Debug events handler: test [un-]load modules notification"""
+
+import unittest
+import target
+import pykd
+import fnmatch
+
+class ModuleLoadHandler(pykd.eventHandler):
+    """Track load/unload module implementation"""
+    def __init__(self, client, moduleMask):
+        pykd.eventHandler.__init__(self, client)
+
+        self.moduleMask = moduleMask.lower()
+
+        self.wasLoad = 0
+        self.wasUnload = False
+
+    def onLoadModule(self, module):
+        """Load module handler"""
+
+        if ( fnmatch.fnmatch(module.name().lower(), self.moduleMask) ):
+            self.wasLoad = module.begin()
+
+        return pykd.DEBUG_STATUS_NO_CHANGE
+
+    def onUnloadModule(self, modBase):
+        """Unload module handler"""
+
+        if ( self.wasLoad and (self.wasLoad == modBase) ):
+            self.wasUnload = True
+
+        return pykd.DEBUG_STATUS_NO_CHANGE
+
+class EhLoadTest(unittest.TestCase):
+    """Unit tests of [un-]load modules notification"""
+
+    def testLoadUnload(self):
+        """Start new process and track loading and unloading modules"""
+        testClient = pykd.createDbgClient()
+        testClient.startProcess( target.appPath + " -testLoadUnload" )
+
+        modLoadHandler = ModuleLoadHandler( testClient, "*Iphlpapi*" )
+        try:
+            while True:
+                testClient.go()
+        except pykd.WaitEventException:
+            pass
+
+        self.assertTrue(modLoadHandler.wasLoad)
+        self.assertTrue(modLoadHandler.wasUnload)
+
diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py
index 5b78d8d..9d58449 100644
--- a/test/scripts/pykdtest.py
+++ b/test/scripts/pykdtest.py
@@ -23,6 +23,7 @@ import typedvar
 import memtest
 import intbase
 import synsymtest
+import ehloadtest
 
 def getTestSuite( singleName = "" ):
     if singleName == "":
@@ -37,7 +38,8 @@ def getTestSuite( singleName = "" ):
                unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest ),
                unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
                unittest.TestLoader().loadTestsFromTestCase( intbase.IntBaseTest ),
-               unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest )
+               unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest ),
+               unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest )
            ] ) 
     else:
        return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
@@ -45,12 +47,12 @@ def getTestSuite( singleName = "" ):
 
 if __name__ == "__main__":
 
-    targetAppPath = sys.argv[1]
+    target.appPath = sys.argv[1]
    
-    target.moduleName = os.path.splitext(os.path.basename(targetAppPath))[0]
-    print "\nTest module: %s" % targetAppPath
+    target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]
+    print "\nTest module: %s" % target.appPath
   
-    pykd.startProcess( targetAppPath )
+    pykd.startProcess( target.appPath )
 
     target.module = pykd.loadModule( target.moduleName )
     target.module.reload();
diff --git a/test/scripts/target.py b/test/scripts/target.py
index 8d64d02..2fcf817 100644
--- a/test/scripts/target.py
+++ b/test/scripts/target.py
@@ -4,4 +4,5 @@
 
 module = None
 moduleName = None
-dbgext = None
\ No newline at end of file
+dbgext = None
+appPath = None
diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp
index 75723ed..7231543 100644
--- a/test/targetapp/targetapp.cpp
+++ b/test/targetapp/targetapp.cpp
@@ -159,6 +159,7 @@ void FuncWithName1(int a)
 
 int doLoadUnload()
 {
+    __debugbreak();
     HMODULE hmod = ::LoadLibrary( _T("iphlpapi.dll") );
     if (hmod)
         ::FreeLibrary(hmod);
@@ -172,6 +173,9 @@ int _tmain(int argc, _TCHAR* argv[])
 {
     try
     {
+        // Let test scripts to execute
+        __debugbreak();
+
         if (2 == argc)
         {
             // run with parameters
@@ -179,8 +183,6 @@ int _tmain(int argc, _TCHAR* argv[])
                 return doLoadUnload();
         }
 
-        // Let test scripts to execute
-        __debugbreak();
         __debugbreak();
         __debugbreak();
         __debugbreak();
diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj
index 03cd77b..b147454 100644
--- a/test/targetapp/targetapp.vcproj
+++ b/test/targetapp/targetapp.vcproj
@@ -416,6 +416,10 @@
 				RelativePath="..\scripts\diatest.py"
 				>
 			</File>
+			<File
+				RelativePath="..\scripts\ehloadtest.py"
+				>
+			</File>
 			<File
 				RelativePath="..\scripts\eventtest.py"
 				>