public unsafe int BuildForEnc(object pUpdatePE)
        {
            try
            {
                log.Write("Applying changes to {0}", _vsProject.DisplayName);

                Debug.Assert(_encService.EditSession != null);
                Debug.Assert(!_encService.EditSession.StoppedAtException);

                // Non-debuggable project has no changes.
                Debug.Assert(IsDebuggable);

                if (_changesApplied)
                {
                    log.Write("Changes already applied to {0}, can't apply again", _vsProject.DisplayName);
                    throw ExceptionUtilities.Unreachable;
                }

                // The debugger always calls GetENCBuildState right before BuildForEnc.
                Debug.Assert(_projectBeingEmitted != null);
                Debug.Assert(_lastEditSessionSummary == GetProjectAnalysisSummary(_projectBeingEmitted));

                // The debugger should have called GetENCBuildState before calling BuildForEnc.
                // Unfortunately, there is no way how to tell the debugger that the changes were not significant,
                // so we'll to emit an empty delta. See bug 839558.
                Debug.Assert(_lastEditSessionSummary == ProjectAnalysisSummary.ValidInsignificantChanges ||
                             _lastEditSessionSummary == ProjectAnalysisSummary.ValidChanges);

                var updater = (IDebugUpdateInMemoryPE2)pUpdatePE;
                if (_committedBaseline == null)
                {
                    var hr = MarshalPdbReader(updater, out _pdbReaderObjAsStream);
                    if (hr != VSConstants.S_OK)
                    {
                        return hr;
                    }

                    _committedBaseline = EmitBaseline.CreateInitialBaseline(_metadata, GetBaselineEncDebugInfo);
                }

                // ISymUnmanagedReader can only be accessed from an MTA thread,
                // so dispatch it to one of thread pool threads, which are MTA.
                var emitTask = Task.Factory.SafeStartNew(EmitProjectDelta, CancellationToken.None, TaskScheduler.Default);

                Deltas delta;
                using (NonReentrantContext)
                {
                    delta = emitTask.Result;

                    if (delta == null)
                    {
                        // Non-fatal Watson has already been reported by the emit task
                        return VSConstants.E_FAIL;
                    }
                }

                var errorId = new EncErrorId(_encService.DebuggingSession, EditAndContinueDiagnosticUpdateSource.EmitErrorId);

                // Clear diagnostics, in case the project was built before and failed due to errors.
                _diagnosticProvider.ClearDiagnostics(errorId, _projectBeingEmitted.Solution, _vsProject.Id, _documentsWithEmitError);

                if (!delta.EmitResult.Success)
                {
                    var errors = delta.EmitResult.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error);
                    _documentsWithEmitError = _diagnosticProvider.ReportDiagnostics(errorId, _projectBeingEmitted.Solution, _vsProject.Id, errors);
                    _encService.EditSession.LogEmitProjectDeltaErrors(errors.Select(e => e.Id));

                    return VSConstants.E_FAIL;
                }

                _documentsWithEmitError = ImmutableArray<DocumentId>.Empty;
                SetFileUpdates(updater, delta.LineEdits);

                updater.SetDeltaIL(delta.IL.Value, (uint)delta.IL.Value.Length);
                updater.SetDeltaPdb(SymUnmanagedStreamFactory.CreateStream(delta.Pdb.Stream));
                updater.SetRemapMethods(delta.Pdb.UpdatedMethods, (uint)delta.Pdb.UpdatedMethods.Length);
                updater.SetDeltaMetadata(delta.Metadata.Bytes, (uint)delta.Metadata.Bytes.Length);

                _pendingBaseline = delta.EmitResult.Baseline;

#if DEBUG
                fixed (byte* deltaMetadataPtr = &delta.Metadata.Bytes[0])
                {
                    var reader = new System.Reflection.Metadata.MetadataReader(deltaMetadataPtr, delta.Metadata.Bytes.Length);
                    var moduleDef = reader.GetModuleDefinition();

                    log.DebugWrite("Gen {0}: MVID={1}, BaseId={2}, EncId={3}",
                        moduleDef.Generation,
                        reader.GetGuid(moduleDef.Mvid),
                        reader.GetGuid(moduleDef.BaseGenerationId),
                        reader.GetGuid(moduleDef.GenerationId));
                }
#endif

                return VSConstants.S_OK;
            }
            catch (Exception e) when (FatalError.ReportWithoutCrash(e))
            {
                return VSConstants.E_FAIL;
            }
        }
        public int StopDebuggingPE()
        {
            try
            {
                log.Write("Exit Debug Mode: project '{0}'", _vsProject.DisplayName);
                Debug.Assert(s_breakStateEnteredProjects.Count == 0);

                // Clear the solution stored while projects were entering break mode. 
                // It should be cleared as soon as all tracked projects enter the break mode 
                // but if the entering break mode fails for some projects we should avoid leaking the solution.
                Debug.Assert(s_breakStateEntrySolution == null);
                s_breakStateEntrySolution = null;

                // EnC service is global (per solution), but the debugger calls this for each project.
                // Avoid ending the debug session if it has already been ended.
                if (_encService.DebuggingSession != null)
                {
                    _encService.OnBeforeDebuggingStateChanged(DebuggingState.Run, DebuggingState.Design);

                    _encService.EndDebuggingSession();
                    LogEncSession();

                    s_encDebuggingSessionInfo = null;
                    s_readOnlyDocumentTracker.Dispose();
                    s_readOnlyDocumentTracker = null;
                }

                if (_metadata != null)
                {
                    _metadata.Dispose();
                    _metadata = null;

                    s_debugStateProjectCount--;
                }
                else
                {
                    // an error might have been reported:
                    var errorId = new EncErrorId(_encService.DebuggingSession, EditAndContinueDiagnosticUpdateSource.DebuggerErrorId);
                    _diagnosticProvider.ClearDiagnostics(errorId, _vsProject.Workspace.CurrentSolution, _vsProject.Id, documentIdOpt: null);
                }

                _activeMethods = null;
                _exceptionRegions = null;
                _committedBaseline = null;
                _activeStatementIds = null;
                _projectBeingEmitted = null;

                Debug.Assert((_pdbReaderObjAsStream == IntPtr.Zero) || (_pdbReader == null));

                if (_pdbReader != null)
                {
                    Marshal.ReleaseComObject(_pdbReader);
                    _pdbReader = null;
                }

                // The HResult is ignored by the debugger.
                return VSConstants.S_OK;
            }
            catch (Exception e) when (FatalError.ReportWithoutCrash(e))
            {
                return VSConstants.E_FAIL;
            }
        }