'Fetches a connection from the pool, making sure to create a new one
if needed, to obey the maximum connection limits, etc.
Opens a connection to the server and returns an appropriate
object.'

def acquireconnection(self):

    self.semaphore.acquire()
    self.connectionlock.acquire()
    curThread = currentThread()
    imapobj = None
    if len(self.availableconnections):
        for i in range((len(self.availableconnections) - 1), (-1), (-1)):
            tryobj = self.availableconnections[i]
            if (self.lastowner[tryobj] == curThread.ident):
                imapobj = tryobj
                del self.availableconnections[i]
                break
        if (not imapobj):
            imapobj = self.availableconnections[0]
            del self.availableconnections[0]
        self.assignedconnections.append(imapobj)
        self.lastowner[imapobj] = curThread.ident
        self.connectionlock.release()
        return imapobj
    self.connectionlock.release()
    success = False
    try:
        while (success is not True):
            if self.tunnel:
                self.ui.connecting(self.repos.getname(), 'tunnel', self.tunnel)
                imapobj = imaplibutil.IMAP4_Tunnel(self.tunnel, timeout=socket.getdefaulttimeout(), use_socket=self.proxied_socket)
                success = True
            elif self.usessl:
                self.ui.connecting(self.repos.getname(), self.hostname, self.port)
                self.ui.debug('imap', ("%s:    level    '%s',    version    '%s'" % (self.repos.getname(), self.tlslevel, self.sslversion)))
                imapobj = imaplibutil.WrappedIMAP4_SSL(host=self.hostname, port=self.port, keyfile=self.sslclientkey, certfile=self.sslclientcert, ca_certs=self.sslcacertfile, cert_verify_cb=self.__verifycert, ssl_version=self.sslversion, timeout=socket.getdefaulttimeout(), fingerprint=self.fingerprint, use_socket=self.proxied_socket, tls_level=self.tlslevel, af=self.af)
            else:
                self.ui.connecting(self.repos.getname(), self.hostname, self.port)
                imapobj = imaplibutil.WrappedIMAP4(self.hostname, self.port, timeout=socket.getdefaulttimeout(), use_socket=self.proxied_socket, af=self.af)
            if (not self.preauth_tunnel):
                try:
                    self.__authn_helper(imapobj)
                    self.goodpassword = self.password
                    success = True
                except OfflineImapError as e:
                    self.passworderror = str(e)
                    raise
        if self.repos.getconfboolean('usecompression', 0):
            imapobj.enable_compression()
        (typ, dat) = imapobj.capability()
        if (dat != [None]):
            imapobj.capabilities = tuple(dat[(-1)].upper().split())
        if (self.delim == None):
            listres = imapobj.list(self.reference, '""')[1]
            if ((listres == [None]) or (listres == None)):
                listres = imapobj.list(self.reference, '"*"')[1]
            if ((listres == [None]) or (listres == None)):
                err = ("Server    '%s'    returned    no    folders    in    '%s'" % (self.repos.getname(), self.reference))
                self.ui.warn(err)
                raise Exception(err)
            (self.delim, self.root) = imaputil.imapsplit(listres[0])[1:]
            self.delim = imaputil.dequote(self.delim)
            self.root = imaputil.dequote(self.root)
        with self.connectionlock:
            self.assignedconnections.append(imapobj)
            self.lastowner[imapobj] = curThread.ident
        return imapobj
    except Exception as e:
        'If    we    are    here    then    we    did    not    succeed    in    getting    a\n                                                connection    -    we    should    clean    up    and    then    re-raise    the\n                                                error...'
        self.semaphore.release()
        severity = OfflineImapError.ERROR.REPO
        if (type(e) == gaierror):
            reason = ("Could    not    resolve    name    '%s'    for    repository    '%s'.    Make    sure    you    have    configured    the    server    name    correctly    and    that    you    are    online." % (self.hostname, self.repos))
            six.reraise(OfflineImapError, OfflineImapError(reason, severity), exc_info()[2])
        elif (isinstance(e, SSLError) and (e.errno == errno.EPERM)):
            if (self.port != 993):
                reason = ("Could    not    connect    via    SSL    to    host    '%s'    and    non-standard    ssl    port    %d    configured.    Make    sure    you    connect    to    the    correct    port.    Got:    %s" % (self.hostname, self.port, e))
            else:
                reason = ("Unknown    SSL    protocol    connecting    to    host    '%s'    for    repository    '%s'.    OpenSSL    responded:\n%s" % (self.hostname, self.repos, e))
            six.reraise(OfflineImapError, OfflineImapError(reason, severity), exc_info()[2])
        elif (isinstance(e, socket.error) and (e.args[0] == errno.ECONNREFUSED)):
            reason = ("Connection    to    host    '%s:%d'    for    repository    '%s'    was    refused.    Make    sure    you    have    the    right    host    and    port    configured    and    that    you    are    actually    able    to    access    the    network." % (self.hostname, self.port, self.repos))
            six.reraise(OfflineImapError, OfflineImapError(reason, severity), exc_info()[2])
        if (str(e)[:24] == "can't    open    socket;    error"):
            six.reraise(OfflineImapError, OfflineImapError(("Could    not    connect    to    remote    server    '%s'    for    repository    '%s'.    Remote    does    not    answer." % (self.hostname, self.repos)), OfflineImapError.ERROR.REPO), exc_info()[2])
        else:
            raise
