diff --git a/pykd-0.3-2010.sln b/pykd-0.3-2010.sln
index 20343a9..da00dc8 100644
--- a/pykd-0.3-2010.sln
+++ b/pykd-0.3-2010.sln
@@ -30,6 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{FE24
 		test\scripts\mspdbtest.py = test\scripts\mspdbtest.py
 		test\scripts\pykdtest.py = test\scripts\pykdtest.py
 		test\scripts\regtest.py = test\scripts\regtest.py
+		test\scripts\stacktest.py = test\scripts\stacktest.py
 		test\scripts\synsymtest.py = test\scripts\synsymtest.py
 		test\scripts\target.py = test\scripts\target.py
 		test\scripts\testutils.py = test\scripts\testutils.py
diff --git a/pykd/cpucontext.cpp b/pykd/cpucontext.cpp
index b1f80a8..6185c35 100644
--- a/pykd/cpucontext.cpp
+++ b/pykd/cpucontext.cpp
@@ -8,52 +8,47 @@ namespace pykd {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-python::object CPUContextAdaptor::getRegisterByName( kdlib::CPUContext& cpu, const std::wstring &name )
+python::object CPUContextAdaptor::getRegisterByName( kdlib::CPUContextPtr& cpu, const std::wstring &name )
 {
-    kdlib::NumVariant var = cpu.getRegisterByName(name);
+    kdlib::NumVariant var = cpu->getRegisterByName(name);
     return NumVariantAdaptor::convertToPython( var );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-python::object CPUContextAdaptor::getRegisterByIndex( kdlib::CPUContext& cpu, unsigned long  index )
+python::object CPUContextAdaptor::getRegisterByIndex( kdlib::CPUContextPtr& cpu, unsigned long  index )
 {
-    kdlib::NumVariant var = cpu.getRegisterByIndex(index);
-    std::wstring name = cpu.getRegisterName(index);
+    kdlib::NumVariant var = cpu->getRegisterByIndex(index);
+    std::wstring name = cpu->getRegisterName(index);
 
     return python::make_tuple( name, NumVariantAdaptor::convertToPython( var ) );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-python::list  CPUContextAdaptor::getStack( kdlib::CPUContext& cpu )
+python::list  CPUContextAdaptor::getStack( kdlib::CPUContextPtr& cpu )
 {
-    unsigned long  numberFrames = cpu.getStackLength();
-    python::list  lst;
+    kdlib::StackPtr  stack = kdlib::getStack(cpu);
 
-    python::object  typeObj = python::object( python::handle<>(&PyType_Type) );
-    python::object  frameType = typeObj("frameType", python::tuple(), python::dict() );
+    unsigned long  numberFrames = stack->getFrameCount();
+     python::list  lst;
 
     for ( unsigned long  i = 0; i < numberFrames; ++i )
-    {
-        StackFrame   frame;
-        cpu.getStackFrame( i, frame.ip, frame.ret, frame.fp, frame.sp );
-        lst.append( frame );
-    }
+        lst.append( stack->getFrame(i) );
 
     return lst;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-std::wstring printStackFrame( StackFrame& frame )
+std::wstring printStackFrame( kdlib::StackFramePtr& frame )
 {
     std::wstringstream sstr;
     sstr << L"Frame: ";
-    sstr << L"IP=" << std::hex << frame.ip << L"  ";
-    sstr << L"Return=" << std::hex << frame.ret << L"  ";
-    sstr << L"Frame Offset=" << std::hex << frame.fp << L"  ";
-    sstr << L"Stack Offset=" << std::hex << frame.sp;
+    sstr << L"IP=" << std::hex << frame->getIP() << L"  ";
+    sstr << L"Return=" << std::hex << frame->getRET() << L"  ";
+    sstr << L"Frame Offset=" << std::hex << frame->getFP() << L"  ";
+    sstr << L"Stack Offset=" << std::hex << frame->getSP();
 
     return sstr.str();
 }
diff --git a/pykd/cpucontext.h b/pykd/cpucontext.h
index 716194c..8bf54e9 100644
--- a/pykd/cpucontext.h
+++ b/pykd/cpucontext.h
@@ -5,6 +5,7 @@ namespace python = boost::python;
 
 #include "kdlib/dbgengine.h"
 #include "kdlib/cpucontext.h"
+#include "kdlib/stack.h"
 
 namespace pykd {
 
@@ -13,20 +14,20 @@ namespace pykd {
 class CPUContextAdaptor
 {
 public:
-    static python::object getRegisterByName( kdlib::CPUContext& cpu, const std::wstring &name );
-    static python::object getRegisterByIndex( kdlib::CPUContext& cpu, unsigned long index );
-    static python::list getStack( kdlib::CPUContext& cpu );
+    static python::object getRegisterByName( kdlib::CPUContextPtr& cpu, const std::wstring &name );
+    static python::object getRegisterByIndex( kdlib::CPUContextPtr& cpu, unsigned long index );
+    static python::list getStack( kdlib::CPUContextPtr& cpu );
 };
 
-struct StackFrame {
-    kdlib::MEMOFFSET_64 ip, ret, fp, sp;
-};
+//struct StackFrame {
+//    kdlib::MEMOFFSET_64 ip, ret, fp, sp;
+//};
 
-std::wstring printStackFrame( StackFrame& frame );
+std::wstring printStackFrame( kdlib::StackFramePtr& frame );
 
 inline python::object getRegisterByName( const std::wstring &name )
 {
-    return CPUContextAdaptor::getRegisterByName( *kdlib::loadCPUCurrentContext().get(), name );
+    return CPUContextAdaptor::getRegisterByName( kdlib::loadCPUCurrentContext(), name );
 }
 
 inline unsigned long long loadMSR( unsigned long  msrIndex ) 
@@ -56,9 +57,12 @@ inline void switchProcessorMode() {
 }
 
 inline python::list getCurrentStack() {
-    return CPUContextAdaptor::getStack( *kdlib::loadCPUCurrentContext() );
+    return CPUContextAdaptor::getStack( kdlib::loadCPUCurrentContext() );
 }
 
+inline kdlib::StackFramePtr getCurrentFrame() {
+    return kdlib::getStack()->getFrame(0);
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/pykd/dbgengine.cpp b/pykd/dbgengine.cpp
index ca61c12..de5dff0 100644
--- a/pykd/dbgengine.cpp
+++ b/pykd/dbgengine.cpp
@@ -160,7 +160,8 @@ python::tuple findSymbolAndDisp( ULONG64 offset )
 {
     kdlib::MEMDISPLACEMENT  displacement = 0;
     std::wstring  symbolName = kdlib::findSymbol( offset, displacement );
-    return python::make_tuple(symbolName,displacement);
+    std::wstring  moduleName = kdlib::getModuleName( kdlib::findModuleBase( offset ) );
+    return python::make_tuple(moduleName,symbolName,displacement);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp
index 81213f6..684ff31 100644
--- a/pykd/pymod.cpp
+++ b/pykd/pymod.cpp
@@ -277,6 +277,10 @@ BOOST_PYTHON_MODULE( pykd )
    // stack and local variables
     python::def( "getStack", &getCurrentStack,
         "Return a current stack as a list of stackFrame objects" );
+    python::def( "getFrame", &getCurrentFrame,
+        "Return a current stack frame" );
+
+
    // python::def( "getStackWow64", &getCurrentStackWow64,
    //     "Return a stack for wow64 context as a list of stackFrame objects" );
    // python::def( "getFrame", &getCurrentStackFrame,
@@ -555,12 +559,12 @@ BOOST_PYTHON_MODULE( pykd )
         .def("__init__", python::make_constructor(Breakpoint::setSoftwareBreakpoint) )
         ;
 
-    python::class_<StackFrame>( "stackFrame",
+    python::class_<kdlib::StackFrame, kdlib::StackFramePtr, boost::noncopyable>( "stackFrame",
         "class for stack's frame representation", python::no_init  )
-        .def_readonly( "ip", &StackFrame::ip, "instruction pointer" )
-        .def_readonly( "ret", &StackFrame::ret, "return pointer" )
-        .def_readonly( "fp", &StackFrame::fp, "frame pointer" )
-        .def_readonly( "sp", &StackFrame::sp, "stack pointer" )
+        .def_readonly( "ip", &kdlib::StackFrame::getIP, "instruction pointer" )
+        .def_readonly( "ret", &kdlib::StackFrame::getRET, "return pointer" )
+        .def_readonly( "fp", &kdlib::StackFrame::getFP, "frame pointer" )
+        .def_readonly( "sp", &kdlib::StackFrame::getSP, "stack pointer" )
         .def( "__str__", &printStackFrame );
 
     python::class_<kdlib::CPUContext, kdlib::CPUContextPtr, boost::noncopyable>( "cpu",