/// <summary>
        /// Handles the <see cref="IActiveConfiguredProjectSubscriptionService"/> callback on the active configured project's
        /// design-time build change notification service.
        /// </summary>
        private async Task ProjectBuildRuleBlock_ChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> e)
        {
            await ThreadingService.SwitchToUIThread();

            using (ProjectAsynchronousTasksService.LoadedProject())
            {
                foreach (var resolvedReferenceChange in e.Value.ProjectChanges.Values)
                {
                    if (!WatchedDesignTimeBuildRules.Contains(resolvedReferenceChange.After.RuleName))
                    {
                        // This is an evaluation rule.
                        continue;
                    }

                    foreach (string resolvedReferencePath in resolvedReferenceChange.Difference.AddedItems)
                    {
                        // If this is a resolved project reference, we need to treat it specially.
                        string originalItemSpec = resolvedReferenceChange.After.Items[resolvedReferencePath]["OriginalItemSpec"];
                        if (!string.IsNullOrEmpty(originalItemSpec))
                        {
                            if (e.Value.CurrentState[ProjectReference.SchemaName].Items.ContainsKey(originalItemSpec))
                            {
                                string originalFullPath = UnconfiguredProject.MakeRooted(originalItemSpec);
                                ProjectReferenceState state;
                                if (!_projectReferenceFullPaths.TryGetValue(originalFullPath, out state))
                                {
                                    _projectReferenceFullPaths = _projectReferenceFullPaths.Add(originalFullPath, state = new ProjectReferenceState());
                                }

                                state.ResolvedPath = resolvedReferencePath;

                                // Be careful to not add assembly references that overlap with project references.
                                if (state.AsProjectReference)
                                {
                                    continue;
                                }
                            }
                        }

                        Marshal.ThrowExceptionForHR(_intellisenseEngine.AddAssemblyReference(resolvedReferencePath));
                    }

                    foreach (string resolvedReferencePath in resolvedReferenceChange.Difference.RemovedItems)
                    {
                        Marshal.ThrowExceptionForHR(_intellisenseEngine.RemoveAssemblyReference(resolvedReferencePath));
                    }

                    Marshal.ThrowExceptionForHR(_intellisenseEngine.StartIntellisenseEngine());
                }
            }
        }
        /// <summary>
        /// Invoked when the UnconfiguredProject is first loaded to initialize language services.
        /// </summary>
        protected async Task InitializeAsync()
        {
            ProjectAsynchronousTasksService.UnloadCancellationToken.ThrowIfCancellationRequested();

            // Don't start until the project has been loaded as far as the IDE is concerned.
#pragma warning disable CA2007 // Do not directly await a Task (see https://github.com/dotnet/roslyn/issues/6770)
            await ProjectAsyncLoadDashboard.ProjectLoadedInHost;
#pragma warning restore CA2007 // Do not directly await a Task

            // Defer this work until VS has idle time.  Otherwise we'll block the UI thread to load the MSBuild project evaluation
            // during synchronous project load time.
            await ThreadHelper.JoinableTaskFactory.RunAsync(
                VsTaskRunContext.UIThreadBackgroundPriority,
                async delegate
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                await Task.Yield();

                using (ProjectAsynchronousTasksService.LoadedProject())
                {
                    // hack to ensure webproj package is properly sited, by forcing it to load with a QueryService call for
                    // one of the services it implements.
                    var tmpObj = Package.GetGlobalService(typeof(SWebApplicationCtxSvc)) as IWebApplicationCtxSvc;
                    Report.IfNotPresent(tmpObj);
                    if (tmpObj == null)
                    {
                        return;
                    }

                    // Create the Intellisense engine for C#
                    var registry = ServiceProvider.GetService(typeof(SLocalRegistry)) as ILocalRegistry3;
                    Assumes.Present(registry);
                    IntPtr pIntellisenseEngine = IntPtr.Zero;
                    try
                    {
                        Marshal.ThrowExceptionForHR(registry.CreateInstance(
                                                        IntelliSenseProviderGuid,
                                                        null,
                                                        typeof(IVsIntellisenseProject).GUID,
                                                        (uint)CLSCTX.CLSCTX_INPROC_SERVER,
                                                        out pIntellisenseEngine));

                        _intellisenseEngine = Marshal.GetObjectForIUnknown(pIntellisenseEngine) as IVsIntellisenseProject;
                    }
                    finally
                    {
                        if (pIntellisenseEngine != IntPtr.Zero)
                        {
                            Marshal.Release(pIntellisenseEngine);
                        }
                    }

                    Marshal.ThrowExceptionForHR(_intellisenseEngine.Init(this));
#pragma warning disable CA2007 // Do not directly await a Task (see https://github.com/dotnet/roslyn/issues/6770)
                    await LanguageServiceRegister.RegisterProjectAsync(this);
#pragma warning restore CA2007 // Do not directly await a Task
                }
            });

            // The rest of this can execute on a worker thread.
            await TaskScheduler.Default;
            using (ProjectAsynchronousTasksService.LoadedProject())
            {
                var designTimeBuildBlock = new ActionBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> >(
                    ProjectBuildRuleBlock_ChangedAsync);
                _designTimeBuildSubscriptionLink = ActiveConfiguredProjectSubscriptionService.JointRuleSource.SourceBlock.LinkTo(
                    designTimeBuildBlock,
                    ruleNames: WatchedEvaluationRules.Union(WatchedDesignTimeBuildRules));

                var evaluationBlock = new ActionBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> >(
                    ProjectRuleBlock_ChangedAsync);
                _evaluationSubscriptionLink = ActiveConfiguredProjectSubscriptionService.JointRuleSource.SourceBlock.LinkTo(
                    evaluationBlock,
                    ruleNames: WatchedEvaluationRules);
            }
        }