fix first part of bug #677, for second see feature request #688.
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / php / model / XDebugTarget.java
1 /**
2  * 
3  */
4 package net.sourceforge.phpeclipse.xdebug.php.model;
5
6 import java.util.List;
7
8 import net.sourceforge.phpeclipse.xdebug.core.IPHPDebugEvent;
9 import net.sourceforge.phpeclipse.xdebug.core.IProxyEventListener;
10 import net.sourceforge.phpeclipse.xdebug.core.IXDebugPreferenceConstants;
11 import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils;
12 import net.sourceforge.phpeclipse.xdebug.core.PathMapItem;
13 import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
14 import net.sourceforge.phpeclipse.xdebug.core.XDebugProxy;
15 import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants;
16
17 import org.eclipse.core.resources.IMarker;
18 import org.eclipse.core.resources.IMarkerDelta;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.debug.core.DebugEvent;
22 import org.eclipse.debug.core.DebugException;
23 import org.eclipse.debug.core.DebugPlugin;
24 import org.eclipse.debug.core.IDebugEventSetListener;
25 import org.eclipse.debug.core.ILaunch;
26
27 import org.eclipse.debug.core.model.IBreakpoint;
28 import org.eclipse.debug.core.model.IDebugTarget;
29 import org.eclipse.debug.core.model.ILineBreakpoint;
30 import org.eclipse.debug.core.model.IMemoryBlock;
31 import org.eclipse.debug.core.model.IProcess;
32 import org.eclipse.debug.core.model.IThread;
33 import org.w3c.dom.NamedNodeMap;
34 import org.w3c.dom.Node;
35
36 import net.sourceforge.phpeclipse.xdebug.core.xdebug.ResponseListener;
37 import net.sourceforge.phpeclipse.xdebug.core.xdebug.XDebugConnection;
38 import net.sourceforge.phpeclipse.xdebug.core.xdebug.ResponseListener.XDebugResponse;
39
40 /**
41  * @author Christian
42  *
43  */
44 public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugEventSetListener, IProxyEventListener {
45         private IProcess fProcess;
46         
47         private ILaunch fLaunch;
48         
49         private int fDebugPort;
50         
51         private boolean fSuspended = false;
52         
53         private boolean fTerminated = false;
54         
55         private XDebugThread fThread;
56         private IThread[] fThreads;
57         
58         private XDebugConnection fDebugConnection;
59
60         private ResponseListener fResponseListener;
61
62         private String fIdeKey;
63
64
65         /**
66          * Constructs a new debug target in the given launch and waits until
67          * someone with the ideKey connects to the Debugproxy
68          *  
69          * 
70          * @param launch containing launch
71          * @param process process of the interpreter
72          * @param ideKey 
73          * @param pathMap Pathmap for the debug session
74          * @exception CoreException if unable to connect to host
75          */     
76         public XDebugTarget(ILaunch launch, IProcess process, String ideKey) throws CoreException {
77                 fLaunch = launch;
78                 fProcess = process;
79                 fDebugConnection = null;
80                 fThread = null;
81                 fThreads = new IThread[0];
82                 fIdeKey = ideKey;
83                 
84                 fDebugPort = XDebugCorePlugin.getDefault().getPreferenceStore().getInt(IXDebugPreferenceConstants.DEBUGPORT_PREFERENCE);                
85                 if (fDebugPort == 0) {
86                         fDebugPort = IXDebugPreferenceConstants.DEFAULT_DEBUGPORT;
87                 }
88                 
89                 DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);
90                 DebugPlugin.getDefault().addDebugEventListener(this);
91         }
92
93         /* (non-Javadoc)
94          * @see org.eclipse.debug.core.model.IDebugTarget#getProcess()
95          */
96         public IProcess getProcess() {
97                 return fProcess;
98         }
99
100         /* (non-Javadoc)
101          * @see org.eclipse.debug.core.model.IDebugTarget#getThreads()
102          */
103         public IThread[] getThreads() throws DebugException {
104                 return fThreads;
105         }
106
107         /* (non-Javadoc)
108          * @see org.eclipse.debug.core.model.IDebugTarget#hasThreads()
109          */
110         public boolean hasThreads() throws DebugException {
111                 return (fThreads.length > 0);
112         }
113
114         /* (non-Javadoc)
115          * @see org.eclipse.debug.core.model.IDebugTarget#getName()
116          */
117         public String getName() throws DebugException {
118                 return "PHP XDebug Client at localhost:" + fDebugPort;
119         }
120
121         /* (non-Javadoc)
122          * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(org.eclipse.debug.core.model.IBreakpoint)
123          */
124         public boolean supportsBreakpoint(IBreakpoint breakpoint) {
125                 if (breakpoint.getModelIdentifier().equals(IXDebugConstants.ID_PHP_DEBUG_MODEL)) {
126                         return true;
127                 }
128                 return false;
129         }
130
131         /* (non-Javadoc)
132          * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
133          */
134         public IDebugTarget getDebugTarget() {
135                 return this;
136         }
137
138         /* (non-Javadoc)
139          * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
140          */
141         public ILaunch getLaunch() {
142                 return fLaunch;
143         }
144
145         /* (non-Javadoc)
146          * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
147          */
148         public boolean canTerminate() {
149                 if (getProcess()!=null)  // ther is no running Process in remote debugging
150                         return getProcess().canTerminate();
151                 return true;
152         }
153
154         /* (non-Javadoc)
155          * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
156          */
157         public boolean isTerminated() {
158 //              return getProcess().isTerminated();
159                 return fTerminated;
160         }
161
162         /* (non-Javadoc)
163          * @see org.eclipse.debug.core.model.ITerminate#terminate()
164          */
165         public void terminate() throws DebugException {
166                 if(fTerminated) {
167                         return;
168                 }
169                 
170                 if (XDebugCorePlugin.getDefault() != null) {
171                         XDebugProxy proxy = XDebugCorePlugin.getDefault().getXDebugProxy();
172                         proxy.removeProxyEventListener(this, fIdeKey);
173                         
174                         System.out.println("XDebug.Target: ProxyEventlistener removed");
175                         
176                         fTerminated = true;
177                         fSuspended = false;
178                         
179                         XDebugCorePlugin.getBreakpointManager().removeBreakpointListener(this);
180                         fireTerminateEvent();
181                         DebugPlugin.getDefault().removeDebugEventListener(this);
182                         /*if (fThread!=null)
183                                 fThread.removeEventListeners();*/
184                 }
185         }
186
187         /* (non-Javadoc)
188          * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
189          */
190         public boolean canResume() {
191                 return false;
192         }
193
194         /* (non-Javadoc)
195          * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
196          */
197         public boolean canSuspend() {
198                 return false;
199         }
200
201         /* (non-Javadoc)
202          * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
203          */
204         public boolean isSuspended() {
205                 return fSuspended;
206         }
207
208         /* (non-Javadoc)
209          * @see org.eclipse.debug.core.model.ISuspendResume#resume()
210          */
211         public void resume() throws DebugException {
212                 if (fDebugConnection != null) {
213                         fThread.setBreakpoints(null);
214                         fDebugConnection.run();
215                 }                       
216         }
217         
218         /**
219          * Notification the target has resumed for the given reason
220          * 
221          * @param detail reason for the resume
222          */
223         private void resumed(int detail) {
224                 fSuspended = false;
225                 fThread.fireResumeEvent(detail);
226         }
227         
228         /**
229          * Notification the target has suspended for the given reason
230          * 
231          * @param detail reason for the suspend
232          */
233         public void suspended(int detail) {
234                 fSuspended = true;
235                 fThread.fireSuspendEvent(detail);
236         }       
237         
238         /* (non-Javadoc)
239          * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
240          */
241         public void suspend() throws DebugException {
242         }
243
244         /* (non-Javadoc)
245          * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
246          */
247         public void breakpointAdded(IBreakpoint breakpoint) {
248                 IMarker marker = breakpoint.getMarker();
249                 IPath path = marker.getResource().getLocation();
250                 IPath cp = path.removeLastSegments(1);
251                 List pathMap = null;
252                 try {
253                         pathMap = fLaunch.getLaunchConfiguration().getAttribute(IXDebugConstants.ATTR_PHP_PATHMAP,(List)null);
254                 } catch (CoreException e2) {
255                         // TODO Auto-generated catch block
256                         e2.printStackTrace();
257                 }
258
259                 if (fDebugConnection != null)
260                 if (!fDebugConnection.isClosed()) {
261                         if (fProcess == null) {
262                                 PathMapItem pmi = null;
263                                 for (int i = 0; i < pathMap.size(); i++) {
264                                         pmi = new PathMapItem((String) pathMap.get(i));
265                                         IPath local = (IPath)pmi.getLocalPath().clone();
266                                         local = local.makeAbsolute();
267                                         int matchedSegments = local.segmentCount();
268                                         if (local.matchingFirstSegments(cp) == matchedSegments) {
269                                                 IPath newPath = pmi.getRemotePath();
270                                                 newPath = newPath.append(path.removeFirstSegments(matchedSegments));
271                                                 newPath = newPath.makeAbsolute();
272                                                 if (supportsBreakpoint(breakpoint)) {
273                                                         try {
274                                                                 if (breakpoint.isEnabled()) {
275                                                                         if (marker != null) {
276                                                                                 //XDebugResponse dr = fDebugConnection.breakpointSet(newPath.toString(), ((ILineBreakpoint)breakpoint).getLineNumber());
277
278                                                                                 int id = fDebugConnection.breakpointSet(newPath.toString(), ((ILineBreakpoint)breakpoint).getLineNumber(), marker.getAttribute(XDebugBreakpoint.HIT_COUNT,-1));
279                                                                                 XDebugResponse dr = getResponse(id);
280                                                                                 
281                                                                                 String bpid = dr.getAttributeValue("id");
282                                                                                 
283                                                                                 if (!"".equals(bpid))
284                                                                                         marker.setAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,Integer.parseInt(bpid));
285                                                                         }
286                                                                 }
287                                                         } catch (DebugException e) {
288                                                                 e.printStackTrace();
289                                                         } catch (CoreException e) {
290                                                                 e.printStackTrace();
291                                                         }
292                                                 }
293                                         }
294                                 }                       
295                         } else {
296                                 if (supportsBreakpoint(breakpoint)) {
297                                         try {
298                                                 if (breakpoint.isEnabled()) {
299                                                         if (marker != null) {
300                                                                 int id = fDebugConnection.breakpointSet(path.toString(), ((ILineBreakpoint)breakpoint).getLineNumber(), marker.getAttribute(XDebugBreakpoint.HIT_COUNT,-1));
301                                                                 XDebugResponse dr = getResponse(id);
302                                                                 String bpid = dr.getAttributeValue("id");
303                                                                 
304                                                                 if (!"".equals(bpid))
305                                                                         marker.setAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,Integer.parseInt(bpid));
306                                                         }
307                                                 }
308                                         } catch (DebugException e) {
309                                                 e.printStackTrace();
310                                         } catch (CoreException e) {
311                                                 e.printStackTrace();
312                                         }
313                                 }
314                         }
315                 }
316         }
317         
318         /* (non-Javadoc)
319          * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
320          */
321         public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
322                 if (supportsBreakpoint(breakpoint)) {
323                         try {
324                                 int id =((XDebugLineBreakpoint)breakpoint).getID();
325                                 if (id >0)
326                                         fDebugConnection.breakpointRemove(id);
327                         } catch (CoreException e) {
328                         }
329                 }
330         }
331
332         /* (non-Javadoc)
333          * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
334          */
335         public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
336 //              if (supportsBreakpoint(breakpoint)) {
337 //                      try {
338 //                              if (breakpoint.isEnabled()) {
339 //                                      breakpointAdded(breakpoint);
340 //                              } else {
341 //                                      breakpointRemoved(breakpoint, null);
342 //                              }
343 //                      } catch (CoreException e) {
344 //                      }
345 //              }
346         }
347
348         /* (non-Javadoc)
349          * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect()
350          */
351         public boolean canDisconnect() {
352                 return false;
353         }
354
355         /* (non-Javadoc)
356          * @see org.eclipse.debug.core.model.IDisconnect#disconnect()
357          */
358         public void disconnect() throws DebugException {
359         }
360
361         /* (non-Javadoc)
362          * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected()
363          */
364         public boolean isDisconnected() {
365                 return (false);
366 //              return (fDebugConnection==null);
367         }
368
369         /* (non-Javadoc)
370          * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval()
371          */
372         public boolean supportsStorageRetrieval() {
373                 return false;
374         }
375
376         /* (non-Javadoc)
377          * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long)
378          */
379         public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException {
380                 return null;
381         }
382
383         /**
384          * Notification we have connected to the PHP debugger and it has been started.
385          * Resume the the debugger.
386          */
387         public void started() throws DebugException {
388                 fThread.setBreakpoints(null);
389                 fThread.setStepping(false);
390
391                 int id = fDebugConnection.featureGet("detach");
392
393                 XDebugResponse response = getResponse(id);
394
395                 Integer.parseInt(response.getValue());
396                 System.out.println("in Target.started()");
397                 /*XDebugResponse response = fDebugConnection.featureGet("max_children");
398                 String a1 = response.getValue();
399                 System.out.println("max children:"+a1);
400                 XDebugResponse response1 = fDebugConnection.featureGet("max_children");
401                 String a2 = response1.getValue();
402                 System.out.println("max depth:"+a2);*/
403                 
404                 
405                 int id1 = fDebugConnection.featureSet("max_depth", "1024" );
406                 XDebugResponse response1 = getResponse(id1);
407                 if (response1.getAttributeValue("success").equals("1") ) {
408                         System.out.println("Set depth to 1024 (hack)");
409                 }
410                 int id2 = fDebugConnection.featureSet("max_children", "1024" );
411                 XDebugResponse response2 = getResponse(id2);
412                 if (response2.getAttributeValue("success").equals("1") ) {
413                         System.out.println("Set children to 1024 (hack)");
414                 }
415                 
416                 installDeferredBreakpoints();
417                 try {
418                         resume();
419                 } catch (DebugException e) {
420                         e.printStackTrace();
421                 }
422         }
423         
424         /**
425          * Install breakpoints that are already registered with the breakpoint
426          * manager.
427          */
428         private void installDeferredBreakpoints() {
429                 IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints();
430                 for (int i = 0; i < breakpoints.length; i++) {
431                         breakpointAdded(breakpoints[i]);
432                 }
433         }
434         
435         /**
436          * Returns the current stack frames in the target.
437          * 
438          * @return the current stack frames in the target
439          * @throws DebugException if unable to perform the request
440          */
441         public XDebugResponse getStackFrames() throws DebugException {
442                 int id = fDebugConnection.stackGet();
443                 XDebugResponse lastResponse = getResponse(id);
444                 return lastResponse;
445         }
446         
447         /**
448          * Single step the interpreter.
449          * 
450          * @throws DebugException if the request fails
451          */
452         protected void step_over() throws DebugException {
453                 fThread.setStepping(true);
454                 resumed(DebugEvent.STEP_OVER);
455                 fDebugConnection.stepOver();
456         }
457         
458         /**
459          * Single step the interpreter.
460          * 
461          * @throws DebugException if the request fails
462          */
463         protected void step_into() throws DebugException {
464                 fThread.setStepping(true);
465                 resumed(DebugEvent.STEP_INTO);
466                 fDebugConnection.stepInto();
467         }
468         
469         /**
470          * Single step the interpreter.
471          * 
472          * @throws DebugException if the request fails
473          */
474         protected void step_out() throws DebugException {
475                 fThread.setStepping(true);
476                 resumed(DebugEvent.STEP_RETURN);
477                 fDebugConnection.stepOut();
478         }
479         
480         public boolean setVarValue(String name, String value) {
481                 int id = fDebugConnection.setVarValue(name,value);
482                 XDebugResponse response = getResponse(id);
483                 
484                 if ((response.getAttributeValue("success")).equals("1")) {
485                         return true;
486                 } else {
487                         return false;
488                 }
489         }
490         
491         public void handleDebugEvents(DebugEvent[] events) {
492                 for (int i = 0; i < events.length; i++) {
493                         DebugEvent event = events[i];
494                         
495                         if (fResponseListener != null) {
496                                 Object s = null;
497                                 s = event.getSource();
498                                 if (s instanceof ResponseListener) {
499                                         if (!fResponseListener.equals((ResponseListener) s)) {
500                                                 return;
501                                         }
502                                 }
503                         } else {
504                                 return;
505                         }
506                         
507                         if (event.getKind() == DebugEvent.MODEL_SPECIFIC) {
508                                 switch (event.getDetail()) {
509                                         case IPHPDebugEvent.BREAKPOINT_HIT:
510                                                 int id = fDebugConnection.stackGet();
511                                                 XDebugResponse lastResponse = getResponse(id);
512
513                                                 IBreakpoint breakpoint = breakpointHit(lastResponse.getParentNode());
514                                                 
515                                                 if (breakpoint != null) {
516                                                         fThread.setBreakpoints(new IBreakpoint[]{breakpoint});
517                                                         fThread.incrementStepCounter();
518                                                         suspended(DebugEvent.BREAKPOINT);
519                                                 } else {
520                                                         try {
521                                                                 resume();
522                                                         } catch (DebugException e ) {
523                                                                 ; //nothing to do
524                                                         }
525                                                 }
526                                                 break;
527                                         case IPHPDebugEvent.STEP_END:
528                                                 fThread.incrementStepCounter();
529                                                 suspended(DebugEvent.STEP_END);
530                                                 break;
531                                         case IPHPDebugEvent.STOPPED:
532                                                 stopped();
533                                                 break;
534                                 }
535                         }
536                 }
537         }
538         
539         public void stopped() {
540                 if(fDebugConnection == null) {
541                         return;
542                 }
543
544                 stopListener();
545                 fDebugConnection.close();
546
547                 fThread.removeEventListeners();
548                 fThread = null;
549                 fThreads = new IThread[0];
550                 
551 /*              stopListener();
552                 fDebugConnection.close();*/
553
554                 fSuspended = false;
555
556                 // Dirty hack to check debugging mode (remote or local)
557                 if (fProcess!=null) {
558                         try {
559                                 terminate();
560                         } catch (DebugException e) {
561                                 e.printStackTrace();
562                         }
563                 } else {
564                         fDebugConnection = null;
565                         fireEvent(new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CONTENT));
566                 }               
567         }
568         
569         public void handleProxyEvent(/*String ideKey,*/ XDebugConnection connection) {
570                 setDebugConnection(connection);
571                 System.out.println("* New Connection - XDebug.Target: " + fDebugConnection.getSessionID());
572                 
573                 fireEvent(new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CHANGE));
574                 
575                 fThread = new XDebugThread(this);
576                 fThreads = new IThread[] {fThread};
577                 try {
578                         started();
579                 } catch( DebugException e ){
580                         e.printStackTrace();            
581                 }               
582         }
583
584         private void setDebugConnection(XDebugConnection connection) {
585                 if (connection != null) {
586                         fDebugConnection = connection;
587                         fResponseListener = new ResponseListener(connection);
588                         startListener();
589                 }
590         }
591         
592         /**
593          * @return Returns the fDebugConnection.
594          */
595         public XDebugConnection getDebugConnection() {
596                 return fDebugConnection;
597         }       
598         
599         public void addProcess(IProcess p) {
600                 fProcess = p;
601
602         }
603         public Node getLocalVariables(int level) throws DebugException {
604 //              XDebugResponse response = fDebugConnection.contextGet(level, 0);
605                 int id = fDebugConnection.contextGet(level, 0);
606                 XDebugResponse response = getResponse(id);
607                 
608                 return response.getParentNode();
609         }
610         
611         public Node getGlobalVariables(int level) throws DebugException {
612                 //XDebugResponse response = fDebugConnection.contextGet(level, 1);
613
614                 int id = fDebugConnection.contextGet(level, 1);
615                 XDebugResponse response = getResponse(id);
616                 
617                 return response.getParentNode();
618         }
619         
620         protected IBreakpoint breakpointHit(Node node) {
621                 Node child = node.getFirstChild();
622                 if (child.getNodeName().equals("stack")) {
623                         int lineNumber = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "lineno"));
624                         String filename=PHPDebugUtils.getAttributeValue(child, "filename");  
625                         IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints();
626                         for (int i = 0; i < breakpoints.length; i++) {
627                                 IBreakpoint breakpoint = breakpoints[i];
628                                 if (supportsBreakpoint(breakpoint)) {
629                                         if (breakpoint instanceof ILineBreakpoint) {
630                                                 ILineBreakpoint lineBreakpoint = (ILineBreakpoint) breakpoint;
631                                                 try {                                           
632                                                         if (breakpoint.isEnabled()) {
633                                                                 IMarker marker = breakpoint.getMarker();
634                                                                 if (marker != null) {
635                                                                         String endfilename;
636                                                                         
637                                                                         if (getProcess() == null) {
638                                                                                 endfilename = marker.getResource().getLocation().lastSegment(); 
639                                                                         } else {
640                                                                                 endfilename = marker.getResource().getLocation().toOSString();
641                                                                         }
642                                                                         
643                                                                         int id = fDebugConnection.breakpointGet(marker.getAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,-1));
644                                                                         XDebugResponse dr = getResponse(id);
645                                                                         
646                                                                         //String bpid = dr.getAttributeValue("command");                                                                        
647                                                                         Node hitCo = dr.getParentNode().getFirstChild();
648                                                                         int hitCount = 0;
649                                                                         if (hitCo.hasAttributes()) {
650                                                                                 NamedNodeMap listAttribute = hitCo.getAttributes();
651                                                                                 Node attribute = listAttribute.getNamedItem("hit_count");
652                                                                                 if (attribute !=null) {
653                                                                                         hitCount = Integer.parseInt(attribute.getNodeValue());
654                                                                                 }
655                                                                         }
656
657                                                                         //String hitCount = hitCo.getAttributeValue("hit_count");                                                                       
658                                                                         if(PHPDebugUtils.unescapeString(filename).endsWith(endfilename)
659                                                                                         && (lineBreakpoint.getLineNumber() == lineNumber) ) {
660                                                                                 if (marker.getAttribute(XDebugLineBreakpoint.HIT_COUNT, 0) > 0) {
661                                                                                         if (marker.getAttribute(XDebugLineBreakpoint.HIT_COUNT, 0) == hitCount) {
662                                                                                                 return (breakpoint);                                                                                            
663                                                                                         }
664                                                                                 } else {
665                                                                                         return (breakpoint);
666                                                                                 }
667                                                                         }
668                                                                 }
669                                                         }
670                                                 } catch (CoreException e) {
671                                                 }
672                                         }
673                                 }
674                         }
675                 }
676                 
677                 return null;
678         }
679         
680         public void startListener() {
681                 fResponseListener.schedule();
682         }
683         
684         public /*boolean*/ void stopListener() {
685                 /*return*/ fResponseListener.cancel(); //done(null); //.cancel();
686         }
687         public XDebugResponse getResponse(int id) {
688                 XDebugResponse response = fResponseListener.getResponse(id);
689
690                 return response;
691         }
692 }