public void HandleThreadStart(JvmEventsService.JvmVirtualMachineRemoteHandle virtualMachine, JvmEventsService.JvmThreadRemoteHandle threadHandle)
            {
                int id = _nextThreadId++;

                //JvmToolsService.jvmtiError result = Program.ToolsService.SetTag(virtualMachine, threadHandle, id);
                //Contract.Assert(result == JvmToolsService.jvmtiError.None);

                //long tag;
                //result = Program.ToolsService.GetTag(out tag, virtualMachine, threadHandle);
                //Contract.Assert(result == JvmToolsService.jvmtiError.None);
                //Contract.Assert(tag == id);

                int hashCode;

                JvmToolsService.jvmtiError result = Program.ToolsService.GetObjectHashCode(out hashCode, virtualMachine, threadHandle);

                JavaDebugThread thread = new JavaDebugThread(Program, virtualMachine, threadHandle, id);

                Program._threads[hashCode] = thread;

                DebugEvent           @event = new DebugThreadCreateEvent(enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS);
                Guid                 guid   = typeof(IDebugThreadCreateEvent2).GUID;
                enum_EVENTATTRIBUTES attrib = @event.GetAttributes();

                Program.Callback.Event(Program.DebugEngine, Program.Process, Program, thread, @event, ref guid, (uint)attrib);
            }
        private void HandleThreadStart(object sender, ThreadEventArgs e)
        {
            if (e.SuspendPolicy == SuspendPolicy.All)
            {
                Interlocked.Increment(ref _suspended);
            }

            // nothing to do if this thread is already started
            JavaDebugThread thread;

            if (_threads.TryGetValue(e.Thread.GetUniqueId(), out thread))
            {
                switch (e.SuspendPolicy)
                {
                case SuspendPolicy.All:
                    Continue(thread);
                    break;

                case SuspendPolicy.EventThread:
                    Task.Factory.StartNew(e.Thread.Resume).HandleNonCriticalExceptions();
                    break;

                case SuspendPolicy.None:
                    break;
                }

                return;
            }

            thread = new JavaDebugThread(this, e.Thread, ThreadCategory.Worker);
            lock (this._threads)
            {
                this._threads.Add(e.Thread.GetUniqueId(), thread);
            }

            DebugEvent debugEvent = new DebugThreadCreateEvent(GetAttributesForEvent(e));

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

            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);
        }