/// <returns>
        /// True: if a failure notification was displayed or the user did not want to proceed in a best effort scenario.
        ///       Extract Method does not proceed further and is done.
        /// False: the user proceeded to a best effort scenario.
        /// </returns>
        private async Task <bool> TryNotifyFailureToUserAsync(
            Document document, ExtractMethodResult result, CancellationToken cancellationToken)
        {
            // We are about to show a modal UI dialog so we should take over the command execution
            // wait context. That means the command system won't attempt to show its own wait dialog
            // and also will take it into consideration when measuring command handling duration.
            var project             = document.Project;
            var solution            = project.Solution;
            var notificationService = solution.Workspace.Services.GetService <INotificationService>();

            // see whether we will allow best effort extraction and if it is possible.
            if (!_globalOptions.GetOption(ExtractMethodPresentationOptionsStorage.AllowBestEffort, document.Project.Language) ||
                !result.Status.HasBestEffort() ||
                result.DocumentWithoutFinalFormatting == null)
            {
                if (notificationService != null)
                {
                    await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

                    notificationService.SendNotification(
                        EditorFeaturesResources.Extract_method_encountered_the_following_issues + Environment.NewLine +
                        string.Join("", result.Reasons.Select(r => Environment.NewLine + "  " + r)),
                        title: EditorFeaturesResources.Extract_Method,
                        severity: NotificationSeverity.Error);
                }

                return(true);
            }

            // okay, best effort is turned on, let user know it is an best effort
            if (notificationService != null)
            {
                await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

                if (!notificationService.ConfirmMessageBox(
                        EditorFeaturesResources.Extract_method_encountered_the_following_issues + Environment.NewLine +
                        string.Join("", result.Reasons.Select(r => Environment.NewLine + "  " + r)) + Environment.NewLine + Environment.NewLine +
                        EditorFeaturesResources.Do_you_still_want_to_proceed_This_may_produce_broken_code,
                        title: EditorFeaturesResources.Extract_Method,
                        severity: NotificationSeverity.Warning))
                {
                    return(true);
                }
            }

            return(false);
        }
        private static ExtractMethodResult TryWithoutMakingValueTypesRef(
            Document document, NormalizedSnapshotSpanCollection spans, ExtractMethodResult result, ExtractMethodOptions options, CancellationToken cancellationToken)
        {
            if (options.DontPutOutOrRefOnStruct || !result.Reasons.IsSingle())
            {
                return(null);
            }

            var reason = result.Reasons.FirstOrDefault();
            var length = FeaturesResources.Asynchronous_method_cannot_have_ref_out_parameters_colon_bracket_0_bracket.IndexOf(':');

            if (reason != null && length > 0 && reason.IndexOf(FeaturesResources.Asynchronous_method_cannot_have_ref_out_parameters_colon_bracket_0_bracket.Substring(0, length), 0, length, StringComparison.Ordinal) >= 0)
            {
                var newResult = ExtractMethodService.ExtractMethodAsync(
                    document,
                    spans.Single().Span.ToTextSpan(),
                    localFunction: false,
                    options with {
                    DontPutOutOrRefOnStruct = true
                },