public function startAddon($addonName, $level = 0) {

        $nest = str_repeat(' ', $level);

        $this->log(LogLevel::NOTICE, "{$nest} start addon: {addon}", [
            'addon' => $addonName
        ]);

        // Short circuit if already started
        if ($this->isStarted($addonName)) {
            $this->log(LogLevel::INFO, "{$nest}  already started");
            return true;
        }

        // Check if we've got an addon called this
        $addon = $this->getAddon($addonName);
        if (!$addon) {
            $this->log(LogLevel::WARNING, "{$nest}  unknown addon, not loaded");
            return false;
        }

        // Check requirements
        $requiredAddons = $addon->getInfo('requires') ?? [];

        // If we have requirements, try to load them
        if (count($requiredAddons)) {
            $txtRequirements = implode(',', $requiredAddons);
            $this->log(LogLevel::INFO, "{$nest}  addon has requirements: {requirements}", [
                'requirements' => $txtRequirements
            ]);

            // Check if the requirements are all available
            $missing = [];
            foreach ($requiredAddons as $requiredAddon) {
                if (!$this->isAvailable($requiredAddon)) {
                    $missing[] = $requiredAddon;
                }
            }
            if (count($missing)) {
                $txtMissing = implode(',', $missing);
                $this->log(LogLevel::WARNING, "{$nest}  missing requirements: {missing}", [
                    'missing' => $txtMissing
                ]);
                return false;
            }

            // Keep track of which requirements we've loaded so we can unload if things went wrong
            $startedRequirements = [];

            // Loop over requirements and load each one in turn
            $loadedAllRequirements = true;
            foreach ($requiredAddons as $requiredAddon) {
                if (!$this->isStarted($requiredAddon)) {

                    // Try to load addon if available
                    $loadedRequirement = false;
                    if ($this->isAvailable($requiredAddon)) {
                        $loadedRequirement = $this->startAddon($requiredAddon, $level+1);
                    }

                    $loadedAllRequirements &= $loadedRequirement;

                    if (!$loadedRequirement) {
                        $this->log(LogLevel::WARNING, "{$nest}  failed starting required addon: {addon}", [
                            'addon' => $requiredAddon
                        ]);
                        return false;
                    }

                    $startedRequirements[] = $requiredAddon;
                }
            }
        }

        // Cache autoload info
        $this->autoload = array_merge($this->autoload, $addon->getClasses());

        $addonClass = $addon->getAddonClass();
        if ($addonClass) {

            $this->log(LogLevel::INFO, "{$nest}  creating addon instance: {$addonClass}");

            // Get instance
            $instance = $this->di->getArgs($addonClass, [
                new Reference([AbstractConfig::class, "addons.addon.{$addonName}"])
            ]);
            $instance->setAddon($addon);
            $this->instances[$addonName] = $instance;
            $instance->start();

        }

        $this->enabled[$addonName] = true;

        return true;
    }