private void AsyncBindImpl()
        {
            UnbindAllBreakpoints(enum_BP_UNBOUND_REASON.BPUR_BREAKPOINT_REBIND);

            string fileName = RequestLocation.DocumentPosition.GetFileName();
            int lineNumber = RequestLocation.DocumentPosition.GetRange().iStartLine + 1;
            bool errorNotFirstOnLine = false;

            List<JavaDebugBoundBreakpoint> boundBreakpoints = new List<JavaDebugBoundBreakpoint>();
            IEnumerable<JavaDebugProgram> programs = DebugEngine.Programs.ToArray();
            foreach (var program in programs)
            {
                if (!program.IsLoaded)
                    continue;

                IVirtualMachine virtualMachine = program.VirtualMachine;
                ReadOnlyCollection<IReferenceType> classes = virtualMachine.GetAllClasses();
                foreach (var @class in classes)
                {
                    if ([email protected]())
                        continue;

                    ReadOnlyCollection<ILocation> locations = @class.GetLocationsOfLine(@class.GetDefaultStratum(), Path.GetFileName(fileName), lineNumber);
                    ILocation bindLocation = locations.OrderBy(i => i.GetCodeIndex()).FirstOrDefault();
                    if (bindLocation != null)
                    {
                        if (!IsFirstOnLine())
                        {
                            errorNotFirstOnLine = true;
                            break;
                        }

                        IEventRequestManager eventRequestManager = virtualMachine.GetEventRequestManager();
                        IBreakpointRequest eventRequest = eventRequestManager.CreateBreakpointRequest(bindLocation);
                        eventRequest.SuspendPolicy = SuspendPolicy.All;

                        JavaDebugCodeContext codeContext = new JavaDebugCodeContext(program, bindLocation);
                        BreakpointResolutionLocationCode location = new BreakpointResolutionLocationCode(codeContext);
                        DebugBreakpointResolution resolution = new DebugBreakpointResolution(program, null, enum_BP_TYPE.BPT_CODE, location);
                        JavaDebugBoundBreakpoint boundBreakpoint = new JavaDebugBoundBreakpoint(this, program, eventRequest, resolution);
                        if (!_disabled)
                            boundBreakpoint.Enable(1);

                        boundBreakpoints.Add(boundBreakpoint);
                    }
                }

                if (errorNotFirstOnLine)
                    break;
            }

            _boundBreakpoints.AddRange(boundBreakpoints);

            if (_boundBreakpoints.Count == 0)
            {
                foreach (var program in programs)
                {
                    JavaDebugThread thread = null;
                    IDebugCodeContext2 codeContext = new DebugDocumentCodeContext(RequestLocation.DocumentPosition);
                    BreakpointResolutionLocation location = new BreakpointResolutionLocationCode(codeContext);
                    string message = "The class is not yet loaded, or the location is not present in the debug symbols for this document.";
                    if (errorNotFirstOnLine)
                        message = "Only breakpoints on the first statement on a line can be bound at this time.";

                    DebugErrorBreakpointResolution resolution = new DebugErrorBreakpointResolution(program, thread, enum_BP_TYPE.BPT_CODE, location, enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, message);
                    DebugErrorBreakpoint errorBreakpoint = new DebugErrorBreakpoint(this, resolution);
                    _errorBreakpoints.Add(errorBreakpoint);

                    DebugEvent debugEvent = new DebugBreakpointErrorEvent(enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS, errorBreakpoint);
                    program.Callback.Event(DebugEngine, program.Process, program, null, debugEvent);
                }
            }

            foreach (var group in boundBreakpoints.GroupBy(i => i.Program))
            {
                DebugEvent debugEvent = new DebugBreakpointBoundEvent(enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS, this, new EnumDebugBoundBreakpoints(group));
                group.Key.Callback.Event(DebugEngine, group.Key.Process, group.Key, null, debugEvent);
            }
        }
        /// <summary>
        /// Determines whether this pending breakpoint can bind to a code location.
        /// </summary>
        /// <param name="ppErrorEnum">
        /// [out] Returns an IEnumDebugErrorBreakpoints2 object that contains a list of IDebugErrorBreakpoint2
        /// objects if there could be errors.
        /// </param>
        /// <returns>
        /// If successful, returns S_OK. Returns S_FALSE if the breakpoint cannot bind, in which case the errors
        /// are returned by the ppErrorEnum parameter. Otherwise, returns an error code. Returns E_BP_DELETED if
        /// the breakpoint has been deleted.
        /// </returns>
        /// <remarks>
        /// This method is called to determine what would happen if this pending breakpoint was bound. Call the
        /// IDebugPendingBreakpoint2::Bind method to actually bind the pending breakpoint.
        /// </remarks>
        public int CanBind(out IEnumDebugErrorBreakpoints2 ppErrorEnum)
        {
            if (_deleted)
            {
                ppErrorEnum = null;
                return AD7Constants.E_BP_DELETED;
            }

            string fileName = RequestLocation.DocumentPosition.GetFileName();
            int lineNumber = RequestLocation.DocumentPosition.GetRange().iStartLine + 1;
            bool errorNotFirstOnLine = false;

            IEnumerable<JavaDebugProgram> programs = DebugEngine.Programs.ToArray();
            foreach (var program in programs)
            {
                if (!program.IsLoaded)
                    continue;

                IVirtualMachine virtualMachine = program.VirtualMachine;
                ReadOnlyCollection<IReferenceType> classes = virtualMachine.GetAllClasses();
                foreach (var @class in classes)
                {
                    if ([email protected]())
                        continue;

                    ReadOnlyCollection<ILocation> locations = @class.GetLocationsOfLine(@class.GetDefaultStratum(), Path.GetFileName(fileName), lineNumber);
                    ILocation bindLocation = locations.OrderBy(i => i.GetCodeIndex()).FirstOrDefault();
                    if (bindLocation != null)
                    {
                        if (IsFirstOnLine())
                        {
                            ppErrorEnum = null;
                            return VSConstants.S_OK;
                        }
                        else
                        {
                            errorNotFirstOnLine = true;
                            break;
                        }
                    }
                }

                if (errorNotFirstOnLine)
                    break;
            }

            foreach (var program in programs)
            {
                JavaDebugThread thread = null;
                IDebugCodeContext2 codeContext = new DebugDocumentCodeContext(RequestLocation.DocumentPosition);
                BreakpointResolutionLocation location = new BreakpointResolutionLocationCode(codeContext);
                string message = "The class is not yet loaded, or the location is not present in the debug symbols for this document.";
                if (errorNotFirstOnLine)
                    message = "Only breakpoints on the first statement on a line can be bound at this time.";

                DebugErrorBreakpointResolution resolution = new DebugErrorBreakpointResolution(program, thread, enum_BP_TYPE.BPT_CODE, location, enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, message);
                DebugErrorBreakpoint errorBreakpoint = new DebugErrorBreakpoint(this, resolution);
                _errorBreakpoints.Add(errorBreakpoint);

                DebugEvent debugEvent = new DebugBreakpointErrorEvent(enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS, errorBreakpoint);
                program.Callback.Event(DebugEngine, program.Process, program, null, debugEvent);
            }

            if (_errorBreakpoints.Count == 0)
            {
                JavaDebugProgram program = null;
                JavaDebugThread thread = null;
                IDebugCodeContext2 codeContext = new DebugDocumentCodeContext(RequestLocation.DocumentPosition);
                BreakpointResolutionLocation location = new BreakpointResolutionLocationCode(codeContext);
                string message = "The binding process is not yet implemented.";

                DebugErrorBreakpointResolution resolution = new DebugErrorBreakpointResolution(program, thread, enum_BP_TYPE.BPT_CODE, location, enum_BP_ERROR_TYPE.BPET_GENERAL_ERROR, message);
                DebugErrorBreakpoint errorBreakpoint = new DebugErrorBreakpoint(this, resolution);
                _errorBreakpoints.Add(errorBreakpoint);
            }

            ppErrorEnum = new EnumDebugErrorBreakpoints(_errorBreakpoints);
            return VSConstants.S_FALSE;
        }
        public void Bind(JavaDebugProgram program, JavaDebugThread thread, IReferenceType type, IEnumerable<string> sourcePaths)
        {
            IVirtualMachine virtualMachine = program.VirtualMachine;

            IEnumerable<string> validPaths = sourcePaths.Where(i => string.Equals(Path.GetFileName(RequestLocation.DocumentPosition.GetFileName()), Path.GetFileName(i), StringComparison.OrdinalIgnoreCase));

            List<JavaDebugBoundBreakpoint> boundBreakpoints = new List<JavaDebugBoundBreakpoint>();
            List<IDebugErrorBreakpoint2> errorBreakpoints = new List<IDebugErrorBreakpoint2>();
            foreach (var path in validPaths)
            {
                TextSpan range = RequestLocation.DocumentPosition.GetRange();
                try
                {
                    ReadOnlyCollection<ILocation> locations = type.GetLocationsOfLine(range.iStartLine + 1);
                    ILocation bindLocation = locations.OrderBy(i => i.GetCodeIndex()).FirstOrDefault();
                    if (bindLocation != null && IsFirstOnLine())
                    {
                        IEventRequestManager eventRequestManager = virtualMachine.GetEventRequestManager();

                        IBreakpointRequest eventRequest = eventRequestManager.CreateBreakpointRequest(bindLocation);
                        eventRequest.SuspendPolicy = SuspendPolicy.All;

                        JavaDebugCodeContext codeContext = new JavaDebugCodeContext(program, bindLocation);
                        BreakpointResolutionLocationCode location = new BreakpointResolutionLocationCode(codeContext);
                        DebugBreakpointResolution resolution = new DebugBreakpointResolution(program, thread, enum_BP_TYPE.BPT_CODE, location);
                        JavaDebugBoundBreakpoint boundBreakpoint = new JavaDebugBoundBreakpoint(this, program, eventRequest, resolution);
                        if (!_disabled)
                            boundBreakpoint.Enable(1);

                        boundBreakpoints.Add(boundBreakpoint);
                    }
                }
                catch (MissingInformationException)
                {
                }
            }

            _boundBreakpoints.AddRange(boundBreakpoints);
            if (boundBreakpoints.Count > 0)
            {
                _errorBreakpoints.Clear();
            }

            _errorBreakpoints.AddRange(errorBreakpoints);

            if (boundBreakpoints.Count > 0)
            {
                DebugEvent debugEvent = new DebugBreakpointBoundEvent(enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS, this, new EnumDebugBoundBreakpoints(boundBreakpoints));
                program.Callback.Event(DebugEngine, program.Process, program, null, debugEvent);
            }

            foreach (var errorBreakpoint in errorBreakpoints)
            {
                DebugEvent debugEvent = new DebugBreakpointErrorEvent(enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS, errorBreakpoint);
                program.Callback.Event(DebugEngine, program.Process, program, null, debugEvent);
            }
        }