private static async Task <Checksum> ComputeSourceSymbolsChecksumAsync(ProjectState projectState, CancellationToken cancellationToken)
        {
            // The SymbolTree for source is built from the source-symbols from the project's compilation's
            // assembly.  Specifically, we only get the name, kind and parent/child relationship of all the
            // child symbols.  So we want to be able to reuse the index as long as none of these have
            // changed.  The only thing that can make those source-symbols change in that manner are if
            // the text of any document changes, or if options for the project change.  So we build our
            // checksum out of that data.
            var serializer            = projectState.LanguageServices.WorkspaceServices.GetService <ISerializerService>();
            var projectStateChecksums = await projectState.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false);

            // Order the documents by FilePath.  Default ordering in the RemoteWorkspace is
            // to be ordered by Guid (which is not consistent across VS sessions).
            var textChecksumsTasks = projectState.DocumentStates.OrderBy(d => d.Value.FilePath, StringComparer.Ordinal).Select(async d =>
            {
                var documentStateChecksum = await d.Value.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false);
                return(documentStateChecksum.Text);
            });

            var compilationOptionsChecksum = projectStateChecksums.CompilationOptions;
            var parseOptionsChecksum       = projectStateChecksums.ParseOptions;
            var textChecksums = await Task.WhenAll(textChecksumsTasks).ConfigureAwait(false);

            var allChecksums = ArrayBuilder <Checksum> .GetInstance();

            try
            {
                allChecksums.AddRange(textChecksums);
                allChecksums.Add(compilationOptionsChecksum);
                allChecksums.Add(parseOptionsChecksum);

                // Include serialization format version in our checksum.  That way if the
                // version ever changes, all persisted data won't match the current checksum
                // we expect, and we'll recompute things.
                allChecksums.Add(SerializationFormatChecksum);

                var checksum = Checksum.Create(WellKnownSynchronizationKind.SymbolTreeInfo, allChecksums);
                return(checksum);
            }
            finally
            {
                allChecksums.Free();
            }
        }