Implemented breakpoint service, namely perform these in agent:
breakpoint addition and removal, remove breakpoints from memory read,
run over breakpoint. That should speed up debugging especially stepping.
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/WindowsDebugAgent.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/WindowsDebugAgent.cpp
index 1086893..1a70828 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/WindowsDebugAgent.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/WindowsDebugAgent.cpp
@@ -18,6 +18,7 @@
 #include "RegistersService.h"
 #include "MemoryService.h"
 #include "LoggingService.h"
+#include "BreakpointsService.h"
 
 #include "EventClientNotifier.h"
 #include "Logger.h"
@@ -97,6 +98,14 @@
 #endif
 
 	try {
+	// For interim test purpose only:
+	// Use this unpublished option to turn off BreakpointsService,
+	// namely use EDC generic breakpoints mechanism.
+	//
+	bool installBpService = true;
+	if (argc > 1 && strcmp(argv[1], "-nobpservice") == 0)
+		installBpService = false;
+
 	static const char * url = "TCP:";
 	PeerServer * ps = NULL;
 	ini_mdep();
@@ -117,6 +126,8 @@
 	new RegistersService(proto);
 	new MemoryService(proto);
 	new LoggingService(proto);
+	if (installBpService)
+		new BreakpointsService(proto);
 	
 	ps = channel_peer_from_url(url);
 
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/BreakpointsService.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/BreakpointsService.cpp
new file mode 100644
index 0000000..ef1ff6e
--- /dev/null
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/BreakpointsService.cpp
@@ -0,0 +1,304 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Nokia and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ * Nokia - Initial API and implementation

+ *******************************************************************************/

+

+#include "BreakpointsService.h"

+#include "ContextManager.h"

+

+#include <string>

+

+#include "TCFHeaders.h"

+#include "TCFChannel.h"

+

+#include "AgentUtils.h"

+#include "ContextManager.h"

+#include "EventClientNotifier.h"

+#include "Logger.h"

+

+#include "WinProcess.h"

+#include "WinThread.h"

+

+static const char * sServiceName = "Breakpoints";

+

+static const unsigned char	sBreakInst = 0xCC;

+

+bool BreakpointsService::sServiceInstalled = false;

+

+//

+// The static function reads the context ids for a breakpoint

+//

+static void read_id_array(InputStream* inp, void* arg)

+{

+     TCFInputStream inpStream(inp);

+     std::vector<std::string>* ids = (std::vector<std::string>*)(arg);

+     std::string str = inpStream.readString();

+     ids->push_back(str);    

+}

+

+//

+// This static function is used to read all the breakpoint properties or attributes

+//

+static void read_breakpoint_attr(InputStream * inp, const char * nm, void * arg)

+{

+    TCFInputStream inpStream(inp);    

+    TBreakpoint * attrs = (TBreakpoint*)arg;

+                

+    if (strcmp(nm, "Location") == 0)

+    {

+    	std::string location(inpStream.readString());

+    	// atoi fails on large unsigned ints.

+    	// this will also handle negative numbers, though.

+    	sscanf(location.c_str(), "%u", (unsigned int*)&attrs->address);

+        return;

+    }

+

+    if (strcmp(nm, "ContextIds") == 0)

+    {

+        json_read_array(inp,read_id_array,&attrs->iContextIds);

+        return;

+    }

+    

+    if (strcmp(nm, "ID") == 0)

+    {

+        attrs->hostBreakPointId = inpStream.readString();

+        return;

+    }

+    

+    if (strcmp(nm, "Enabled") == 0)

+    {

+        attrs->enabled = json_read_boolean(inp);

+        return;

+    }

+    

+    json_skip_object(inp);    

+}

+

+//

+// BreakpointService::BreakpointService()

+//

+BreakpointsService::BreakpointsService(Protocol * proto)

+                :TCFService(proto) 

+{

+    AddCommand("add", CommandAddBreakpoint);

+    AddCommand("remove", CommandRemoveBreakpoint);

+

+    sServiceInstalled = true;

+}

+

+//

+//  static function to get the service name

+//

+const char* BreakpointsService::GetName()

+{

+    return sServiceName;

+}

+

+// 

+// BreakpointService::CommandAddBreakpoint()

+//

+void BreakpointsService::CommandAddBreakpoint(const char * token, Channel * c)

+{

+    LogTrace("BreakpointService::command_add_Breakpoint", "token: %s", token);

+       

+    TCFChannel channel(c);

+    TBreakpoint* breakInfo = new TBreakpoint();

+    json_read_struct(&c->inp, read_breakpoint_attr, breakInfo);

+    

+    channel.readZero();

+    channel.readComplete();

+    

+    // EDC in 3.x > 20100831 will pass a thread-specific bp (if known) at the end of the list.

+    // For now we stick with process-specific breakpoints.

+    // TODO: see if we want thread-specific breakpoints in the future.

+    std::string contextID = breakInfo->iContextIds.front();

+    

+    Context* context = ContextManager::findContext(contextID);

+    

+    RunControlContext* thread_context = 0;

+    WinProcess* proc_context = 0;

+    

+    if ((proc_context = dynamic_cast<WinProcess*>(context)) != NULL)

+    	{

+    	// id is a process

+    	}

+    else if ((thread_context = dynamic_cast<WinThread*>(context)) != NULL)

+    	{

+    	// id is a thread

+    	proc_context = dynamic_cast<WinProcess*>(ContextManager::findContext(

+    			thread_context->GetParentID()));

+    	}

+

+	if (!proc_context || !proc_context->IsDebugging()) 

+		{

+		channel.writeCompleteReply(token, ERR_INV_CONTEXT);

+		return;

+		}

+

+	// "thread_context" is not required.

+    if (thread_context && !thread_context->IsDebugging())

+    	{

+    	channel.writeCompleteReply(token, ERR_INV_CONTEXT);

+		return;

+		}

+    

+    if (!breakInfo->enabled)

+		{

+    	trace(LOG_ALWAYS, "!!! cannot set disabled breakpoints");

+		channel.writeCompleteReply(token, ERR_UNSUPPORTED);

+		return;

+		}

+

+	breakInfo->procHandle = proc_context->GetProcessHandle();

+

+	int err = InsertBreak(breakInfo);

+	

+	if( err == 0)

+		{

+		trace(LOG_ALWAYS, "Breakpoint added for ID = %s", breakInfo->hostBreakPointId.c_str());

+		sBreakPointMap[breakInfo->hostBreakPointId] = breakInfo;

+		}

+	

+	channel.writeCompleteReply(token, err);

+}

+

+//

+// BreakpointService::CommandRemoveBreakpoint()

+//

+void BreakpointsService::CommandRemoveBreakpoint(const char * token, Channel * c)

+{

+    LogTrace("BreakpointService::command_remove_Breakpoint", "token: %s", token);

+    

+    TCFChannel channel(c); 

+    int err = 0;

+    int overallError = 0;

+    std::vector<std::string> breakIdList;

+    json_read_array(&c->inp, read_id_array, &breakIdList);

+    

+    channel.readZero();

+    channel.readComplete();

+    

+	std::vector<std::string>::iterator iter ;

+	for(iter = breakIdList.begin(); iter != breakIdList.end(); )

+		{

+		TID2BreakpointMap::iterator it = sBreakPointMap.find(*iter++);

+		if (it == sBreakPointMap.end())

+			{

+			if (!overallError)

+			    overallError = ERR_OTHER;

+			continue;

+			}

+		

+		TBreakpoint* bp = it->second;

+		sBreakPointMap.erase(it->first);

+		

+		err = ClearBreak(bp);

+		

+		delete bp;

+

+		// ignore "not found" from the driver, since some breakpoints

+		// are removed automatically on process kill / detach / etc.

+		if (err != 0 && err != ERR_OTHER && !overallError)

+		    overallError = err;

+		}

+    

+    channel.writeCompleteReply(token, overallError);

+}

+

+/*

+ * Is the Breakpoints service installed in the agent ?

+ */

+bool BreakpointsService::ServiceInstalled()

+{

+	return sServiceInstalled;

+}

+

+/*

+ * Insert a software breakpoint in a process.

+ */

+int BreakpointsService::InsertBreak(const TBreakpoint* bpInfo)

+{

+	// save byte at breakpoint address.

+	if (! ReadProcessMemory(bpInfo->procHandle, (LPCVOID)bpInfo->address, (LPVOID)&bpInfo->originalByte, 1, NULL))

+		return GetLastError();

+

+	// write breakpoint (INT3) to memory

+	if (! WriteProcessMemory(bpInfo->procHandle, (LPVOID)bpInfo->address, (LPVOID)&sBreakInst, 1, NULL))

+		return GetLastError();

+

+	// make sure original instruction isn't already in cache

+	if (! FlushInstructionCache(bpInfo->procHandle, (LPCVOID) bpInfo->address, 1))

+		return GetLastError();

+

+	return 0;

+}

+

+/*

+ * Clear a breakpoint from a process.

+ */

+int BreakpointsService::ClearBreak(const TBreakpoint* bpInfo)

+{

+	// write breakpoint (INT3) to memory

+	if (! WriteProcessMemory(bpInfo->procHandle, (LPVOID)bpInfo->address, (LPVOID)&bpInfo->originalByte, 1, NULL))

+		return GetLastError();

+

+	// make sure bp instruction isn't already in cache

+	if (! FlushInstructionCache(bpInfo->procHandle, (LPCVOID) bpInfo->address, 1))

+		return GetLastError();

+

+	return 0;

+}

+

+/*

+ * find if there's a breakpoint at the given address in a process.

+ */

+TBreakpoint* BreakpointsService::FindBreakpointByAddress(HANDLE processHandle, unsigned long address)

+{

+	TID2BreakpointMap::iterator iter;

+	for (iter = sBreakPointMap.begin(); iter != sBreakPointMap.end(); iter++) {

+		TBreakpoint* bp = iter->second;

+		if (processHandle == bp->procHandle &&	// same process

+				address == bp->address)

+			return bp;

+	}

+	return NULL;

+}

+

+/*

+ * Given a memory buffer read from a process, remove any breakpoint instructions added by debugger in the buffer.

+ */

+void BreakpointsService::RemoveBreakpointsFromMemoryRead(HANDLE processHandle, ContextAddress address, char* memBuffer, unsigned long size)

+{

+	TID2BreakpointMap::iterator iter;

+	for (iter = sBreakPointMap.begin(); iter != sBreakPointMap.end(); iter++) {

+		TBreakpoint* bp = iter->second;

+		if (processHandle == bp->procHandle &&	// same process

+				address <= bp->address && address+size > bp->address)	// bp falls in the buffer

+		{

+			char *byteToChange = memBuffer + (bp->address - address);

+			*byteToChange = bp->originalByte;

+		}

+	}

+}

+

+/*

+ * Given a memory buffer that has been writen to a process, re-inssert any breakpoints in the buffer range.

+ */

+void BreakpointsService::ReInsertBreakpointsAfterMemoryWrite(HANDLE processHandle, ContextAddress address, char* memBuffer, unsigned long size)

+{

+	TID2BreakpointMap::iterator iter;

+	for (iter = sBreakPointMap.begin(); iter != sBreakPointMap.end(); iter++) {

+		TBreakpoint* bp = iter->second;

+		if (processHandle == bp->procHandle &&	// same process

+				address <= bp->address && address+size > bp->address)	// bp falls in the buffer

+		{

+			InsertBreak(bp);

+		}

+	}

+}

diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/BreakpointsService.h b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/BreakpointsService.h
new file mode 100644
index 0000000..92783dc
--- /dev/null
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/BreakpointsService.h
@@ -0,0 +1,75 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Nokia and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ * Nokia - Initial API and implementation

+ *******************************************************************************/

+

+#ifndef BREAKPOINTSERVICE_H_

+#define BREAKPOINTSERVICE_H_

+

+#include <map>

+#include <string>

+#include <vector>

+

+#include "TCFService.h"

+#include "TCFContext.h"

+

+struct Protocol;

+struct Channel;

+

+//

+// To store the breakpoint info

+//

+struct TBreakpoint

+{

+    std::vector<std::string> iContextIds;

+    HANDLE  procHandle;	// Win32 handle of the hosting process

+    std::string hostBreakPointId;	// breakpoint ID from host debugger.

+    ContextAddress address;

+    bool enabled;

+    unsigned char originalByte;	// original byte where we set the bp.

+    

+    TBreakpoint(): address(0), enabled(true), originalByte(0)

+    {}

+};

+

+typedef std::map<std::string, TBreakpoint*> TID2BreakpointMap;

+

+/*

+ * A list of breakpoints in all processes in the debug session.

+ */

+static TID2BreakpointMap sBreakPointMap;

+

+//

+// Breakpoint service implementation

+//

+class BreakpointsService: public TCFService

+{

+public:

+    BreakpointsService(Protocol * proto);

+    

+    const char* GetName();

+

+    static void CommandAddBreakpoint(const char *, Channel *);

+    static void CommandRemoveBreakpoint(const char *, Channel *);

+

+    static int InsertBreak(const TBreakpoint* bpInfo);

+    static int ClearBreak(const TBreakpoint* bpInfo);

+

+    static TBreakpoint* FindBreakpointByAddress(HANDLE processHandle, unsigned long address);

+    static void RemoveBreakpointsFromMemoryRead(HANDLE, ContextAddress, char*, unsigned long);

+    static void ReInsertBreakpointsAfterMemoryWrite(HANDLE, ContextAddress, char*, unsigned long);

+

+    static bool ServiceInstalled();

+

+private:

+    static bool sServiceInstalled;

+};

+

+

+#endif /* BREAKPOINTSERVICE_H_ */

diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/ResumeContextAction.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/ResumeContextAction.cpp
index 925113a..3ee5f1e 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/ResumeContextAction.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/ResumeContextAction.cpp
@@ -13,18 +13,67 @@
 #include "WinProcess.h"
 #include "WinThread.h"
 #include "WinDebugMonitor.h"
+#include "RunControlService.h"
+#include "BreakpointsService.h"
 
-ResumeContextAction::ResumeContextAction(const AgentActionParams& params, ContextOSID processid,
-		ContextOSID threadid) : AgentAction(params) {
-	processid_ = processid;
-	threadid_ = threadid;
+ResumeContextAction::ResumeContextAction(const AgentActionParams& params,
+		WinProcess& process,
+		WinThread& thread,
+		long resumeMode) : AgentAction(params), process_(process), thread_(thread) {
+	resumeMode_ = resumeMode;
 }
 
 ResumeContextAction::~ResumeContextAction(void) {
 }
 
+/*
+ * This will & must be run in debugger monitor thread.
+ */
 void ResumeContextAction::Run() {
-	ContinueDebugEvent(processid_, threadid_, DBG_CONTINUE);
+	// Single step over a breakpoint (if any) at current PC.
+	//
+	TBreakpoint* bpAtStartAddress = BreakpointsService::FindBreakpointByAddress(process_.GetProcessHandle(), thread_.GetPCAddress());
+	if (bpAtStartAddress) {
+		BreakpointsService::ClearBreak(bpAtStartAddress);
+		thread_.EnableSingleStep();
+	}
+	else if (resumeMode_ == RM_STEP_INTO)
+		thread_.EnableSingleStep();
+
+	ContinueDebugEvent(process_.GetOSID(), thread_.GetOSID(), DBG_CONTINUE);
+
+	// notify host the Resume action is done before
+	// any suspend event is reported.
 	params.reportSuccessForAction();
 
+	if (bpAtStartAddress) {
+		DEBUG_EVENT debugEvent;
+
+		if (WaitForDebugEvent(&debugEvent, 200 /* ms */)) {
+			// Done executing single instruction.
+			BreakpointsService::InsertBreak(bpAtStartAddress);	// restore the bp
+
+			if (debugEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP) {
+				if (resumeMode_ == RM_STEP_INTO)
+					// single-step done, report suspend event to host.
+					process_.GetMonitor()->HandleDebugEvent(debugEvent);
+				else {
+					// other resume modes
+					// Ignore the SINGLE_STEP event, go on to Resume again
+					ContinueDebugEvent(process_.GetOSID(), thread_.GetOSID(), DBG_CONTINUE);
+				}
+			}
+			else {
+				// Other exceptions
+				// Handle the event, say, report to host.
+				process_.GetMonitor()->HandleDebugEvent(debugEvent);
+			}
+		}
+		else {
+			trace(LOG_ALWAYS, "Failed to execute one instruction. Error: %d", GetLastError());
+		}
+	}
+	else {
+		// the event loop of monitor thread would catch and report event.
+	}
 }
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/ResumeContextAction.h b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/ResumeContextAction.h
index 7e57b58..2e4c1de 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/ResumeContextAction.h
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/ResumeContextAction.h
@@ -11,17 +11,19 @@
 #pragma once
 #include "AgentAction.h"
 #include "TCFContext.h"
+#include "WinProcess.h"
+#include "WinThread.h"
 
 class ResumeContextAction: public AgentAction {
 public:
-	ResumeContextAction(const AgentActionParams& params, ContextOSID processid, ContextOSID threadid);
+	ResumeContextAction(const AgentActionParams& params, WinProcess& process, WinThread& thread, long resumeMode);
 	virtual ~ResumeContextAction(void);
 
 	void Run();
 
 private:
 
-	ContextOSID processid_;
-	ContextOSID threadid_;
-
+	WinProcess& process_;
+	WinThread& thread_;
+	long resumeMode_;
 };
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.h b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.h
index 9cedef8..aed6d0a 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.h
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.h
@@ -77,10 +77,11 @@
 
 	static std::string GetDebugExceptionDescription(const EXCEPTION_DEBUG_INFO& exceptionInfo);
 
+	void HandleDebugEvent(DEBUG_EVENT& debugEvent);
+
 private:
 	void AttachToProcessForDebug();
 
-	void HandleDebugEvent(DEBUG_EVENT& debugEvent);
 	void HandleNoDebugEvent();
 
 	void HandleExceptionEvent(DEBUG_EVENT& debugEvent);
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp
index 40f82e4..9ae67e9 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp
@@ -20,6 +20,7 @@
 #include "ProtocolConstants.h"
 #include "RunControlService.h"
 #include "ContextManager.h"
+#include "BreakpointsService.h"
 
 std::map<int, WinProcess*> WinProcess::processIDMap;
 
@@ -101,13 +102,14 @@
 }
 
 int WinProcess::ReadMemory(const ReadWriteMemoryParams& params) throw (AgentException) {
-	// to do: handle breakpoints and watchpoints
 	int result = 0;
 
 	boolean success = ReadProcessMemory(processHandle_, (LPCVOID) params.address,
 			params.memBuffer, params.size, params.sizeTransferred);
 	if (!success)
 		result = GetLastError();
+	else
+		BreakpointsService::RemoveBreakpointsFromMemoryRead(processHandle_, params.address, params.memBuffer, params.size);
 
 	return result;
 }
@@ -120,7 +122,9 @@
 			params.memBuffer, params.size, params.sizeTransferred);
 	if (!success)
 		result = GetLastError();
