def METHOD_NAME(target=None, killOnFailure=True):
    """Return current connection to libvirt or open a new one.
    Use target to get/create the connection object linked to that object.
    target must have a callable attribute named 'dispatchLibvirtEvents' which
    will be registered as a callback on libvirt events.
    Wrap methods of connection object so that they catch disconnection, and
    take the current process down.
    """
    def wrapMethod(f):
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            try:
                ret = f(*args, **kwargs)
                if isinstance(ret, libvirt.virDomain):
                    for name in dir(ret):
                        method = getattr(ret, name)
                        if callable(method) and name[0] != '_':
                            setattr(ret, name,
                                    wrapMethod(function.weakmethod(method)))
                return ret
            except libvirt.libvirtError as e:
                edom = e.get_error_domain()
                ecode = e.get_error_code()
                EDOMAINS = (libvirt.VIR_FROM_REMOTE,
                            libvirt.VIR_FROM_RPC)
                ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
                          libvirt.VIR_ERR_INTERNAL_ERROR,
                          libvirt.VIR_ERR_NO_CONNECT,
                          libvirt.VIR_ERR_INVALID_CONN)
                if edom in EDOMAINS and ecode in ECODES:
                    try:
                        __connections.METHOD_NAME(id(target)).pingLibvirt()
                    except libvirt.libvirtError as e:
                        edom = e.get_error_domain()
                        ecode = e.get_error_code()
                        if edom in EDOMAINS and ecode in ECODES:
                            log.warning('connection to libvirt broken.'
                                        ' ecode: %d edom: %d', ecode, edom)
                            if killOnFailure:
                                log.critical('taking calling process down.')
                                os.kill(os.getpid(), signal.SIGTERM)
                            else:
                                raise
                raise
        return wrapper
    with __connectionLock:
        conn = __connections.METHOD_NAME(id(target))
        if not conn:
            log.debug('trying to connect libvirt')
            password = ProtectedPassword(libvirt_password())
            conn = open_connection('qemu:///system', SASL_USERNAME, password)
            __connections[id(target)] = conn
            setattr(conn, 'pingLibvirt', getattr(conn, 'getLibVersion'))
            for name in dir(libvirt.virConnect):
                method = getattr(conn, name)
                if callable(method) and name[0] != '_':
                    setattr(conn, name,
                            wrapMethod(function.weakmethod(method)))
            if target is not None:
                for ev in (libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                           libvirt.VIR_DOMAIN_EVENT_ID_REBOOT,
                           libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
                           libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
                           libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS,
                           # Report stable drive name (e.g. vda) in block job
                           # events instead of the drive path which may change
                           # after active commit or block copy.  See
                           # virConnectDomainEventBlockJobCallback in libvirt
                           # docs.
                           libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2,
                           libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG,
                           libvirt.VIR_DOMAIN_EVENT_ID_JOB_COMPLETED,
                           libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
                           libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD,
                           libvirt.VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE):
                    conn.domainEventRegisterAny(None,
                                                ev,
                                                target.dispatchLibvirtEvents,
                                                ev)
            # In case we're running into troubles with keeping the connections
            # alive we should place here:
            # conn.setKeepAlive(interval=5, count=3)
            # However the values need to be considered wisely to not affect
            # hosts which are hosting a lot of virtual machines
        return conn