diff --git a/pykd/pydbgeng.h b/pykd/pydbgeng.h
index de1aa72..0c16f8f 100644
--- a/pykd/pydbgeng.h
+++ b/pykd/pydbgeng.h
@@ -103,10 +103,19 @@ bool isKernelDebugging()
 }
 
 inline
-std::wstring debugCommand( const std::wstring &command )
+python::object debugCommand( const std::wstring &command,  bool suppressOutput = true)
 {
-    AutoRestorePyState  pystate;
-    return kdlib::debugCommand(command);
+    std::wstring  debugResult;
+
+    {
+        AutoRestorePyState  pystate;
+        debugResult = kdlib::debugCommand(command, suppressOutput);
+    }
+
+    if (debugResult.size() > 0 )
+        return python::object(debugResult);
+
+    return python::object();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -378,8 +387,6 @@ std::wstring callExtension( kdlib::EXTENSION_ID extId, const std::wstring comman
 
 ///////////////////////////////////////////////////////////////////////////////
 
-std::wstring debugCommand( const std::wstring &command );
-
 python::object evaluate( const std::wstring  &expression, bool cplusplus = false );
 
 python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset = 0 );
diff --git a/pykd/pydbgio.h b/pykd/pydbgio.h
index 43130b9..b0d53c7 100644
--- a/pykd/pydbgio.h
+++ b/pykd/pydbgio.h
@@ -12,6 +12,16 @@ class DbgOut : public  kdlib::windbg::WindbgOut
 {
 public:
 
+    virtual void write( const std::wstring& str ) {
+        AutoRestorePyState  pystate;
+        kdlib::windbg::WindbgOut::write(str);
+    }
+
+    virtual void writedml( const std::wstring& str ) {
+        AutoRestorePyState  pystate;
+        kdlib::windbg::WindbgOut::writedml(str);
+    }
+
     void flush() {
     }
 
@@ -42,14 +52,24 @@ class SysDbgOut : public DbgOut
 {
 public:
 
+    SysDbgOut() {
+         m_state = PyThreadState_Get();
+    }
+
     virtual void write( const std::wstring& str)  {
+        AutoSavePythonState  pystate( &m_state );
         python::object       sys = python::import("sys");
         sys.attr("stdout").attr("write")( str );
     }
 
     virtual void writedml( const std::wstring& str) {
+        AutoSavePythonState  pystate( &m_state );
         write(str);
     }
+
+private:
+
+    PyThreadState*    m_state;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -58,16 +78,26 @@ class SysDbgIn : public DbgIn
 {
 public:
 
+    SysDbgIn() {
+         m_state = PyThreadState_Get();
+    }
+
     virtual std::wstring readline() {
+        AutoSavePythonState  pystate( &m_state );
         python::object    sys = python::import("sys");
         return python::extract<std::wstring>( sys.attr("stdin").attr("readline") );
     }
+
+private:
+
+    PyThreadState*    m_state;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
 inline void dprint( const std::wstring &str, bool dml = false )
 {
+    AutoRestorePyState  pystate;
     kdlib::dprint(str,dml);
 }
 
@@ -75,6 +105,7 @@ inline void dprint( const std::wstring &str, bool dml = false )
 
 inline void dprintln( const std::wstring &str, bool dml = false )
 {
+    AutoRestorePyState  pystate;
     kdlib::dprintln(str,dml);
 }
 
@@ -82,6 +113,7 @@ inline void dprintln( const std::wstring &str, bool dml = false )
 
 inline void eprint( const std::wstring &str )
 {
+    AutoRestorePyState  pystate;
     kdlib::eprint(str);
 }
 
@@ -89,6 +121,7 @@ inline void eprint( const std::wstring &str )
 
 inline void eprintln( const std::wstring &str )
 {
+    AutoRestorePyState  pystate;
     kdlib::eprintln(str);
 }
 
diff --git a/pykd/pyeventhandler.cpp b/pykd/pyeventhandler.cpp
index 2d591fd..66e47b1 100644
--- a/pykd/pyeventhandler.cpp
+++ b/pykd/pyeventhandler.cpp
@@ -286,6 +286,28 @@ void EventHandler::onChangeLocalScope()
 
 /////////////////////////////////////////////////////////////////////////////////
 
+void EventHandler::onDebugOutput(const std::wstring& text)
+{
+    PyEval_RestoreThread( m_pystate );
+
+    try {
+
+        python::override pythonHandler = get_override("onDebugOutput");
+        if ( pythonHandler )
+        {
+            pythonHandler(text);
+        }
+    }
+    catch (const python::error_already_set &) 
+    {
+        printException();
+    }
+
+    m_pystate = PyEval_SaveThread();
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
 Breakpoint::Breakpoint(kdlib::BreakpointPtr bp)
 {
     m_pystate = PyThreadState_Get();
diff --git a/pykd/pyeventhandler.h b/pykd/pyeventhandler.h
index 890101f..ebdb7fa 100644
--- a/pykd/pyeventhandler.h
+++ b/pykd/pyeventhandler.h
@@ -35,6 +35,7 @@ public:
     virtual kdlib::DebugCallbackResult onModuleUnload( kdlib::MEMOFFSET_64 offset, const std::wstring &name );
     virtual void onCurrentThreadChange(kdlib::THREAD_DEBUG_ID  threadid);
     virtual void onChangeLocalScope();
+    virtual void onDebugOutput(const std::wstring& text);
 
 private:
 
diff --git a/pykd/pykdver.h b/pykd/pykdver.h
index f91c3ed..a6d7d37 100644
--- a/pykd/pykdver.h
+++ b/pykd/pykdver.h
@@ -2,7 +2,7 @@
 #define PYKD_VERSION_MAJOR      0
 #define PYKD_VERSION_MINOR      3
 #define PYKD_VERSION_SUBVERSION 0
-#define PYKD_VERSION_BUILDNO    14
+#define PYKD_VERSION_BUILDNO    15
 
 #define __VER_STR2__(x) #x
 #define __VER_STR1__(x) __VER_STR2__(x)
diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp
index cedef18..713cb3c 100644
--- a/pykd/pymod.cpp
+++ b/pykd/pymod.cpp
@@ -39,6 +39,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( detachProcess_,  pykd::detachProcess, 0, 1 );
 BOOST_PYTHON_FUNCTION_OVERLOADS( terminateProcess_,  pykd::terminateProcess, 0, 1 );
 BOOST_PYTHON_FUNCTION_OVERLOADS( attachKernel_,  pykd::attachKernel, 0, 1 );
 BOOST_PYTHON_FUNCTION_OVERLOADS( evaluate_, pykd::evaluate, 1, 2 );
+BOOST_PYTHON_FUNCTION_OVERLOADS( debugCommand_, pykd::debugCommand, 1, 2 );
 
 BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, pykd::dprint, 1, 2 );
 BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, pykd::dprintln, 1, 2 );
@@ -83,16 +84,22 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( Module_findSymbol, ModuleAdapter::findSymbol, 2
 BOOST_PYTHON_FUNCTION_OVERLOADS( TypeInfo_ptrTo, TypeInfoAdapter::ptrTo, 1, 2 ); 
 
 
-pykd::SysDbgOut   sysPykdOut;
-pykd::SysDbgOut   sysPykdErr;
-pykd::SysDbgIn    sysPykdIn;
-
 namespace pykd {
 
 void initialize()
 {
+    pykd::SysDbgOut  *sysPykdOut  =  new pykd::SysDbgOut();
+    pykd::SysDbgOut  *sysPykdErr  =  new pykd::SysDbgOut();
+    pykd::SysDbgIn   *sysPykdIn = new pykd::SysDbgIn();
+
     AutoRestorePyState  pystate;
+    
     kdlib::initialize();
+
+    // ������������ ������ ������� ������ �� sys
+    kdlib::dbgout = sysPykdOut;
+    kdlib::dbgerr = sysPykdErr;
+    kdlib::dbgin = sysPykdIn;
 }
 
 void remote_initialize( const std::wstring& remoteOptions )
@@ -110,11 +117,6 @@ void uninitialize()
 
 BOOST_PYTHON_MODULE( pykd )
 {
-    // ������������ ������ ������� ������ �� sys
-    kdlib::dbgout =&sysPykdOut;
-    kdlib::dbgerr = &sysPykdErr;
-    kdlib::dbgin = &sysPykdIn;
-
     python::scope().attr("__version__") = pykdVersion;
     python::scope().attr("version") = pykdVersion;
 
@@ -173,10 +175,10 @@ BOOST_PYTHON_MODULE( pykd )
 
     python::def( "breakin", pykd::targetBreak,
         "Break into debugger" );
-    python::def( "expr", pykd::evaluate, evaluate_( boost::python::args( "expression", "cplusplus" ),
+    python::def( "expr", pykd::evaluate, evaluate_( python::args( "expression", "cplusplus" ),
         "Evaluate windbg expression" ) );
-    python::def( "dbgCommand", pykd::debugCommand,
-        "Run a debugger's command and return it's result as a string" );
+    python::def( "dbgCommand", &pykd::debugCommand, 
+        debugCommand_( python::args( "command", "suppressOutput"), "Run a debugger's command and return it's result as a string" ) );
     python::def( "go", pykd::targetGo,
         "Go debugging"  );
     python::def( "step", pykd::targetStep,
@@ -898,7 +900,9 @@ BOOST_PYTHON_MODULE( pykd )
              "There is no return value" )
         .def( "onChangeLocalScope", &EventHandler::onChangeLocalScope,
             "The current local scope has been changed.\n"
-             "There is no return value" )
+            "There is no return value" )
+        .def( "onDebugOutput", &EventHandler::onDebugOutput,
+            "Request debug output" );
 
    //     .def( "onSymbolsLoaded", &EventHandlerWrap::onSymbolsLoaded,
    //         "Triggered debug symbols loaded. Parameter - module base or 0\n"
@@ -908,7 +912,6 @@ BOOST_PYTHON_MODULE( pykd )
    //         "There is no return value");
         ;
 
-
     python::class_<Breakpoint, boost::noncopyable>( "breakpoint",
         "class for CPU context representation", python::init<kdlib::MEMOFFSET_64>()) 
         .def( python::init<kdlib::MEMOFFSET_64, size_t, kdlib::ACCESS_TYPE>() )
diff --git a/pykd/pythreadstate.h b/pykd/pythreadstate.h
index c920777..9cc2233 100644
--- a/pykd/pythreadstate.h
+++ b/pykd/pythreadstate.h
@@ -30,4 +30,25 @@ private:
     PyThreadState*    m_state;
 };
 
+class AutoSavePythonState
+{
+public:
+
+    explicit AutoSavePythonState(PyThreadState **state) {
+        PyEval_RestoreThread(*state);
+        m_state = state;
+    }
+
+    ~AutoSavePythonState() {
+        *m_state = PyEval_SaveThread();
+
+    }
+
+private:
+
+    PyThreadState**    m_state;
+
+
+};
+
 }
\ No newline at end of file
diff --git a/pykd/windbgext.cpp b/pykd/windbgext.cpp
index 45d82d3..f895923 100644
--- a/pykd/windbgext.cpp
+++ b/pykd/windbgext.cpp
@@ -25,9 +25,9 @@ bool PykdExt::isInit() {
 
 extern "C" void initpykd();
 
-pykd::DbgOut   pykdOut;
-pykd::DbgOut   pykdErr;
-pykd::DbgIn    pykdIn;
+//pykd::DbgOut   pykdOut;
+//pykd::DbgOut   pykdErr;
+//pykd::DbgIn    pykdIn;
 
 
 void PykdExt::setUp() 
@@ -58,16 +58,16 @@ void PykdExt::setUp()
         main_namespace[ key ] = pykd_namespace[ key ];
     }
 
-    // ��������������� ����������� ������� ��
-    kdlib::dbgout =&pykdOut;
-    kdlib::dbgerr = &pykdErr;
-    kdlib::dbgin = &pykdIn;
+    //// ��������������� ����������� ������� ��
+    //kdlib::dbgout =&pykdOut;
+    //kdlib::dbgerr = &pykdErr;
+    //kdlib::dbgin = &pykdIn;
 
     python::object       sys = python::import("sys");
 
-    sys.attr("stdout") = python::object( &pykdOut );
-    sys.attr("stderr") = python::object( &pykdErr );
-    sys.attr("stdin") = python::object( &pykdIn );
+    sys.attr("stdout") = python::object( pykd::DbgOut() );
+    sys.attr("stderr") = python::object( pykd::DbgOut() );
+    sys.attr("stdin") = python::object( pykd::DbgIn() );
 
     python::list pathList(sys.attr("path"));