-
+	else {
+		BreakpointsService::ReInsertBreakpointsAfterMemoryWrite(processHandle_, params.address, params.memBuffer, params.size);
+	}
 	return result;
 }
 
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp
index 63d33fc..811b235 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp
@@ -21,6 +21,7 @@
 #include "ResumeContextAction.h"
 #include "ProtocolConstants.h"
 #include "RunControlService.h"
+#include "BreakpointsService.h"
 
 std::map<std::pair<int, int>, WinThread*> WinThread::threadIDMap_;
 
@@ -121,11 +122,41 @@
 	MarkSuspended();
 	exceptionInfo_ = debugEvent.u.Exception;
 	EnsureValidContextInfo();
+	AdjustPC();
 	EventClientNotifier::SendContextSuspended(this,
 			GetPCAddress(), GetSuspendReason(), GetExceptionMessage());
 
 }
 
+/*
+ * Check if the program is stopped due to a software breakpoint
+ * installed by the agent, if yes, move PC back by one byte.
+ */
+void WinThread::AdjustPC() {
+	// Bail out if the agent does not install & manage
+	// breakpoints (namely the EDC host uses generic
+	// software breakpoint mechanism).
+	if (! BreakpointsService::ServiceInstalled())
+		return;
+
+	/*
+	 * Check
+	 * 1. Did we stop due to a breakpoint exception ?
+	 *   -- This is to prevent adjusting PC for other exceptions such as
+	 *      divide-by-zero & invalid code.
+	 * 2. is there a software breakpoint at the byte right before the PC?
+	 *   -- this is to exclude the case of user-inserted "int 3" instruction.
+	 */
+	if (exceptionInfo_.ExceptionRecord.ExceptionCode != EXCEPTION_BREAKPOINT)
+		return;
+
+	ContextAddress pc = GetPCAddress();
+	pc--;
+	if (NULL != BreakpointsService::FindBreakpointByAddress(parentProcess_.GetProcessHandle(), pc)) {
+		SetRegisterValue("EIP", 4, (char*)&pc);
+	}
+}
+
 void WinThread::HandleExecutableEvent(bool isLoaded, const std::string& exePath,
 		unsigned long baseAddress, unsigned long codeSize) {
 	MarkSuspended();
@@ -412,20 +443,23 @@
 	}
 	else {
 		parentProcess_.GetMonitor()->PostAction(new ResumeContextAction(
-			params, parentProcess_.GetOSID(), GetOSID()));
+			params, parentProcess_, *this, RM_RESUME));
 	}
 }
 
