public function load_theme($classmap = null)
    {
        if ($classmap !== null) {
            static::$theme_includes = \unserialize($classmap);
        } else {
            $hookables_dir = \trim(Config::get('theme.hookables_directory'), '/');
            $root = \trailingslashit(\get_template_directory());

            $hookable_locations = [
                $root . 'theme/' . $hookables_dir,
                $root . 'theme/Http/Ajax',
                $root . 'theme/Http/Middleware',
                $root . 'theme/Http/Validation/Rules',
                $root . 'theme/Content',
                $root . 'theme/Events',
            ];

            if (\is_child_theme()) {
                $root = \trailingslashit(\get_stylesheet_directory());

                $hookable_locations[] = $root . 'theme/' . $hookables_dir;
                $hookable_locations[] = $root . 'theme/Http/Ajax';
                $hookable_locations[] = $root . 'theme/Http/Middleware';
                $hookable_locations[] = $root . 'theme/Http/Validation/Rules';
                $hookable_locations[] = $root . 'theme/Content';
                $hookable_locations[] = $root . 'theme/Events';
            }

            // Gather all possible Hookables.
            foreach ($hookable_locations as $dir) {
                static::$theme_includes = $this->scan_dir($dir, static::$theme_includes);
            }

            if (!empty(static::$theme_includes)) {
                foreach (static::$theme_includes as $class => $path) {
                    $this->init_hookable($class);
                }
            }

            static::$theme_includes = $this->scan_dir(
                \get_stylesheet_directory() . '/theme/',
                static::$theme_includes
            );
        }

        $this->init_theme_providers();
        $this->init_theme_setup();
    }