public async Task AnalyzeDocumentAsync(Document document, SyntaxNode bodyOpt, CancellationToken cancellationToken)
            {
                try
                {
                    // do nothing if this document is not currently open.
                    // to prevent perf from getting too poor for large projects, only examine open documents.
                    if (!document.IsOpen())
                    {
                        return;
                    }

                    // Only analyzing C# for now
                    if (document.Project.Language != LanguageNames.CSharp)
                    {
                        return;
                    }

                    List<CompilationErrorDetails> errorDetails = await _errorDetailDiscoverer.GetCompilationErrorDetails(document, bodyOpt, cancellationToken).ConfigureAwait(false);

                    var errorsToReport = _errorDetailCache.GetErrorsToReportAndRecordErrors(document.Id, errorDetails);
                    if (errorsToReport != null)
                    {
                        using (var hashProvider = new SHA256CryptoServiceProvider())
                        {
                            foreach (CompilationErrorDetails errorDetail in errorsToReport)
                            {
                                var telemetryEvent = TelemetryHelper.TelemetryService.CreateEvent(TelemetryEventPath);
                                telemetryEvent.SetStringProperty(TelemetryErrorId, errorDetail.ErrorId);

                                string projectGuid = _projectGuidCache.GetProjectGuidFromProjectPath(document.Project.FilePath);
                                telemetryEvent.SetStringProperty(TelemetryProjectGuid, string.IsNullOrEmpty(projectGuid) ? UnspecifiedProjectGuid : projectGuid.ToString());

                                if (!string.IsNullOrEmpty(errorDetail.UnresolvedMemberName))
                                {
                                    telemetryEvent.SetStringProperty(TelemetryUnresolvedMemberName, GetHashedString(errorDetail.UnresolvedMemberName, hashProvider));
                                }

                                if (!string.IsNullOrEmpty(errorDetail.LeftExpressionDocId))
                                {
                                    telemetryEvent.SetStringProperty(TelemetryLeftExpressionDocId, GetHashedString(errorDetail.LeftExpressionDocId, hashProvider));
                                }

                                if (!IsArrayNullOrEmpty(errorDetail.LeftExpressionBaseTypeDocIds))
                                {
                                    string telemetryBaseTypes = string.Join(";", errorDetail.LeftExpressionBaseTypeDocIds.Select(docId => GetHashedString(docId, hashProvider)));
                                    telemetryEvent.SetStringProperty(TelemetryBaseTypes, telemetryBaseTypes);
                                }

                                if (!IsArrayNullOrEmpty(errorDetail.GenericArguments))
                                {
                                    string telemetryGenericArguments = string.Join(";", errorDetail.GenericArguments.Select(docId => GetHashedString(docId, hashProvider)));
                                    telemetryEvent.SetStringProperty(TelemetryGenericArguments, telemetryGenericArguments);
                                }

                                if (!string.IsNullOrEmpty(errorDetail.MethodName))
                                {
                                    telemetryEvent.SetStringProperty(TelemetryMethodName, GetHashedString(errorDetail.MethodName, hashProvider));
                                }

                                if (!IsArrayNullOrEmpty(errorDetail.ArgumentTypes))
                                {
                                    string telemetryMisMatchedArgumentTypeDocIds = string.Join(";", errorDetail.ArgumentTypes.Select(docId => GetHashedString(docId, hashProvider)));
                                    telemetryEvent.SetStringProperty(TelemetryMismatchedArgumentTypeDocIds, telemetryMisMatchedArgumentTypeDocIds);
                                }

                                TelemetryHelper.DefaultTelemetrySession.PostEvent(telemetryEvent);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    // The telemetry service itself can throw.
                    // So, to be very careful, put this in a try/catch too.
                    try
                    {
                        var exceptionEvent = TelemetryHelper.TelemetryService.CreateEvent(TelemetryExceptionEventPath);
                        exceptionEvent.SetStringProperty("Type", e.GetTypeDisplayName());
                        exceptionEvent.SetStringProperty("Message", e.Message);
                        exceptionEvent.SetStringProperty("StackTrace", e.StackTrace);
                        TelemetryHelper.DefaultTelemetrySession.PostEvent(exceptionEvent);
                    }
                    catch
                    {
                    }
                }
            }
            private static string GetHashedString(string unhashedString, SHA256CryptoServiceProvider hashProvider)
            {
                // The point of hashing here is to obscure customer data.  
                // So, if we get any empty values (noone knows why this happens for certain... has only been observed in dumps)
                // an empty string is fine.  It will appear as an extra semicolon in the MD value.
                if (string.IsNullOrEmpty(unhashedString))
                {
                    return string.Empty;
                }

                if (TelemetryHelper.DefaultTelemetrySession.CanCollectPrivateInformation())
                {
                    return unhashedString;
                }

                byte[] theHash = hashProvider.ComputeHash(Encoding.UTF8.GetBytes(unhashedString));
                StringBuilder sb = new StringBuilder(theHash.Length);
                for (int i = 0; i < theHash.Length; i++)
                {
                    sb.AppendFormat("{0:X}", theHash[i]);
                }

                return sb.ToString();
            }