/// <summary>
            /// Return all no location diagnostics for the given project stored in this state
            /// </summary>
            public async Task <DiagnosticAnalysisResult> GetProjectAnalysisDataAsync(
                IPersistentStorageService persistentService,
                Project project,
                bool avoidLoadingData,
                CancellationToken cancellationToken
                )
            {
                // make a copy of last result.
                var lastResult = _lastResult;

                Contract.ThrowIfFalse(lastResult.ProjectId == project.Id);

                if (lastResult.IsDefault)
                {
                    return(await LoadInitialProjectAnalysisDataAsync(
                               persistentService,
                               project,
                               cancellationToken
                               )
                           .ConfigureAwait(false));
                }

                var version = await GetDiagnosticVersionAsync(project, cancellationToken)
                              .ConfigureAwait(false);

                if (avoidLoadingData && lastResult.Version != version)
                {
                    return(lastResult);
                }

                // if given document doesnt have any diagnostics, return empty.
                if (lastResult.IsEmpty)
                {
                    return(DiagnosticAnalysisResult.CreateEmpty(
                               lastResult.ProjectId,
                               lastResult.Version
                               ));
                }

                // loading data can be cancelled any time.
                var serializer = new DiagnosticDataSerializer(
                    _owner.AnalyzerVersion,
                    lastResult.Version
                    );
                var builder = new Builder(project, lastResult.Version);

                if (
                    !await TryDeserializeProjectDiagnosticsAsync(
                        persistentService,
                        serializer,
                        project,
                        builder,
                        cancellationToken
                        )
                    .ConfigureAwait(false)
                    )
                {
                    // this can happen if SaveAsync is not yet called but active file merge happened. one of case is if user did build before the very first
                    // analysis happened.
                }

                return(builder.ToResult());
            }
            /// <summary>
            /// Return all diagnostics for the given project stored in this state
            /// </summary>
            public async Task <DiagnosticAnalysisResult> GetAnalysisDataAsync(
                IPersistentStorageService persistentService,
                Project project,
                bool avoidLoadingData,
                CancellationToken cancellationToken
                )
            {
                // make a copy of last result.
                var lastResult = _lastResult;

                Contract.ThrowIfFalse(lastResult.ProjectId == project.Id);

                if (lastResult.IsDefault)
                {
                    return(await LoadInitialAnalysisDataAsync(
                               persistentService,
                               project,
                               cancellationToken
                               )
                           .ConfigureAwait(false));
                }

                RoslynDebug.Assert(lastResult.DocumentIds != null);

                // PERF: avoid loading data if version is not right one.
                // avoid loading data flag is there as a strictly perf optimization.
                var version = await GetDiagnosticVersionAsync(project, cancellationToken)
                              .ConfigureAwait(false);

                if (avoidLoadingData && lastResult.Version != version)
                {
                    return(lastResult);
                }

                // if given project doesnt have any diagnostics, return empty.
                if (lastResult.IsEmpty)
                {
                    return(DiagnosticAnalysisResult.CreateEmpty(
                               lastResult.ProjectId,
                               lastResult.Version
                               ));
                }

                // loading data can be cancelled any time.
                var serializer = new DiagnosticDataSerializer(
                    _owner.AnalyzerVersion,
                    lastResult.Version
                    );
                var builder = new Builder(project, lastResult.Version, lastResult.DocumentIds);

                foreach (var documentId in lastResult.DocumentIds)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var document = project.GetDocument(documentId);
                    if (document == null)
                    {
                        continue;
                    }

                    if (
                        !await TryDeserializeDocumentDiagnosticsAsync(
                            persistentService,
                            serializer,
                            document,
                            builder,
                            cancellationToken
                            )
                        .ConfigureAwait(false)
                        )
                    {
                        Debug.Assert(lastResult.Version == VersionStamp.Default);
                        // this can happen if we merged back active file diagnostics back to project state but
                        // project state didn't have diagnostics for the file yet. (since project state was staled)
                        continue;
                    }
                }

                if (
                    !await TryDeserializeProjectDiagnosticsAsync(
                        persistentService,
                        serializer,
                        project,
                        builder,
                        cancellationToken
                        )
                    .ConfigureAwait(false)
                    )
                {
                    // this can happen if SaveAsync is not yet called but active file merge happened. one of case is if user did build before the very first
                    // analysis happened.
                }

                return(builder.ToResult());
            }
            /// <summary>
            /// Return all diagnostics for the given document stored in this state including non local diagnostics for this document
            /// </summary>
            public async Task <DiagnosticAnalysisResult> GetAnalysisDataAsync(
                IPersistentStorageService persistentService,
                TextDocument document,
                bool avoidLoadingData,
                CancellationToken cancellationToken
                )
            {
                // make a copy of last result.
                var lastResult = _lastResult;

                Contract.ThrowIfFalse(lastResult.ProjectId == document.Project.Id);

                if (lastResult.IsDefault)
                {
                    return(await LoadInitialAnalysisDataAsync(
                               persistentService,
                               document,
                               cancellationToken
                               )
                           .ConfigureAwait(false));
                }

                var version = await GetDiagnosticVersionAsync(document.Project, cancellationToken)
                              .ConfigureAwait(false);

                if (avoidLoadingData && lastResult.Version != version)
                {
                    return(lastResult);
                }

                // if given document doesnt have any diagnostics, return empty.
                if (IsEmpty(lastResult, document.Id))
                {
                    return(DiagnosticAnalysisResult.CreateEmpty(
                               lastResult.ProjectId,
                               lastResult.Version
                               ));
                }

                // loading data can be cancelled any time.
                var serializer = new DiagnosticDataSerializer(
                    _owner.AnalyzerVersion,
                    lastResult.Version
                    );
                var builder = new Builder(document.Project, lastResult.Version);

                if (
                    !await TryDeserializeDocumentDiagnosticsAsync(
                        persistentService,
                        serializer,
                        document,
                        builder,
                        cancellationToken
                        )
                    .ConfigureAwait(false)
                    )
                {
                    Debug.Assert(lastResult.Version == VersionStamp.Default);
                    // this can happen if we merged back active file diagnostics back to project state but
                    // project state didn't have diagnostics for the file yet. (since project state was staled)
                }

                return(builder.ToResult());
            }