public function add(ExtensionInterface $extension, DirectoryInterface $baseDir = null, DirectoryInterface $webDir = null, $composerName = null)
    {
        if ($this->registered) {
            throw new \RuntimeException('Can not add extensions after they are registered.');
        }

        // Set paths in the extension
        if ($baseDir === null) {
            // If there is no base dir we just default to the same directory as the extension class is in.
            $reflector = new ReflectionClass($extension);
            $dir = dirname($reflector->getFileName());
            if (basename($dir) === 'src') {
                $dir = dirname($dir);
            } elseif (basename(dirname($dir)) === 'src') {
                $dir = dirname(dirname($dir));
            }
            $fs = new Filesystem(new Local($dir));

            $baseDir = $fs->getDir('/');
        }
        $extension->setBaseDirectory($baseDir);

        if ($webDir === null) {
            $webDir = $this->webFs->getDir($extension->getId());
        }
        $extension->setWebDirectory($webDir);

        // Determine if enabled
        $enabled = $this->config->get('extensions/' . $extension->getId(), true);

        if ($composerName !== null) {
            // Map composer name to ID
            $this->composerNames[$composerName] = $extension->getId();

            // Check if enabled by composer name
            $enabled = $this->config->get("extensions/$composerName", $enabled);
        }

        // Instantiate resolved extension and mark enabled/disabled
        $resolved = (new ResolvedExtension($extension))
            ->setEnabled($enabled)
        ;

        return $this->extensions[$extension->getId()] = $resolved;
    }