private void HandleClassPrepare(object sender, ClassPrepareEventArgs e)
        {
            if (e.SuspendPolicy == SuspendPolicy.All)
            {
                Interlocked.Increment(ref _suspended);
            }

            JavaDebugThread thread;

            lock (_threads)
            {
                this._threads.TryGetValue(e.Thread.GetUniqueId(), out thread);
            }

            try
            {
                ReadOnlyCollection <string> sourceFiles = e.Type.GetSourcePaths(e.Type.GetDefaultStratum());
                DebugEngine.BindVirtualizedBreakpoints(this, thread, e.Type, sourceFiles);
            }
            catch (MissingInformationException)
            {
                // Can't bind debug information for classes that don't contain debug information
            }

            // The format of the message created by the .NET debugger is this:
            // 'devenv.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualStudio.Windows.Forms\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Windows.Forms.dll'
            string     message     = string.Format("'{0}' ({1}): Loaded '{2}'\n", Process.GetName(enum_GETNAME_TYPE.GN_BASENAME), Java.Constants.JavaLanguageName, e.Type.GetName());
            DebugEvent outputEvent = new DebugOutputStringEvent(message);

            SetEventProperties(outputEvent, e, true);
            Callback.Event(DebugEngine, Process, this, thread, outputEvent);

            ManualContinueFromEvent(e);
        }
        private void HandleVirtualMachineStart(object sender, ThreadEventArgs e)
        {
            if (e.SuspendPolicy == SuspendPolicy.All)
            {
                Interlocked.Increment(ref _suspended);
            }

            var requestManager = _virtualMachine.GetEventRequestManager();

            var threadStartRequest = requestManager.CreateThreadStartRequest();

            threadStartRequest.SuspendPolicy = SuspendPolicy.EventThread;
            threadStartRequest.IsEnabled     = true;

            var threadDeathRequest = requestManager.CreateThreadDeathRequest();

            threadDeathRequest.SuspendPolicy = SuspendPolicy.EventThread;
            threadDeathRequest.IsEnabled     = true;

            var classPrepareRequest = requestManager.CreateClassPrepareRequest();

            classPrepareRequest.SuspendPolicy = SuspendPolicy.EventThread;
            classPrepareRequest.IsEnabled     = true;

            var exceptionRequest = requestManager.CreateExceptionRequest(null, true, true);

            exceptionRequest.SuspendPolicy = SuspendPolicy.All;
            exceptionRequest.IsEnabled     = true;

            var virtualMachineDeathRequest = requestManager.CreateVirtualMachineDeathRequest();

            virtualMachineDeathRequest.SuspendPolicy = SuspendPolicy.All;
            virtualMachineDeathRequest.IsEnabled     = true;

            DebugEvent debugEvent = new DebugLoadCompleteEvent(enum_EVENTATTRIBUTES.EVENT_ASYNC_STOP);

            SetEventProperties(debugEvent, e, false);
            Callback.Event(DebugEngine, Process, this, null, debugEvent);

            _isLoaded = true;

            JavaDebugThread mainThread = null;
            ReadOnlyCollection <IThreadReference> threads = VirtualMachine.GetAllThreads();

            for (int i = 0; i < threads.Count; i++)
            {
                bool            isMainThread = threads[i].Equals(e.Thread);
                JavaDebugThread thread       = new JavaDebugThread(this, threads[i], isMainThread ? ThreadCategory.Main : ThreadCategory.Worker);
                if (isMainThread)
                {
                    mainThread = thread;
                }

                lock (this._threads)
                {
                    this._threads.Add(threads[i].GetUniqueId(), thread);
                }

                debugEvent = new DebugThreadCreateEvent(enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS);
                Callback.Event(DebugEngine, Process, this, thread, debugEvent);
            }

            if (DebugEngine.VirtualizedBreakpoints.Count > 0)
            {
                ReadOnlyCollection <IReferenceType> classes = VirtualMachine.GetAllClasses();
                foreach (var type in classes)
                {
                    if (!type.GetIsPrepared())
                    {
                        continue;
                    }

                    ReadOnlyCollection <string> sourceFiles = type.GetSourcePaths(type.GetDefaultStratum());
                    DebugEngine.BindVirtualizedBreakpoints(this, mainThread, type, sourceFiles);
                }
            }

            JavaDebugThread thread2;

            lock (_threads)
            {
                this._threads.TryGetValue(e.Thread.GetUniqueId(), out thread2);
            }

            debugEvent = new DebugEntryPointEvent(GetAttributesForEvent(e));
            SetEventProperties(debugEvent, e, false);
            Callback.Event(DebugEngine, Process, this, thread2, debugEvent);
        }