public static async Task <ImmutableArray <INamedTypeSymbol> > FindTypesInCurrentProcessAsync(
            INamedTypeSymbol type,
            Solution solution,
            IImmutableSet <Project>?projects,
            bool transitive,
            DependentTypesKind kind,
            CancellationToken cancellationToken)
        {
            var functionId = kind switch
            {
                DependentTypesKind.DerivedClasses => FunctionId.DependentTypeFinder_FindAndCacheDerivedClassesAsync,
                DependentTypesKind.DerivedInterfaces => FunctionId.DependentTypeFinder_FindAndCacheDerivedInterfacesAsync,
                DependentTypesKind.ImplementingTypes => FunctionId.DependentTypeFinder_FindAndCacheImplementingTypesAsync,
                _ => throw ExceptionUtilities.UnexpectedValue(kind)
            };

            using (Logger.LogBlock(functionId, cancellationToken))
            {
                var task = kind switch
                {
                    DependentTypesKind.DerivedClasses => FindDerivedClassesInCurrentProcessAsync(type, solution, projects, transitive, cancellationToken),
                    DependentTypesKind.DerivedInterfaces => FindDerivedInterfacesInCurrentProcessAsync(type, solution, projects, transitive, cancellationToken),
                    DependentTypesKind.ImplementingTypes => FindImplementingTypesInCurrentProcessAsync(type, solution, projects, transitive, cancellationToken),
                    _ => throw ExceptionUtilities.UnexpectedValue(kind)
                };

                return(await task.ConfigureAwait(false));
            }
        }
        public static async Task <ImmutableArray <INamedTypeSymbol> > FindTypesAsync(
            INamedTypeSymbol type,
            Solution solution,
            IImmutableSet <Project>?projects,
            bool transitive,
            DependentTypesKind kind,
            CancellationToken cancellationToken)
        {
            if (SerializableSymbolAndProjectId.TryCreate(type, solution, cancellationToken, out var serializedType))
            {
                var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                if (client != null)
                {
                    var projectIds = projects?.SelectAsArray(p => p.Id) ?? default;

                    var result = await client.TryInvokeAsync <IRemoteDependentTypeFinderService, ImmutableArray <SerializableSymbolAndProjectId> >(
                        solution,
                        (service, solutionInfo, cancellationToken) => service.FindTypesAsync(solutionInfo, serializedType, projectIds, transitive, kind, cancellationToken),
                        callbackTarget : null,
                        cancellationToken).ConfigureAwait(false);

                    if (!result.HasValue)
                    {
                        return(ImmutableArray <INamedTypeSymbol> .Empty);
                    }

                    return(await RehydrateAsync(solution, result.Value, cancellationToken).ConfigureAwait(false));
                }

                // TODO: Do not fall back to in-proc https://github.com/dotnet/roslyn/issues/47557
            }

            return(await FindTypesInCurrentProcessAsync(type, solution, projects, transitive, kind, cancellationToken).ConfigureAwait(false));
        }