internal static IContainer AddJsonRpcServerCore <T>(this IContainer container, JsonRpcServerOptionsBase <T> options) where T : IJsonRpcHandlerRegistry <T>
        {
            if (options.Output == null)
            {
                throw new ArgumentException("Output is missing!", nameof(options));
            }

            if (options.Input == null)
            {
                throw new ArgumentException("Input is missing!", nameof(options));
            }

            container = container.Populate(options.Services);

            container.RegisterInstance(options.Output, serviceKey: nameof(options.Output));
            container.RegisterInstance(options.Input, serviceKey: nameof(options.Input));
            container.RegisterInstance(options.MaximumRequestTimeout, serviceKey: nameof(options.MaximumRequestTimeout));
            container.RegisterInstance(options.SupportsContentModified, serviceKey: nameof(options.SupportsContentModified));
            container.RegisterInstance(options.Concurrency ?? -1, serviceKey: nameof(options.Concurrency));
            container.RegisterInstance(options.InputScheduler, serviceKey: nameof(options.InputScheduler));
            container.RegisterInstance(options.OutputScheduler, serviceKey: nameof(options.OutputScheduler));
            if (options.CreateResponseException != null)
            {
                container.RegisterInstance(options.CreateResponseException);
            }

            container.RegisterMany <OutputHandler>(
                nonPublicServiceTypes: true,
                made: Parameters.Of
                .Type <PipeWriter>(serviceKey: nameof(options.Output))
                .Type <IScheduler>(serviceKey: nameof(options.OutputScheduler)),
                reuse: Reuse.Singleton
                );

            container.Register <RequestInvokerOptions>(
                made: Made.Of().Parameters
                .Type <TimeSpan>(serviceKey: nameof(options.MaximumRequestTimeout))
                .Type <bool>(serviceKey: nameof(options.SupportsContentModified))
                .Name("concurrency", serviceKey: nameof(options.Concurrency)),
                reuse: Reuse.Singleton);

            if (!container.IsRegistered <RequestInvoker>())
            {
                container.Register <RequestInvoker, DefaultRequestInvoker>(
                    made: Made.Of().Parameters
                    .Type <IScheduler>(serviceKey: nameof(options.InputScheduler)),
                    reuse: Reuse.Singleton);
            }

            container.Register <Connection>(
                made: Made.Of().Parameters
                .Type <PipeReader>(serviceKey: nameof(options.Input))
                ,
                reuse: Reuse.Singleton
                );

            container.RegisterInstance(options.DefaultScheduler);

            container.RegisterMany <ResponseRouter>(
                serviceTypeCondition: type => type.IsInterface,
                reuse: Reuse.Singleton
                );

            container.RegisterInstance(options.Handlers);
            container.RegisterInitializer <IJsonRpcHandlerCollection>(
                (collection, context) => {
                foreach (var description in context
                         .ResolveMany <JsonRpcHandlerDescription>()
                         .Concat(
                             context
                             .ResolveMany <IJsonRpcHandler>().Select(_ => JsonRpcHandlerDescription.Infer(_))
                             ))
                {
                    collection.Add(description);
                }
            }
                );
            container.RegisterMany <InstanceHasStarted>(nonPublicServiceTypes: true, reuse: Reuse.Singleton);

            return(container.AddJsonRpcMediatR());
        }