def install(self, plugin, name=None, **opts):
        """Install plugin to the application."""
        source = plugin

        if isinstance(plugin, str):
            module, _, attr = plugin.partition(':')
            module = import_module(module)
            plugin = getattr(module, attr or 'Plugin', None)

        if isinstance(plugin, types.ModuleType):
            plugin = getattr(module, 'Plugin', None)

        if plugin is None:
            raise MuffinException('Plugin is not found %r' % source)

        name = name or plugin.name
        if name in self.ps:
            raise MuffinException('Plugin with name `%s` is already intalled.' % name)

        if isinstance(plugin, type):
            plugin = plugin(**opts)

        if hasattr(plugin, 'setup'):
            plugin.setup(self)

        if hasattr(plugin, 'middleware') and plugin.middleware not in self.middlewares:
            self.middlewares.append(plugin.middleware)

        if hasattr(plugin, 'startup'):
            self.on_startup.append(plugin.startup)

        if hasattr(plugin, 'cleanup'):
            self.on_cleanup.append(plugin.cleanup)

        # Save plugin links
        self.ps[name] = plugin

        return plugin
Install plugin to the application.