/** Removes last step request. */
 void removeStepRequest() {
   if (stepRequest != null) {
     requestManager.deleteEventRequest(stepRequest);
     stepRequest = null;
   }
   if (findSourceMER != null) {
     requestManager.deleteEventRequest(findSourceMER);
     findSourceMER = null;
   }
   if (findSourceSR != null) {
     requestManager.deleteEventRequest(findSourceSR);
     findSourceSR = null;
   }
 }
 /**
  * If this line can not be current => stepOver & return true. {support for non java languages}
  *
  * <p>return false on the other hand.
  */
 boolean resolveCanBeCurrent(ThreadReference tr, Line l) {
   if ((l != null) && (!canBeCurrent(l, false))) {
     try {
       removeStepRequest();
       findSourceSR =
           requestManager.createStepRequest(tr, StepRequest.STEP_LINE, StepRequest.STEP_OVER);
       findSourceSR.addCountFilter(1);
       findSourceSR.setSuspendPolicy(EventRequest.SUSPEND_ALL);
       operator.register(findSourceSR, this);
       findSourceSR.enable();
       operator.resume();
     } catch (DuplicateRequestException e) {
       e.printStackTrace();
     }
     return true;
   }
   return false;
 }
 /** Step out. */
 public synchronized void stepOut() throws DebuggerException {
   if (virtualMachine == null) return;
   removeStepRequest();
   try {
     setLastAction(ACTION_STEP_OUT);
     stepRequest =
         requestManager.createStepRequest(
             currentThread.getThreadReference(), StepRequest.STEP_LINE, StepRequest.STEP_OUT);
     stepRequest.addCountFilter(1);
     stepRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
     operator.register(stepRequest, this);
     stepRequest.enable();
     virtualMachine.resume();
     super.stepOut();
   } catch (DuplicateRequestException e) {
     e.printStackTrace();
   }
 }
  public void applyThreadFilter(
      @NotNull final DebugProcessImpl debugProcess, @Nullable ThreadReference newFilterThread) {
    final RequestManagerImpl requestManager = debugProcess.getRequestsManager();
    final ThreadReference oldFilterThread = requestManager.getFilterThread();
    if (Comparing.equal(newFilterThread, oldFilterThread)) {
      // the filter already added
      return;
    }
    requestManager.setFilterThread(newFilterThread);
    if (newFilterThread == null || oldFilterThread != null) {
      final List<Breakpoint> breakpoints = getBreakpoints();
      for (Breakpoint breakpoint : breakpoints) {
        if (LineBreakpoint.CATEGORY.equals(breakpoint.getCategory())
            || MethodBreakpoint.CATEGORY.equals(breakpoint.getCategory())) {
          requestManager.deleteRequest(breakpoint);
          breakpoint.createRequest(debugProcess);
        }
      }
    } else {
      // important! need to add filter to _existing_ requests, otherwise Requestor->Request mapping
      // will be lost
      // and debugger trees will not be restored to original state
      abstract class FilterSetter<T extends EventRequest> {
        void applyFilter(@NotNull final List<T> requests, final ThreadReference thread) {
          for (T request : requests) {
            try {
              final boolean wasEnabled = request.isEnabled();
              if (wasEnabled) {
                request.disable();
              }
              addFilter(request, thread);
              if (wasEnabled) {
                request.enable();
              }
            } catch (InternalException e) {
              LOG.info(e);
            }
          }
        }

        protected abstract void addFilter(final T request, final ThreadReference thread);
      }

      final EventRequestManager eventRequestManager = requestManager.getVMRequestManager();

      new FilterSetter<BreakpointRequest>() {
        @Override
        protected void addFilter(
            @NotNull final BreakpointRequest request, final ThreadReference thread) {
          request.addThreadFilter(thread);
        }
      }.applyFilter(eventRequestManager.breakpointRequests(), newFilterThread);

      new FilterSetter<MethodEntryRequest>() {
        @Override
        protected void addFilter(
            @NotNull final MethodEntryRequest request, final ThreadReference thread) {
          request.addThreadFilter(thread);
        }
      }.applyFilter(eventRequestManager.methodEntryRequests(), newFilterThread);

      new FilterSetter<MethodExitRequest>() {
        @Override
        protected void addFilter(
            @NotNull final MethodExitRequest request, final ThreadReference thread) {
          request.addThreadFilter(thread);
        }
      }.applyFilter(eventRequestManager.methodExitRequests(), newFilterThread);
    }
  }
  /** Finds the first executed line with source code. */
  public void traceToSourceCode(ThreadReference thread) {
    // S ystem.out.println ("Start finding!!! "); // NOI18N

    // create Step Request for searching a source code
    try {
      findSourceSR =
          requestManager.createStepRequest(thread, StepRequest.STEP_LINE, StepRequest.STEP_OUT);
      findSourceSR.addCountFilter(1);
      findSourceSR.setSuspendPolicy(EventRequest.SUSPEND_ALL);
      operator.register(findSourceSR, this);
      findSourceSR.enable();
    } catch (DuplicateRequestException e) {
      e.printStackTrace();
    }

    // create Method Entry Request for searching a source code
    findSourceMER = requestManager.createMethodEntryRequest();
    findSourceMER.setSuspendPolicy(EventRequest.SUSPEND_ALL);
    findSourceMER.addThreadFilter(thread);
    findSourceCounter = 0;
    operator.register(
        findSourceMER,
        new Executor() {
          public void exec(com.sun.jdi.event.Event event) {
            if (findSourceCounter == 500) {
              // finding source takes a long time
              operator.resume();
              if (findSourceMER != null) {
                requestManager.deleteEventRequest(findSourceMER);
                findSourceMER = null;
              }
              return;
            }
            findSourceCounter++;

            Location loc = ((MethodEntryEvent) event).location();
            if (loc == null) {
              // no line => continue finding
              operator.resume();
              return;
            }
            String className = loc.declaringType().name();
            int ln = loc.lineNumber();
            // S ystem.out.println ("FIND " + className + " : " + ln); // NOI18N
            try {
              Line l = null;
              if ((l = Utils.getLineForSource(className, loc.sourceName(), ln)) == null) {
                // no line => continue finding
                operator.resume();
                return;
              }

              // WOW I have a nice line!
              ThreadReference tr = ((MethodEntryEvent) event).thread();
              if (resolveCanBeCurrent(tr, l))
                // if can not be current => steps to some line
                return;

              // line can be current!
              String threadName = tr.name();
              String methodName = loc.method() != null ? loc.method().name() : ""; // NOI18N
              String lineNumber = ln == -1 ? "?" : "" + ln; // NOI18N
              makeCurrent(threadName, className, methodName, lineNumber, true, tr);
              operator.stopRequest();
            } catch (AbsentInformationException e) {
            }
          }
        });
    findSourceMER.enable();

    operator.resume();
    return;
  }