protected function sortPlugins()
    {
        $plugins = $this->plugins;
        $nativePlugins = $this->nativePlugins;
        $sortedPlugins = array();
        $sortedNativePlugins = array();
        $visitedPlugins = array();

        $visitPlugin = function ($plugin) use (
            $plugins,
            $nativePlugins,
            &$sortedPlugins,
            &$sortedNativePlugins,
            &$visitedPlugins,
            &$visitPlugin
        ) {
            $pluginName = get_class($plugin);

            // skip already visited plugins and ignore circular dependencies
            if (!isset($visitedPlugins[$pluginName])) {
                $visitedPlugins[$pluginName] = true;

                $dependencies = array();
                if ($plugin instanceof PicoPluginInterface) {
                    $dependencies = $plugin->getDependencies();
                }
                if (!isset($nativePlugins[$pluginName])) {
                    $dependencies[] = 'PicoDeprecated';
                }

                foreach ($dependencies as $dependency) {
                    // ignore missing dependencies
                    // this is only a problem when the user tries to enable this plugin
                    if (isset($plugins[$dependency])) {
                        $visitPlugin($plugins[$dependency]);
                    }
                }

                $sortedPlugins[$pluginName] = $plugin;
                if (isset($nativePlugins[$pluginName])) {
                    $sortedNativePlugins[$pluginName] = $plugin;
                }
            }
        };

        if (isset($this->plugins['PicoDeprecated'])) {
            $visitPlugin($this->plugins['PicoDeprecated']);
        }

        foreach ($this->plugins as $plugin) {
            $visitPlugin($plugin);
        }

        $this->plugins = $sortedPlugins;
        $this->nativePlugins = $sortedNativePlugins;
    }