-void WinThread::SingleStep(const AgentActionParams& params) throw (AgentException) {
-	//if (exceptionInfo_.ExceptionRecord.ExceptionCode == USER_SUSPEND_THREAD){
-	//	ResumeThread(handle_);
-	//}
+/*
+ * Enable single instruction step by setting Trap Flag (TF) bit.
+ */
+void WinThread::EnableSingleStep() {
 #define FLAG_TRACE_BIT 0x100
+	// The bit will be auto-cleared after next resume.
 	threadContextInfo_.EFlags |= FLAG_TRACE_BIT;
 	SetThreadContext(handle_, &threadContextInfo_);
+}
 
+void WinThread::SingleStep(const AgentActionParams& params) throw (AgentException) {
 	parentProcess_.GetMonitor()->PostAction(new ResumeContextAction(
-			params, parentProcess_.GetOSID(), GetOSID()));
+			params, parentProcess_, *this, RM_STEP_INTO));
 }
 
 void WinThread::PrepareForTermination(const AgentActionParams& params) throw (AgentException) {
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h
index b9d7b85..57a0270 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h
@@ -57,6 +57,11 @@
 	void HandleExecutableEvent(bool isLoaded, const std::string& exePath,
 			unsigned long baseAddress, unsigned long codeSize);
 
+	/** Address where suspend is reported */
+	ContextAddress GetPCAddress();
+
+	void EnableSingleStep();
+
 private:
 	void initialize();
 
@@ -65,8 +70,8 @@
 	bool isSuspended();
 	void MarkSuspended();
 
-	/** Address where suspend is reported */
-	ContextAddress GetPCAddress();
+	void AdjustPC();
+
 	/** REASON_xx code for suspend */
 	const char* GetSuspendReason();
 	/** Description for suspend */