diff --git a/pykd/bpoint.cpp b/pykd/bpoint.cpp
new file mode 100644
index 0000000..06b1f93
--- /dev/null
+++ b/pykd/bpoint.cpp
@@ -0,0 +1,157 @@
+// 
+// Breakpoints management
+// 
+
+#include "stdafx.h"
+#include "bpoint.h"
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace pykd {
+
+static IDebugBreakpoint *setBreakPoint(
+    IDebugControl4 *control,
+    ULONG bpType,
+    ULONG64 addr
+)
+{
+    IDebugBreakpoint *bp;
+    HRESULT hres = control->AddBreakpoint(bpType, DEBUG_ANY_ID, &bp);
+    if (S_OK != hres)
+        throw DbgException("IDebugControl::AddBreakpoint", hres);
+
+    hres = bp->SetOffset(addr);
+    if (S_OK != hres)
+    {
+        control->RemoveBreakpoint(bp);
+        throw DbgException("IDebugBreakpoint::SetOffset", hres);
+    }
+
+    ULONG bpFlags;
+    hres = bp->GetFlags(&bpFlags);
+    if (S_OK != hres)
+    {
+        control->RemoveBreakpoint(bp);
+        throw DbgException("IDebugBreakpoint::GetFlags", hres);
+    }
+
+    bpFlags |= DEBUG_BREAKPOINT_ENABLED;
+    hres = bp->SetFlags(bpFlags);
+    if (S_OK != hres)
+    {
+        control->RemoveBreakpoint(bp);
+        throw DbgException("IDebugBreakpoint::SetFlags", hres);
+    }
+
+    return bp;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static ULONG getBpId(IDebugBreakpoint *bp, IDebugControl4 *control = NULL)
+{
+    ULONG Id;
+    HRESULT hres = bp->GetId(&Id);
+    if (S_OK != hres)
+    {
+        if (control)
+            control->RemoveBreakpoint(bp);
+        throw DbgException("IDebugBreakpoint::GetId", hres);
+    }
+    return Id;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+ULONG DebugClient::setSoftwareBp(ULONG64 addr)
+{
+    addr = addr64(addr);
+    IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_CODE, addr);
+
+    return getBpId(bp, m_control);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+ULONG DebugClient::setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType)
+{
+    addr = addr64(addr);
+    IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_DATA, addr);
+
+    HRESULT hres = bp->SetDataParameters(size, accessType);
+    if (S_OK != hres)
+    {
+        m_control->RemoveBreakpoint(bp);
+        throw DbgException("IDebugBreakpoint::SetDataParameters", hres);
+    }
+
+    return getBpId(bp, m_control);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+python::list DebugClient::getAllBp()
+{
+    ULONG numberOfBps;
+    HRESULT hres = m_control->GetNumberBreakpoints(&numberOfBps);
+    if (S_OK != hres)
+        throw DbgException("IDebugControl::GetNumberBreakpoints", hres);
+
+    python::list lstIds;
+
+    for (ULONG i =0; i < numberOfBps; ++i)
+    {
+        IDebugBreakpoint *bp;
+        hres = m_control->GetBreakpointByIndex(i, &bp);
+        if (S_OK != hres)
+            throw DbgException("IDebugControl::GetBreakpointByIndex", hres);
+        lstIds.append( getBpId(bp) );
+    }
+
+    return lstIds;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void DebugClient::removeBp(ULONG Id)
+{
+    IDebugBreakpoint *bp;
+    HRESULT hres = m_control->GetBreakpointById(Id, &bp);
+    if (S_OK != hres)
+        throw DbgException("IDebugControl::GetBreakpointById", hres);
+
+    hres = m_control->RemoveBreakpoint(bp);
+    if (S_OK != hres)
+        throw DbgException("IDebugControl::RemoveBreakpoint", hres);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void DebugClient::removeAllBp()
+{
+    ULONG numberOfBps;
+    do {
+        HRESULT hres = m_control->GetNumberBreakpoints(&numberOfBps);
+        if (S_OK != hres)
+            throw DbgException("IDebugControl::GetNumberBreakpoints", hres);
+        if (!numberOfBps)
+            break;
+
+        IDebugBreakpoint *bp;
+        hres = m_control->GetBreakpointByIndex(0, &bp);
+        if (S_OK != hres)
+            throw DbgException("IDebugControl::GetBreakpointByIndex", hres);
+
+        hres = m_control->RemoveBreakpoint(bp);
+        if (S_OK != hres)
+            throw DbgException("IDebugControl::RemoveBreakpoint", hres);
+
+    } while (numberOfBps);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+}   // namespace pykd
+
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/bpoint.h b/pykd/bpoint.h
new file mode 100644
index 0000000..c987a31
--- /dev/null
+++ b/pykd/bpoint.h
@@ -0,0 +1,46 @@
+// 
+// Breakpoints management
+// 
+
+#include "dbgclient.h"
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace pykd {
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline ULONG setSoftwareBp(ULONG64 addr) {
+    return g_dbgClient->setSoftwareBp(addr);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline ULONG setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType) {
+    return g_dbgClient->setHardwareBp(addr, size, accessType);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline python::list getAllBp() {
+    return g_dbgClient->getAllBp();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline void removeBp(ULONG Id) {
+    return g_dbgClient->removeBp(Id);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline void removeAllBp() {
+    return g_dbgClient->removeAllBp();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+}   // namespace pykd
+
+////////////////////////////////////////////////////////////////////////////////
+
diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h
index 9282556..3aacc80 100644
--- a/pykd/dbgclient.h
+++ b/pykd/dbgclient.h
@@ -297,6 +297,15 @@ public:
         return m_symSymbols;
     }
 
+    // breakpoints management
+    ULONG setSoftwareBp(ULONG64 addr);
+    ULONG setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType);
+
+    python::list getAllBp();
+
+    void removeBp(ULONG Id);
+    void removeAllBp();
+
 private:
     template<typename T>
     python::list
diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index e0ff237..5ba7123 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -18,6 +18,7 @@
 #include "dbgmem.h"
 #include "intbase.h"
 #include "process.h"
+#include "bpoint.h"
 #include "pykdver.h"
 
 using namespace pykd;
@@ -284,7 +285,7 @@ BOOST_PYTHON_MODULE( pykd )
         .def( "step", &DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>, 
             "Change debugger status to DEBUG_STATUS_STEP_OVER" )
         .def( "symbolsPath", &DebugClient::dbgSymPath, 
-            "Return symbol path" )   
+            "Return symbol path" )
         .def( "trace", &DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>, 
             "Change debugger status to DEBUG_STATUS_STEP_INTO" )
         .def( "waitForEvent", &DebugClient::waitForEvent,
@@ -299,6 +300,16 @@ BOOST_PYTHON_MODULE( pykd )
             "Get context of current thread (register values)" )
         .def( "getLocals", &DebugClient::getLocals, DebugClient_getLocals( python::args( "ctx" ),
             "Get list of local variables" ) )
+        .def( "setBp", &DebugClient::setSoftwareBp,
+            "Set software breakpoint on executiont" )
+        .def( "setBp", &DebugClient::setHardwareBp,
+            "Set hardware breakpoint" )
+        .def( "getAllBp", &DebugClient::getAllBp,
+            "Get all breapoint IDs" )
+        .def( "removeBp", &DebugClient::removeBp,
+            "Remove breapoint by IDs" )
+        .def( "removeBp", &DebugClient::removeAllBp,
+            "Remove all breapoints" )
         .def( "addSynSymbol", &DebugClient::addSyntheticSymbol,
             "Add new synthetic symbol for virtual address" )
         .def( "delAllSynSymbols", &DebugClient::delAllSyntheticSymbols, 
@@ -473,7 +484,17 @@ BOOST_PYTHON_MODULE( pykd )
     python::def( "getContext", &getThreadContext,
         "Get context of current thread (register values)" );
     python::def( "getLocals", &getLocals, getLocals_( python::args( "ctx" ),
-            "Get list of local variables" ) );
+        "Get list of local variables" ) );
+    python::def( "setBp", &setSoftwareBp,
+        "Set software breakpoint on executiont" );
+    python::def( "setBp", &setHardwareBp,
+        "Set hardware breakpoint" );
+    python::def( "getAllBp", &getAllBp,
+        "Get all breapoint IDs" );
+    python::def( "removeBp", &removeBp,
+        "Remove breapoint by IDs" );
+    python::def( "removeBp", &removeAllBp,
+        "Remove all breapoints" );
 
     python::class_<TypeInfo, TypeInfoPtr, python::bases<intBase>, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
         .def( "name", &TypeInfo::getName )
@@ -872,6 +893,15 @@ BOOST_PYTHON_MODULE( pykd )
     DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_BRANCH);
     DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_OVER);
     DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_INTO);
+
+    // breakpoints constatns
+    DEF_PY_CONST_ULONG(DEBUG_BREAKPOINT_CODE);
+    DEF_PY_CONST_ULONG(DEBUG_BREAKPOINT_DATA);
+
+    DEF_PY_CONST_ULONG(DEBUG_BREAK_READ);
+    DEF_PY_CONST_ULONG(DEBUG_BREAK_WRITE);
+    DEF_PY_CONST_ULONG(DEBUG_BREAK_EXECUTE);
+    DEF_PY_CONST_ULONG(DEBUG_BREAK_IO);
 }
 
 #undef DEF_PY_CONST_ULONG
diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj
index 9ae61f6..86fddea 100644
--- a/pykd/pykd_2008.vcproj
+++ b/pykd/pykd_2008.vcproj
@@ -349,6 +349,10 @@
 			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			>
+			<File
+				RelativePath=".\bpoint.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\context.cpp"
 				>
@@ -483,6 +487,10 @@
 			Filter="h;hpp;hxx;hm;inl;inc;xsd"
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
+			<File
+				RelativePath=".\bpoint.h"
+				>
+			</File>
 			<File
 				RelativePath=".\context.h"
 				>
diff --git a/test/scripts/ehexcepttest.py b/test/scripts/ehexcepttest.py
index 8d8cb52..fc9af07 100644
--- a/test/scripts/ehexcepttest.py
+++ b/test/scripts/ehexcepttest.py
@@ -14,6 +14,7 @@ class BreakExceptionHandler(pykd.eventHandler):
         self.wasSecondChance = False
 
         self.wasBreakpoint = False
+        self.wasBreakpointIds = []
 
         self.bpLastModuleName = ""
         self.bpCount = 0
@@ -24,6 +25,7 @@ class BreakExceptionHandler(pykd.eventHandler):
     def onBreakpoint(self, bpId):
         """Breakpoint handler"""
         self.wasBreakpoint = True
