public static Func <IServiceProvider, LocalizablePresenter> BasedOnQuery(string name, bool redirectWhenNotFound = true)
        {
            void redirect(IDotvvmRequestContext context)
            {
                var url = new UriBuilder(context.HttpContext.Request.Url);

                url.Query =
                    context.HttpContext.Request.Query
                    .Where(q => q.Key != name)
                    .Concat(new[] { new KeyValuePair <string, string>(name, context.Configuration.DefaultCulture) })
                    .Select(q => Uri.EscapeUriString(q.Key) + "=" + Uri.EscapeUriString(q.Value)).Apply(s => string.Join("&", s));
                if (url.ToString() == context.HttpContext.Request.Url.ToString())
                {
                    throw new Exception($"The specified default culture is probably invalid");
                }
                context.RedirectToUrl(url.ToString());
            }

            CultureInfo?getCulture(IDotvvmRequestContext context) =>
            context.Query.TryGetValue(name, out var value) && !string.IsNullOrEmpty(value) ? CultureInfo.GetCultureInfo(value) : null;

            var presenter = new LocalizablePresenter(
                redirectWhenNotFound ? WithRedirectOnFailure(redirect, getCulture) : getCulture,
                context => context.Services.GetRequiredService <IDotvvmPresenter>().ProcessRequest(context)
                );

            return(_ => presenter);
        }
        public static Func <IServiceProvider, LocalizablePresenter> BasedOnParameter(string name, bool redirectWhenNotFound = true)
        {
            void redirect(IDotvvmRequestContext context)
            {
                var routeParameters = context.Parameters.ToDictionary(e => e.Key, e => e.Value);

                if (context.Configuration.DefaultCulture.Equals(routeParameters[name]))
                {
                    throw new Exception($"The specified default culture is probably invalid");
                }
                routeParameters[name] = context.Configuration.DefaultCulture;
                context.RedirectToRoute(context.Route !.RouteName, routeParameters, query: context.HttpContext.Request.Query);
            }

            CultureInfo?getCulture(IDotvvmRequestContext context) =>
            context.Parameters !.TryGetValue(name, out var value) && !string.IsNullOrEmpty(value as string) ? CultureInfo.GetCultureInfo((string)value !) : null;

            var presenter = new LocalizablePresenter(
                redirectWhenNotFound ? WithRedirectOnFailure(redirect, getCulture) : getCulture,
                context => context.Services.GetRequiredService <IDotvvmPresenter>().ProcessRequest(context)
                );

            return(_ => presenter);
        }