+sub get_current_sort_params {
+ my ($self) = @_;
+
+ $self->sorted->read_params;
+}
+
+sub init {
+ my ($self, %params) = @_;
+
+ my $model = delete $params{model};
+ if (!$model && $params{controller} && ref $params{controller}) {
+ $model = ref $params{controller};
+ $model =~ s/.*:://;
+ die 'Need a valid model' unless $model;
+ }
+ $self->model($model);
+
+ my @plugins;
+ for my $plugin (qw(filtered sorted paginated)) {
+ next if exists($params{$plugin}) && !$params{$plugin};
+
+ my $spec = delete $params{$plugin} // {};
+ my $plugin_class = "SL::Controller::Helper::GetModels::" . ucfirst $plugin;
+ push @plugins, $self->$plugin($plugin_class->new(%$spec, get_models => $self));
+ }
+ $self->plugins(@plugins);
+
+ $self->SUPER::init(%params);
+
+ $_->read_params for $self->plugins;
+
+ weaken $self->controller if $self->controller;
+}
+
+sub finalize {
+ my ($self, %params) = @_;
+
+ return %{ $self->final_params } if $self->finalized;
+
+ $self->register_handlers(callback => sub { shift; (@_, %{ $self->additional_url_params }) }) if %{ $self->additional_url_params };
+
+ push @{ $params{query} ||= [] }, @{ $self->query || [] };
+ push @{ $params{with_objects} ||= [] }, @{ $self->with_objects || [] };
+
+ %params = $_->finalize(%params) for $self->plugins;
+
+ $self->finalized(1);
+ $self->final_params(\%params);
+
+ return %params;
+}
+
+sub register_handlers {
+ my ($self, %additional_handlers) = @_;
+
+ my $handlers = $self->handlers;
+ map { push @{ $handlers->{$_} }, $additional_handlers{$_} if $additional_handlers{$_} } keys %$handlers;
+}
+
+sub add_additional_url_params {
+ my ($self, %params) = @_;
+
+ $self->additional_url_params({ %{ $self->additional_url_params }, %params });
+
+ return $self;
+}
+
+sub get_models_url_params {
+ my ($self, $sub_name_or_code) = @_;
+
+ my $code = (ref($sub_name_or_code) || '') eq 'CODE' ? $sub_name_or_code : sub { shift->controller->$sub_name_or_code(@_) };
+ my $callback = sub {
+ my ($self, %params) = @_;
+ my @additional_params = $code->($self);
+ return (
+ %params,
+ (scalar(@additional_params) == 1) && (ref($additional_params[0]) eq 'HASH') ? %{ $additional_params[0] } : @additional_params,
+ );
+ };
+
+ $self->register_handlers('callback' => $callback);
+}
+
+sub get_callback_params {
+ my ($self, %override_params) = @_;
+
+ my %default_params = $self->_run_handlers('callback', action => $self->list_action);
+}
+
+sub get_callback {