public async Task <ExtractClassOptions?> GetExtractClassOptionsAsync(Document document, INamedTypeSymbol selectedType, ISymbol?selectedMember)
        {
            var notificationService = document.Project.Solution.Workspace.Services.GetRequiredService <INotificationService>();

            var membersInType = selectedType.GetMembers().
                                WhereAsArray(member => MemberAndDestinationValidator.IsMemberValid(member));

            var memberViewModels = membersInType
                                   .SelectAsArray(member =>
                                                  new PullMemberUpSymbolViewModel(member, _glyphService)
            {
                // The member user selected will be checked at the beginning.
                IsChecked               = SymbolEquivalenceComparer.Instance.Equals(selectedMember, member),
                MakeAbstract            = false,
                IsMakeAbstractCheckable = !member.IsKind(SymbolKind.Field) && !member.IsAbstract,
                IsCheckable             = true
            });

            using var cancellationTokenSource = new CancellationTokenSource();
            var memberToDependentsMap = SymbolDependentsBuilder.FindMemberToDependentsMap(membersInType, document.Project, cancellationTokenSource.Token);

            var conflictingTypeNames = selectedType.ContainingNamespace.GetAllTypes(cancellationTokenSource.Token).Select(t => t.Name);
            var candidateName        = selectedType.Name + "Base";
            var defaultTypeName      = NameGenerator.GenerateUniqueName(candidateName, name => !conflictingTypeNames.Contains(name));

            var containingNamespaceDisplay = selectedType.ContainingNamespace.IsGlobalNamespace
                ? string.Empty
                : selectedType.ContainingNamespace.ToDisplayString();

            var generatedNameTypeParameterSuffix = ExtractTypeHelpers.GetTypeParameterSuffix(document, selectedType, membersInType);

            var viewModel = new ExtractClassViewModel(
                _waitIndicator,
                notificationService,
                memberViewModels,
                memberToDependentsMap,
                defaultTypeName,
                containingNamespaceDisplay,
                document.Project.Language,
                generatedNameTypeParameterSuffix,
                conflictingTypeNames.ToImmutableArray(),
                document.GetRequiredLanguageService <ISyntaxFactsService>());

            await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync();

            var dialog = new ExtractClassDialog(viewModel);

            var result = dialog.ShowModal();

            if (result.GetValueOrDefault())
            {
                return(new ExtractClassOptions(
                           viewModel.DestinationViewModel.FileName,
                           viewModel.DestinationViewModel.TypeName,
                           viewModel.DestinationViewModel.Destination == CommonControls.NewTypeDestination.CurrentFile,
                           viewModel.MemberSelectionViewModel.CheckedMembers.SelectAsArray(m => new ExtractClassMemberAnalysisResult(m.Symbol, m.MakeAbstract))));
            }

            return(null);
        }
        // internal for testing purposes, get the view model
        internal static MoveStaticMembersDialogViewModel GetViewModel(
            Document document,
            INamedTypeSymbol selectedType,
            ISymbol?selectedNodeSymbol,
            IGlyphService?glyphService,
            IUIThreadOperationExecutor uiThreadOperationExecutor)
        {
            var membersInType = selectedType.GetMembers().
                                WhereAsArray(member => MemberAndDestinationValidator.IsMemberValid(member) && member.IsStatic);

            var memberViewModels = membersInType
                                   .SelectAsArray(member =>
                                                  new SymbolViewModel <ISymbol>(member, glyphService)
            {
                // The member user selected will be checked at the beginning.
                IsChecked = SymbolEquivalenceComparer.Instance.Equals(selectedNodeSymbol, member),
            });

            using var cancellationTokenSource = new CancellationTokenSource();
            var memberToDependentsMap = SymbolDependentsBuilder.FindMemberToDependentsMap(membersInType, document.Project, cancellationTokenSource.Token);

            var existingTypeNames = selectedType.ContainingNamespace.GetAllTypes(cancellationTokenSource.Token).SelectAsArray(t => t.ToDisplayString());
            var candidateName     = selectedType.Name + "Helpers";
            var defaultTypeName   = NameGenerator.GenerateUniqueName(candidateName, name => !existingTypeNames.Contains(name));

            var containingNamespaceDisplay = selectedType.ContainingNamespace.IsGlobalNamespace
                ? string.Empty
                : selectedType.ContainingNamespace.ToDisplayString();

            var selectMembersViewModel = new StaticMemberSelectionViewModel(
                uiThreadOperationExecutor,
                memberViewModels,
                memberToDependentsMap);

            return(new MoveStaticMembersDialogViewModel(selectMembersViewModel,
                                                        defaultTypeName,
                                                        existingTypeNames,
                                                        containingNamespaceDisplay,
                                                        document.GetRequiredLanguageService <ISyntaxFactsService>()));
        }