+        self.wasBreakpointIds.append( bpId )
         return pykd.DEBUG_STATUS_NO_CHANGE
 
     def onException(self, exceptParams):
@@ -33,7 +35,6 @@ class BreakExceptionHandler(pykd.eventHandler):
 
         if exceptParams["Code"] == pykd.EXCEPTION_ACCESS_VIOLATION:
             if self.wasSecondChance:
-                print exceptParams["Parameters"]
                 self.secondChanceAccessAddresses.append( exceptParams["Parameters"][1] )
             else:
                 self.firstChanceAccessAddresses.append( exceptParams["Parameters"][1] )
@@ -50,7 +51,23 @@ class EhExceptionBreakpointTest(unittest.TestCase):
         testClient = pykd.createDbgClient()
         testClient.startProcess( target.appPath + " -testExceptions" )
 
-        testClient.dbgCommand( ".reload /f; bp targetapp!doExeptions" )
+        targetMod = testClient.loadModule( "targetapp" )
+
+        bpIdSoftware = testClient.setBp( targetMod.offset("changeValueForAccessTesting") )
+
+        bpIdHwExecute = testClient.setBp( targetMod.offset("readValueForAccessTesting"),
+                                          1,
+                                          pykd.DEBUG_BREAK_EXECUTE )
+
+        bpIdHwWrite = testClient.setBp( targetMod.offset("g_valueForAccessTesting1"),
+                                        1,
+                                        pykd.DEBUG_BREAK_WRITE )
+
+        bpIdHwRead = testClient.setBp( targetMod.offset("g_valueForAccessTesting2"),
+                                       1,
+                                       pykd.DEBUG_BREAK_READ )
+
+        self.assertEqual( 4, len( testClient.getAllBp() ) )
 
         breakExceptionHandler = BreakExceptionHandler( testClient )
         while not breakExceptionHandler.wasSecondChance:
@@ -63,3 +80,11 @@ class EhExceptionBreakpointTest(unittest.TestCase):
         self.assertEqual( 2, breakExceptionHandler.bpCount ) # main and doExeptions
 
         self.assertEqual( [3, ], breakExceptionHandler.secondChanceAccessAddresses )
+
+        self.assertTrue( bpIdSoftware in breakExceptionHandler.wasBreakpointIds )
+
+        testClient.removeBp(bpIdHwRead)
+        self.assertEqual( 3, len( testClient.getAllBp() ) )
+
+        testClient.removeBp()
+        self.assertEqual( 0, len( testClient.getAllBp() ) )
diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp
index d7b76ba..04e7721 100644
--- a/test/targetapp/targetapp.cpp
+++ b/test/targetapp/targetapp.cpp
@@ -343,10 +343,34 @@ int doLoadUnload()
 
     return 0;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+
+int g_valueForAccessTesting1 = 4;
+int g_valueForAccessTesting2 = 5;
+
+////////////////////////////////////////////////////////////////////////////////
+#pragma optimize("g", off)
+void changeValueForAccessTesting()
+{
+    g_valueForAccessTesting1 = 5;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void readValueForAccessTesting()
+{
+    std::cout << g_valueForAccessTesting1 << g_valueForAccessTesting2;
+}
+#pragma optimize("g", on)
 ////////////////////////////////////////////////////////////////////////////////
 
 int doExeptions()
 {
+    changeValueForAccessTesting();
+
+    readValueForAccessTesting();
+
     __debugbreak();
 
     PUCHAR _ptr = reinterpret_cast<UCHAR *>(2);