diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index 469ea3460112218d7cec8eb0cfa7b2f5d836494b..b2498747161805a6bdfeb3e16ec79486cdd25d93 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -83,3 +83,14 @@ SOURCES += $$PWD/modeltest.cpp
 HEADERS += $$PWD/modeltest.h
 DEFINES += USE_MODEL_TEST=1
 }
+
+false {
+    HEADERS += msvcdebugengine.h \
+               msvcdebugeventcallback.h \
+               msvcdebugoutput.h
+    SOURCES += msvcdebugengine.cpp \
+               msvcdebugeventcallback.cpp \
+               msvcdebugoutput.cpp
+    LIBS += dbgeng.lib
+}
+
diff --git a/src/plugins/debugger/msvcdebugengine.cpp b/src/plugins/debugger/msvcdebugengine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e2216644405a76dfc0b43aab66b33c4ce0896333
--- /dev/null
+++ b/src/plugins/debugger/msvcdebugengine.cpp
@@ -0,0 +1,519 @@
+#include "msvcdebugengine.h"
+
+#include "assert.h"
+#include "debuggermanager.h"
+#include "breakhandler.h"
+#include "stackhandler.h"
+
+#include <QDebug>
+#include <QTimerEvent>
+#include <QFileInfo>
+
+#define DBGHELP_TRANSLATE_TCHAR
+#include <Dbghelp.h>
+
+using namespace Debugger;
+using namespace Debugger::Internal;
+
+
+MSVCDebugEngine::MSVCDebugEngine(DebuggerManager *parent)
+:   IDebuggerEngine(parent),
+    m_hDebuggeeProcess(0),
+    m_hDebuggeeThread(0),
+    //m_hDebuggeeImage(0),
+    m_bIgnoreNextDebugEvent(false),
+    m_watchTimer(-1),
+    m_debugEventCallBack(this),
+    m_debugOutputCallBack(this)
+{
+    q = parent;
+    qq = parent->engineInterface();
+
+    HRESULT hr;
+    hr = DebugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient));
+    if (FAILED(hr)) m_pDebugClient = 0;
+    hr = DebugCreate( __uuidof(IDebugControl4), reinterpret_cast<void**>(&m_pDebugControl));
+    if (FAILED(hr)) m_pDebugControl = 0;
+    hr = DebugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_pDebugSystemObjects));
+    if (FAILED(hr)) m_pDebugSystemObjects = 0;
+    hr = DebugCreate( __uuidof(IDebugSymbols3), reinterpret_cast<void**>(&m_pDebugSymbols));
+    if (FAILED(hr)) m_pDebugSymbols = 0;
+    hr = DebugCreate( __uuidof(IDebugRegisters2), reinterpret_cast<void**>(&m_pDebugRegisters));
+    if (FAILED(hr)) m_pDebugRegisters = 0;
+
+    if (m_pDebugControl) {
+        m_pDebugControl->SetCodeLevel(DEBUG_LEVEL_SOURCE);
+    }
+    if (m_pDebugClient) {
+        m_pDebugClient->SetOutputCallbacks(&m_debugOutputCallBack);
+        m_pDebugClient->SetEventCallbacks(&m_debugEventCallBack);
+    }
+}
+
+MSVCDebugEngine::~MSVCDebugEngine()
+{
+    if (m_pDebugClient)
+        m_pDebugClient->Release();
+    if (m_pDebugControl)
+        m_pDebugControl->Release();
+    if (m_pDebugSystemObjects)
+        m_pDebugSystemObjects->Release();
+    if (m_pDebugSymbols)
+        m_pDebugSymbols->Release();
+    if (m_pDebugRegisters)
+        m_pDebugRegisters->Release();
+}
+
+void MSVCDebugEngine::startWatchTimer()
+{
+    if (m_watchTimer == -1)
+        m_watchTimer = startTimer(0);
+}
+
+void MSVCDebugEngine::killWatchTimer()
+{
+    if (m_watchTimer != -1) {
+        killTimer(m_watchTimer);
+        m_watchTimer = -1;
+    }
+}
+
+void MSVCDebugEngine::shutdown()
+{
+    exitDebugger();
+}
+
+void MSVCDebugEngine::setToolTipExpression(const QPoint &pos, const QString &exp)
+{
+}
+
+bool MSVCDebugEngine::startDebugger()
+{
+    q->showStatusMessage("Starting Debugger", -1);
+
+    //if (!q->m_workingDir.isEmpty())
+    //    m_gdbProc.setWorkingDirectory(q->m_workingDir);
+    //if (!q->m_environment.isEmpty())
+    //    m_gdbProc.setEnvironment(q->m_environment);
+
+    DEBUG_CREATE_PROCESS_OPTIONS dbgopts;
+    memset(&dbgopts, 0, sizeof(dbgopts));
+    dbgopts.CreateFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
+
+    HRESULT hr;
+
+    QString filename(q->m_executable);
+    QFileInfo fi(filename);
+    m_pDebugSymbols->AppendImagePathWide(fi.absolutePath().replace('/','\\').utf16());
+    //m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
+    m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
+    //m_pDebugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH);
+
+    if (q->startMode() == q->attachExternal) {
+        qWarning("MSVCDebugEngine: attach to process not yet implemented!");
+    } else {
+        hr = m_pDebugClient->CreateProcess2Wide(NULL,
+                                                const_cast<PWSTR>(filename.utf16()),
+                                                &dbgopts,
+                                                sizeof(dbgopts),
+                                                NULL,  // TODO: think about the initial directory
+                                                NULL); // TODO: think about setting the environment
+        if (FAILED(hr)) {
+            //qWarning("CreateProcess2Wide failed");
+            qq->notifyInferiorExited();
+            return false;
+        }
+    }
+
+    q->showStatusMessage(tr("Debugger Running"), -1);
+    startWatchTimer();
+    return true;
+}
+
+void MSVCDebugEngine::exitDebugger()
+{
+    m_pDebugClient->TerminateCurrentProcess();
+    killWatchTimer();
+}
+
+void MSVCDebugEngine::updateWatchModel()
+{
+}
+
+void MSVCDebugEngine::stepExec()
+{
+    //qDebug() << "MSVCDebugEngine::stepExec()";
+    //m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
+    HRESULT hr;
+    hr = m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
+    m_bIgnoreNextDebugEvent = true;
+    startWatchTimer();
+}
+
+void MSVCDebugEngine::stepOutExec()
+{
+    //qDebug() << "MSVCDebugEngine::stepOutExec()";
+    StackHandler* sh = qq->stackHandler();
+    const int idx = sh->currentIndex() + 1;
+    QList<StackFrame> stackframes = sh->frames();
+    if (idx < 0 || idx >= stackframes.size()) {
+        qWarning("cannot step out");
+        return;
+    }
+
+    const StackFrame& frame = stackframes.at(idx);
+    bool ok;
+    ULONG64 address = frame.address.toULongLong(&ok, 16);
+    if (!ok) {
+        qWarning("stepOutExec: cannot obtain address from stack frame");
+        return;
+    }
+
+    IDebugBreakpoint2* pBP;
+    HRESULT hr = m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
+    if (FAILED(hr) || !pBP) {
+        qWarning("stepOutExec: cannot create temporary breakpoint");
+        return;
+    }
+
+    pBP->SetOffset(address);
+
+    //QString str = '`' + frame.file + ':' + frame.line + '`';
+    //hr = pBP->SetOffsetExpressionWide(str.utf16());
+    //if (FAILED(hr)) {
+    //    qWarning("SetOffsetExpressionWide failed");
+    //    return;
+    //}
+
+    pBP->AddFlags(DEBUG_BREAKPOINT_ENABLED);
+    pBP->AddFlags(DEBUG_BREAKPOINT_ONE_SHOT);
+    //hr = m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
+    continueInferior();
+}
+
+void MSVCDebugEngine::nextExec()
+{
+    //qDebug() << "MSVCDebugEngine::nextExec()";
+    HRESULT hr;
+    hr = m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
+    startWatchTimer();
+}
+
+void MSVCDebugEngine::stepIExec()
+{
+    qWarning("MSVCDebugEngine::stepIExec() not implemented");
+}
+
+void MSVCDebugEngine::nextIExec()
+{
+    m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
+    startWatchTimer();
+}
+
+void MSVCDebugEngine::continueInferior()
+{
+    killWatchTimer();
+    q->resetLocation();
+
+    ULONG executionStatus;
+    HRESULT hr = m_pDebugControl->GetExecutionStatus(&executionStatus);
+    if (SUCCEEDED(hr) && executionStatus != DEBUG_STATUS_GO)
+        m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
+
+    startWatchTimer();
+    qq->notifyInferiorRunning();
+}
+
+void MSVCDebugEngine::runInferior()
+{
+    continueInferior();
+}
+
+void MSVCDebugEngine::interruptInferior()
+{
+    //TODO: better use IDebugControl::SetInterrupt?
+    if (!m_hDebuggeeProcess)
+        return;
+    if (!DebugBreakProcess(m_hDebuggeeProcess)) {
+        qWarning("DebugBreakProcess failed.");
+        return;
+    }
+    qq->notifyInferiorStopped();
+}
+
+void MSVCDebugEngine::runToLineExec(const QString &fileName, int lineNumber)
+{
+}
+
+void MSVCDebugEngine::runToFunctionExec(const QString &functionName)
+{
+}
+
+void MSVCDebugEngine::jumpToLineExec(const QString &fileName, int lineNumber)
+{
+}
+
+void MSVCDebugEngine::assignValueInDebugger(const QString &expr, const QString &value)
+{
+}
+
+void MSVCDebugEngine::executeDebuggerCommand(const QString &/*command*/)
+{
+}
+
+void MSVCDebugEngine::activateFrame(int frameIndex)
+{
+    if (q->status() != DebuggerInferiorStopped)
+        return;
+
+    StackHandler *stackHandler = qq->stackHandler();
+    int oldIndex = stackHandler->currentIndex();
+    //qDebug() << "ACTIVATE FRAME: " << frameIndex << oldIndex
+    //    << stackHandler->currentIndex();
+
+    QWB_ASSERT(frameIndex < stackHandler->stackSize(), return);
+
+    if (oldIndex != frameIndex) {
+        stackHandler->setCurrentIndex(frameIndex);
+        //updateLocals();
+    }
+
+    const StackFrame &frame = stackHandler->currentFrame();
+
+    bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
+    if (usable)
+        q->gotoLocation(frame.file, frame.line, true);
+    else
+        qDebug() << "FULL NAME NOT USABLE: " << frame.file;
+}
+
+void MSVCDebugEngine::selectThread(int index)
+{
+    //reset location arrow
+    q->resetLocation();
+
+    ThreadsHandler *threadsHandler = qq->threadsHandler();
+    threadsHandler->setCurrentThread(index);
+    m_currentThreadId = index;
+    updateStackTrace();
+}
+
+void MSVCDebugEngine::attemptBreakpointSynchronization()
+{
+    BreakHandler *handler = qq->breakHandler();
+    //qDebug() << "attemptBreakpointSynchronization";
+    for (int i=0; i < handler->size(); ++i) {
+        BreakpointData* breakpoint = handler->at(i);
+        if (breakpoint->pending) {
+            IDebugBreakpoint2* pBP = 0;
+            HRESULT hr = m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
+            if (FAILED(hr) || !pBP) {
+                qWarning("m_pDebugControl->AddBreakpoint2 failed");
+                continue;
+            }
+
+            QString str = '`' + breakpoint->fileName + ':' + breakpoint->lineNumber + '`';
+            hr = pBP->SetOffsetExpressionWide(str.utf16());
+            if (FAILED(hr)) {
+                qWarning("SetOffsetExpressionWide failed");
+                continue;
+            }
+
+            bool ok;
+            ULONG ul;
+            ul = breakpoint->ignoreCount.toULong(&ok);
+            if (ok) pBP->SetPassCount(ul);
+
+            //TODO: handle breakpoint->condition
+
+            pBP->AddFlags(DEBUG_BREAKPOINT_ENABLED);
+            //pBP->AddFlags(DEBUG_BREAKPOINT_GO_ONLY);
+            breakpoint->pending = false;
+        }
+    }
+}
+
+void MSVCDebugEngine::loadSessionData()
+{
+}
+
+void MSVCDebugEngine::saveSessionData()
+{
+}
+
+void MSVCDebugEngine::reloadDisassembler()
+{
+}
+
+void MSVCDebugEngine::reloadModules()
+{
+}
+
+void MSVCDebugEngine::loadSymbols(const QString &moduleName)
+{
+}
+
+void MSVCDebugEngine::loadAllSymbols()
+{
+}
+
+void MSVCDebugEngine::reloadRegisters()
+{
+}
+
+void MSVCDebugEngine::timerEvent(QTimerEvent* te)
+{
+    if (te->timerId() != m_watchTimer)
+        return;
+
+    HRESULT hr;
+    hr = m_pDebugControl->WaitForEvent(0, 1);
+    switch (hr) {
+        case S_OK:
+            //qDebug() << "WaitForEvent S_OK";
+            killWatchTimer();
+            handleDebugEvent();
+            break;
+        case S_FALSE:
+            //qDebug() << "S_FALSE";
+            break;
+        case E_PENDING:
+            qDebug() << "S_PENDING";
+            break;
+        case E_UNEXPECTED:
+            killWatchTimer();
+            break;
+        case E_FAIL:
+            qDebug() << "E_FAIL";
+            break;
+        //default:
+        //    qDebug() << "asser welljuh, schuddnt heppn";
+    }
+}
+
+void MSVCDebugEngine::handleDebugEvent()
+{
+    if (m_bIgnoreNextDebugEvent) {
+        startWatchTimer();
+        m_bIgnoreNextDebugEvent = false;
+    } else {
+        qq->notifyInferiorStopped();
+        updateThreadList();
+        updateStackTrace();
+    }
+
+    //ULONG executionStatus;
+    //HRESULT hr = m_pDebugControl->GetExecutionStatus(&executionStatus);
+    //if (SUCCEEDED(hr) && executionStatus == DEBUG_STATUS_STEP_INTO) {
+    //    // check if stack trace is valid
+    //    StackHandler* sh = qq->stackHandler();
+    //    QList<StackFrame> frames = sh->frames();
+    //    if (frames.size() > 0 && frames.first().file.isEmpty()) {
+    //        stepExec();
+    //    }
+    //}
+}
+
+void MSVCDebugEngine::updateThreadList()
+{
+    ThreadsHandler* th = qq->threadsHandler();
+    QList<ThreadData> threads;
+
+    HRESULT hr;
+    ULONG numberOfThreads;
+    hr = m_pDebugSystemObjects->GetNumberThreads(&numberOfThreads);
+    const ULONG maxThreadIds = 256;
+    ULONG threadIds[maxThreadIds];
+    ULONG biggestThreadId = qMin(maxThreadIds, numberOfThreads - 1);
+    hr = m_pDebugSystemObjects->GetThreadIdsByIndex(0, biggestThreadId, threadIds, 0);
+    for (ULONG threadId = 0; threadId <= biggestThreadId; ++threadId) {
+        ThreadData thread;
+        thread.id = threadId;
+        threads.append(thread);
+    }
+
+    th->setThreads(threads);
+}
+
+void MSVCDebugEngine::updateStackTrace()
+{
+    //qDebug() << "updateStackTrace()";
+    HRESULT hr;
+    hr = m_pDebugSystemObjects->SetCurrentThreadId(m_currentThreadId);
+
+    //ULONG64 frameOffset, instructionOffset, stackOffset;
+    //if (FAILED(m_pDebugRegisters->GetFrameOffset2(DEBUG_REGSRC_DEBUGGEE, &frameOffset)) ||
+    //    FAILED(m_pDebugRegisters->GetInstructionOffset2(DEBUG_REGSRC_DEBUGGEE, &instructionOffset)) ||
+    //    FAILED(m_pDebugRegisters->GetStackOffset2(DEBUG_REGSRC_DEBUGGEE, &stackOffset)))
+    //{
+    //    frameOffset = instructionOffset = stackOffset = 0;
+    //}
+    //frameOffset = instructionOffset = stackOffset = 0;
+
+    const ULONG numFrames = 100;
+    ULONG numFramesFilled = 0;
+    DEBUG_STACK_FRAME frames[numFrames];
+    //hr = m_pDebugControl->GetStackTrace(frameOffset, stackOffset, instructionOffset, frames, numFrames, &numFramesFilled);
+    hr = m_pDebugControl->GetStackTrace(0, 0, 0, frames, numFrames, &numFramesFilled);
+    if (FAILED(hr))
+        qDebug() << "GetStackTrace failed";
+
+    QList<StackFrame> stackFrames;
+
+    WCHAR wszBuf[MAX_PATH];
+    for (ULONG i=0; i < numFramesFilled; ++i) {
+        StackFrame frame;
+        frame.line = 0;
+        frame.level = i;
+        frame.address = QString("0x%1").arg(frames[i].InstructionOffset, 0, 16);
+
+        m_pDebugSymbols->GetNameByOffsetWide(frames[i].InstructionOffset, wszBuf, MAX_PATH, 0, 0);
+        frame.function = QString::fromUtf16(wszBuf);
+
+        ULONG ulLine;
+        ULONG ulFileNameSize;
+        ULONG64 ul64Displacement;
+        hr = m_pDebugSymbols->GetLineByOffsetWide(frames[i].InstructionOffset, &ulLine, wszBuf, MAX_PATH, &ulFileNameSize, &ul64Displacement);
+        if (SUCCEEDED(hr)) {
+            frame.line = ulLine;
+            frame.file = QString::fromUtf16(wszBuf, ulFileNameSize);
+        }
+        stackFrames.append(frame);
+    }
+
+    qq->stackHandler()->setFrames(stackFrames);
+
+    // find the first usable frame and select it
+    for (int i=0; i < stackFrames.count(); ++i) {
+        const StackFrame &frame = stackFrames.at(i);
+        bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
+        if (usable) {
+            qq->stackHandler()->setCurrentIndex(i);
+            q->gotoLocation(frame.file, frame.line, true);
+            break;
+        }
+    }
+
+    //m_pDebugSymbols->GetImagePathWide(wszBuf, buflen, 0);
+    //qDebug() << "ImagePath" << QString::fromUtf16(wszBuf);
+    //m_pDebugSymbols->GetSymbolPathWide(wszBuf, buflen, 0);
+    //qDebug() << "SymbolPath" << QString::fromUtf16(wszBuf);
+
+    //m_pDebugControl->OutputStackTrace(DEBUG_OUTCTL_THIS_CLIENT, 0, 2, DEBUG_STACK_FRAME_ADDRESSES | DEBUG_STACK_COLUMN_NAMES | DEBUG_STACK_FRAME_NUMBERS);
+    //m_pDebugControl->OutputStackTrace(DEBUG_OUTCTL_THIS_CLIENT, frames, numFramesFilled, DEBUG_STACK_SOURCE_LINE);
+}
+
+void MSVCDebugEngine::handleDebugOutput(const char* szOutputString)
+{
+    qq->showApplicationOutput("app-dbgoutput", QString::fromLocal8Bit(szOutputString));
+}
+
+void MSVCDebugEngine::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP)
+{
+    qDebug() << "MSVCDebugEngine::handleBreakpointEvent()";
+}
+
+IDebuggerEngine *createWinEngine(DebuggerManager *parent)
+{
+    return new MSVCDebugEngine(parent);
+}
diff --git a/src/plugins/debugger/msvcdebugengine.h b/src/plugins/debugger/msvcdebugengine.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a358e30462ff8a30f4440503be3dcb0ae7067da
--- /dev/null
+++ b/src/plugins/debugger/msvcdebugengine.h
@@ -0,0 +1,98 @@
+#ifndef __MSVCDEBUGENGINE_H__
+#define __MSVCDEBUGENGINE_H__
+
+#include "idebuggerengine.h"
+#include "msvcdebugeventcallback.h"
+#include "msvcdebugoutput.h"
+#include <windows.h>
+
+namespace Debugger {
+namespace Internal {
+
+class DebuggerManager;
+class IDebuggerManagerAccessForEngines;
+
+class MSVCDebugEngine : public IDebuggerEngine
+{
+    Q_OBJECT
+public:
+    MSVCDebugEngine(DebuggerManager *parent);
+    ~MSVCDebugEngine();
+
+    virtual void shutdown();
+    virtual void setToolTipExpression(const QPoint &pos, const QString &exp);
+    virtual bool startDebugger();
+    virtual void exitDebugger();
+    virtual void updateWatchModel();
+
+    virtual void stepExec();
+    virtual void stepOutExec();
+    virtual void nextExec();
+    virtual void stepIExec();
+    virtual void nextIExec();
+    
+    virtual void continueInferior();
+    virtual void runInferior();
+    virtual void interruptInferior();
+
+    virtual void runToLineExec(const QString &fileName, int lineNumber);
+    virtual void runToFunctionExec(const QString &functionName);
+    virtual void jumpToLineExec(const QString &fileName, int lineNumber);
+    virtual void assignValueInDebugger(const QString &expr, const QString &value);
+    virtual void executeDebuggerCommand(const QString &command);
+
+    virtual void activateFrame(int index);
+    virtual void selectThread(int index);
+
+    virtual void attemptBreakpointSynchronization();
+
+    virtual void loadSessionData();
+    virtual void saveSessionData();
+
+    virtual void reloadDisassembler();
+
+    virtual void reloadModules();
+    virtual void loadSymbols(const QString &moduleName);
+    virtual void loadAllSymbols();
+
+    virtual void reloadRegisters();
+
+protected:
+    void timerEvent(QTimerEvent*);
+
+private:
+    void startWatchTimer();
+    void killWatchTimer();
+    bool isDebuggeeRunning() { return m_watchTimer != -1; }
+    void handleDebugEvent();
+    void updateThreadList();
+    void updateStackTrace();
+    void handleDebugOutput(const char* szOutputString);
+    void handleBreakpointEvent(PDEBUG_BREAKPOINT pBP);
+
+private:
+    HANDLE                  m_hDebuggeeProcess;
+    HANDLE                  m_hDebuggeeThread;
+    int                     m_currentThreadId;
+    bool                    m_bIgnoreNextDebugEvent;
+
+    int                     m_watchTimer;
+    IDebugClient5*          m_pDebugClient;
+    IDebugControl4*         m_pDebugControl;
+    IDebugSystemObjects4*   m_pDebugSystemObjects;
+    IDebugSymbols3*         m_pDebugSymbols;
+    IDebugRegisters2*       m_pDebugRegisters;
+    MSVCDebugEventCallback  m_debugEventCallBack;
+    MSVCDebugOutput         m_debugOutputCallBack;
+
+    DebuggerManager *q;
+    IDebuggerManagerAccessForEngines *qq;
+
+    friend class MSVCDebugEventCallback;
+    friend class MSVCDebugOutput;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif
diff --git a/src/plugins/debugger/msvcdebugeventcallback.cpp b/src/plugins/debugger/msvcdebugeventcallback.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9ef74e63ef71a1dd9f995e6579aaefacaa6f2bd7
--- /dev/null
+++ b/src/plugins/debugger/msvcdebugeventcallback.cpp
@@ -0,0 +1,217 @@
+#include "msvcdebugeventcallback.h"
+#include "msvcdebugengine.h"
+#include "debuggermanager.h"
+
+#include <QDebug>
+
+namespace Debugger {
+namespace Internal {
+
+STDMETHODIMP
+MSVCDebugEventCallback::QueryInterface(
+    THIS_
+    IN REFIID InterfaceId,
+    OUT PVOID* Interface
+    )
+{
+    *Interface = NULL;
+
+    if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
+        IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
+    {
+        *Interface = (IDebugOutputCallbacks *)this;
+        AddRef();
+        return S_OK;
+    }
+    else
+    {
+        return E_NOINTERFACE;
+    }
+}
+
+STDMETHODIMP_(ULONG)
+MSVCDebugEventCallback::AddRef(
+    THIS
+    )
+{
+    // This class is designed to be static so
+    // there's no true refcount.
+    return 1;
+}
+
+STDMETHODIMP_(ULONG)
+MSVCDebugEventCallback::Release(
+    THIS
+    )
+{
+    // This class is designed to be static so
+    // there's no true refcount.
+    return 0;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::GetInterestMask(
+    THIS_
+    __out PULONG mask
+    )
+{
+    *mask = DEBUG_EVENT_CREATE_PROCESS | DEBUG_EVENT_EXIT_PROCESS
+            //| DEBUG_EVENT_CREATE_THREAD | DEBUG_EVENT_EXIT_THREAD
+            | DEBUG_EVENT_BREAKPOINT
+            | DEBUG_EVENT_EXCEPTION
+            ;
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::Breakpoint(
+    THIS_
+    __in PDEBUG_BREAKPOINT Bp
+    )
+{
+    qDebug() << "MSVCDebugEventCallback::Breakpoint";
+    m_pEngine->handleBreakpointEvent(Bp);
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::Exception(
+    THIS_
+    __in PEXCEPTION_RECORD64 Exception,
+    __in ULONG FirstChance
+    )
+{
+    qDebug() << "MSVCDebugEventCallback::Exception";
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::CreateThread(
+    THIS_
+    __in ULONG64 Handle,
+    __in ULONG64 DataOffset,
+    __in ULONG64 StartOffset
+    )
+{
+    //Debugger::ThreadInfo ti;
+    //ti.handle = Handle;
+    //ti.dataOffset = DataOffset;
+    //ti.startOffset = StartOffset;
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::ExitThread(
+    THIS_
+    __in ULONG ExitCode
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::CreateProcess(
+    THIS_
+    __in ULONG64 ImageFileHandle,
+    __in ULONG64 Handle,
+    __in ULONG64 BaseOffset,
+    __in ULONG ModuleSize,
+    __in_opt PCSTR ModuleName,
+    __in_opt PCSTR ImageName,
+    __in ULONG CheckSum,
+    __in ULONG TimeDateStamp,
+    __in ULONG64 InitialThreadHandle,
+    __in ULONG64 ThreadDataOffset,
+    __in ULONG64 StartOffset
+    )
+{
+    m_pEngine->m_hDebuggeeProcess = (HANDLE)Handle;
+    m_pEngine->m_hDebuggeeThread = (HANDLE)InitialThreadHandle;
+    m_pEngine->qq->notifyStartupFinished();
+    m_pEngine->qq->notifyInferiorRunning();
+
+    ULONG currentThreadId;
+    if (SUCCEEDED(m_pEngine->m_pDebugSystemObjects->GetThreadIdByHandle(InitialThreadHandle, &currentThreadId)))
+        m_pEngine->m_currentThreadId = currentThreadId;
+    else
+        m_pEngine->m_currentThreadId = 0;
+
+    m_pEngine->attemptBreakpointSynchronization();
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::ExitProcess(
+    THIS_
+    __in ULONG ExitCode
+    )
+{
+    UNREFERENCED_PARAMETER(ExitCode);
+    m_pEngine->m_hDebuggeeProcess = 0;
+    m_pEngine->m_hDebuggeeThread = 0;
+    m_pEngine->qq->notifyInferiorExited();
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::LoadModule(
+    THIS_
+    __in ULONG64 ImageFileHandle,
+    __in ULONG64 BaseOffset,
+    __in ULONG ModuleSize,
+    __in_opt PCSTR ModuleName,
+    __in_opt PCSTR ImageName,
+    __in ULONG CheckSum,
+    __in ULONG TimeDateStamp
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::UnloadModule(
+    THIS_
+    __in_opt PCSTR ImageBaseName,
+    __in ULONG64 BaseOffset
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::SystemError(
+    THIS_
+    __in ULONG Error,
+    __in ULONG Level
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::SessionStatus(
+    THIS_
+    __in ULONG Status
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::ChangeDebuggeeState(
+    THIS_
+    __in ULONG Flags,
+    __in ULONG64 Argument
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::ChangeEngineState(
+    THIS_
+    __in ULONG Flags,
+    __in ULONG64 Argument
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP MSVCDebugEventCallback::ChangeSymbolState(
+    THIS_
+    __in ULONG Flags,
+    __in ULONG64 Argument
+    )
+{
+    return S_OK;
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/msvcdebugeventcallback.h b/src/plugins/debugger/msvcdebugeventcallback.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa5633ca7911e72bfae15cf834b3bae28895f503
--- /dev/null
+++ b/src/plugins/debugger/msvcdebugeventcallback.h
@@ -0,0 +1,131 @@
+#pragma once
+
+#include <windows.h>
+#include <dbgeng.h>
+
+namespace Debugger {
+namespace Internal {
+
+class MSVCDebugEngine;
+
+class MSVCDebugEventCallback : public IDebugEventCallbacks
+{
+public:
+    MSVCDebugEventCallback(MSVCDebugEngine* dbg)
+        : m_pEngine(dbg)
+    {}
+
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        IN REFIID InterfaceId,
+        OUT PVOID* Interface
+        );
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        );
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        );
+
+    // IDebugEventCallbacks.
+
+    STDMETHOD(GetInterestMask)(
+        THIS_
+        __out PULONG mask
+        );
+
+    STDMETHOD(Breakpoint)(
+        THIS_
+        __in PDEBUG_BREAKPOINT Bp
+        );
+
+    STDMETHOD(Exception)(
+        THIS_
+        __in PEXCEPTION_RECORD64 Exception,
+        __in ULONG FirstChance
+        );
+
+    STDMETHOD(CreateThread)(
+        THIS_
+        __in ULONG64 Handle,
+        __in ULONG64 DataOffset,
+        __in ULONG64 StartOffset
+        );
+    STDMETHOD(ExitThread)(
+        THIS_
+        __in ULONG ExitCode
+        );
+
+    STDMETHOD(CreateProcess)(
+        THIS_
+        __in ULONG64 ImageFileHandle,
+        __in ULONG64 Handle,
+        __in ULONG64 BaseOffset,
+        __in ULONG ModuleSize,
+        __in_opt PCSTR ModuleName,
+        __in_opt PCSTR ImageName,
+        __in ULONG CheckSum,
+        __in ULONG TimeDateStamp,
+        __in ULONG64 InitialThreadHandle,
+        __in ULONG64 ThreadDataOffset,
+        __in ULONG64 StartOffset
+        );
+
+    STDMETHOD(ExitProcess)(
+        THIS_
+        __in ULONG ExitCode
+        );
+
+    STDMETHOD(LoadModule)(
+        THIS_
+        __in ULONG64 ImageFileHandle,
+        __in ULONG64 BaseOffset,
+        __in ULONG ModuleSize,
+        __in_opt PCSTR ModuleName,
+        __in_opt PCSTR ImageName,
+        __in ULONG CheckSum,
+        __in ULONG TimeDateStamp
+        );
+
+    STDMETHOD(UnloadModule)(
+        THIS_
+        __in_opt PCSTR ImageBaseName,
+        __in ULONG64 BaseOffset
+        );
+
+    STDMETHOD(SystemError)(
+        THIS_
+        __in ULONG Error,
+        __in ULONG Level
+        );
+
+    STDMETHOD(SessionStatus)(
+        THIS_
+        __in ULONG Status
+        );
+
+    STDMETHOD(ChangeDebuggeeState)(
+        THIS_
+        __in ULONG Flags,
+        __in ULONG64 Argument
+        );
+
+    STDMETHOD(ChangeEngineState)(
+        THIS_
+        __in ULONG Flags,
+        __in ULONG64 Argument
+        );
+
+    STDMETHOD(ChangeSymbolState)(
+        THIS_
+        __in ULONG Flags,
+        __in ULONG64 Argument
+        );
+
+private:
+    MSVCDebugEngine*   m_pEngine;
+};
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/msvcdebugoutput.cpp b/src/plugins/debugger/msvcdebugoutput.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4f121fb52fdd09f6287fbd82c028cd20589292ad
--- /dev/null
+++ b/src/plugins/debugger/msvcdebugoutput.cpp
@@ -0,0 +1,65 @@
+#include <windows.h>
+#include <dbgeng.h>
+
+#include "msvcdebugoutput.h"
+#include "msvcdebugengine.h"
+
+namespace Debugger {
+namespace Internal {
+
+STDMETHODIMP
+MSVCDebugOutput::QueryInterface(
+    THIS_
+    IN REFIID InterfaceId,
+    OUT PVOID* Interface
+    )
+{
+    *Interface = NULL;
+
+    if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
+        IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
+    {
+        *Interface = (IDebugOutputCallbacks *)this;
+        AddRef();
+        return S_OK;
+    }
+    else
+    {
+        return E_NOINTERFACE;
+    }
+}
+
+STDMETHODIMP_(ULONG)
+MSVCDebugOutput::AddRef(
+    THIS
+    )
+{
+    // This class is designed to be static so
+    // there's no true refcount.
+    return 1;
+}
+
+STDMETHODIMP_(ULONG)
+MSVCDebugOutput::Release(
+    THIS
+    )
+{
+    // This class is designed to be static so
+    // there's no true refcount.
+    return 0;
+}
+
+STDMETHODIMP
+MSVCDebugOutput::Output(
+    THIS_
+    IN ULONG mask,
+    IN PCSTR text
+    )
+{
+    UNREFERENCED_PARAMETER(mask);
+    m_pEngine->handleDebugOutput(text);
+    return S_OK;
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/msvcdebugoutput.h b/src/plugins/debugger/msvcdebugoutput.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0e1f32d79f11b4d3f14f1089e8758ff7d076959
--- /dev/null
+++ b/src/plugins/debugger/msvcdebugoutput.h
@@ -0,0 +1,43 @@
+#ifndef __MSVCDEBUGOUTPUT_H__
+#define __MSVCDEBUGOUTPUT_H__
+
+namespace Debugger {
+namespace Internal {
+
+class MSVCDebugEngine;
+
+class MSVCDebugOutput : public IDebugOutputCallbacks
+{
+public:
+    MSVCDebugOutput(MSVCDebugEngine* engine)
+        : m_pEngine(engine)
+    {}
+
+    // IUnknown.
+    STDMETHOD(QueryInterface)(
+        THIS_
+        IN REFIID InterfaceId,
+        OUT PVOID* Interface
+        );
+    STDMETHOD_(ULONG, AddRef)(
+        THIS
+        );
+    STDMETHOD_(ULONG, Release)(
+        THIS
+        );
+
+    // IDebugOutputCallbacks.
+    STDMETHOD(Output)(
+        THIS_
+        IN ULONG mask,
+        IN PCSTR text
+        );
+
+private:
+    MSVCDebugEngine* m_pEngine;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // #ifndef __MSVCDEBUGOUTPUT_H__