async def METHOD_NAME(  # pylint: disable=too-many-locals
    config: interface.BaseConfig,
    loop: asyncio.AbstractEventLoop,
    protocol: Optional[Protocol] = None,
    session: Optional[aiohttp.ClientSession] = None,
    storage: Optional[Storage] = None,
) -> interface.AppleTV:
    """Connect to a device based on a configuration."""
    if not config.services:
        raise exceptions.NoServiceError("no service to connect to")
    if config.identifier is None:
        raise exceptions.DeviceIdMissingError("no device identifier")
    storage = storage or MemoryStorage()
    config_copy = deepcopy(config)
    _LOGGER.debug("Loading settings from %s", storage)
    settings = await storage.get_settings(config)
    config_copy.apply(settings)
    session_manager = await http.create_session(session)
    core_dispatcher = CoreStateDispatcher()
    atv = FacadeAppleTV(config_copy, session_manager, core_dispatcher, settings)
    try:
        for proto, proto_methods in PROTOCOLS.items():
            service = config_copy.get_service(proto)
            if service is None or not service.enabled:
                continue
            if not service.enabled:
                _LOGGER.debug("Ignore %s as it is disabled", proto.name)
                continue
            # Lock protocol argument so protocol does not have to deal
            # with that
            takeover_method = partial(atv.takeover, proto)
            # Core provides core access with a protocol specific twist
            core = await create_core(
                config_copy,
                service,
                settings=settings,
                device_listener=atv,
                session_manager=session_manager,
                core_dispatcher=core_dispatcher,
                takeover_method=takeover_method,
                loop=loop,
            )
            for setup_data in proto_methods.setup(core):
                atv.add_protocol(setup_data)
        await atv.METHOD_NAME()
    except Exception:
        await session_manager.close()
        raise
    return atv