@Override
    public void login(final LoginCallback prompt, final CancelCallback cancel) throws BackgroundException {
        final Credentials credentials = host.getCredentials();
        if(host.getProtocol().isPasswordConfigurable()) {
            final String domain, username;
            if(credentials.getUsername().contains("\\")) {
                domain = StringUtils.substringBefore(credentials.getUsername(), "\\");
                username = StringUtils.substringAfter(credentials.getUsername(), "\\");
            }
            else {
                username = credentials.getUsername();
                domain = new HostPreferences(host).getProperty("webdav.ntlm.domain");
            }
            for(String scheme : Arrays.asList(AuthSchemes.NTLM, AuthSchemes.SPNEGO)) {
                client.setCredentials(
                        new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, scheme),
                        new NTCredentials(username, credentials.getPassword(),
                                preferences.getProperty("webdav.ntlm.workstation"), domain)
                );
            }
            for(String scheme : Arrays.asList(AuthSchemes.BASIC, AuthSchemes.DIGEST, AuthSchemes.KERBEROS)) {
                client.setCredentials(
                        new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, scheme),
                        new UsernamePasswordCredentials(username, credentials.getPassword()));
            }
            if(preferences.getBoolean("webdav.basic.preemptive")) {
                client.enablePreemptiveAuthentication(host.getHostname(),
                        host.getPort(),
                        host.getPort(),
                        Charset.forName(preferences.getProperty("http.credentials.charset"))
                );
            }
            else {
                client.disablePreemptiveAuthentication();
            }
        }
        if(credentials.isPassed()) {
            if(log.isWarnEnabled()) {
                log.warn(String.format("Skip verifying credentials with previous successful authentication event for %s", this));
            }
            return;
        }
        try {
            final Path home = new DelegatingHomeFeature(new WorkdirHomeFeature(host), new DefaultPathHomeFeature(host)).find();
            final HttpHead head = new HttpHead(new DAVPathEncoder().encode(home));
            try {
                client.execute(head, new MicrosoftIISFeaturesResponseHandler(capabilities));
            }
            catch(SardineException e) {
                switch(e.getStatusCode()) {
                    case HttpStatus.SC_NOT_FOUND:
                        if(log.isWarnEnabled()) {
                            log.warn(String.format("Ignore failure %s", e));
                        }
                        break;
                    case HttpStatus.SC_NOT_IMPLEMENTED:
                    case HttpStatus.SC_FORBIDDEN:
                    case HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE:
                    case HttpStatus.SC_METHOD_NOT_ALLOWED:
                        if(log.isWarnEnabled()) {
                            log.warn(String.format("Failed HEAD request to %s with %s. Retry with PROPFIND.",
                                    host, e.getResponsePhrase()));
                        }
                        cancel.verify();
                        // Possibly only HEAD requests are not allowed
                        final ListService list = this.getFeature(ListService.class);
                        list.list(home, new DisabledListProgressListener() {
                            @Override
                            public void chunk(final Path parent, final AttributedList<Path> list) throws ListCanceledException {
                                try {
                                    cancel.verify();
                                }
                                catch(ConnectionCanceledException e) {
                                    throw new ListCanceledException(list, e);
                                }
                            }
                        });
                        break;
                    case HttpStatus.SC_BAD_REQUEST:
                        if(preferences.getBoolean("webdav.basic.preemptive")) {
                            if(log.isWarnEnabled()) {
                                log.warn(String.format("Disable preemptive authentication for %s due to failure %s",
                                        host, e.getResponsePhrase()));
                            }
                            cancel.verify();
                            client.disablePreemptiveAuthentication();
                            client.execute(head, new MicrosoftIISFeaturesResponseHandler(capabilities));
                        }
                        else {
                            throw new DAVExceptionMappingService().map(e);
                        }
                        break;
                    default:
                        throw new DAVExceptionMappingService().map(e);
                }
            }
        }
        catch(SardineException e) {
            throw new DAVExceptionMappingService().map(e);
        }
        catch(IOException e) {
            throw new HttpExceptionMappingService().map(e);
        }
    }
@Test(expected = ConnectionRefusedException.class)
    public void testConnectRefused() throws Exception {
        final Host host = new Host(new DAVSSLProtocol(), "localhost", 2121);
        final DAVSession session = new DAVSession(host,
                new CertificateStoreX509TrustManager(new DisabledCertificateTrustCallback(), new DefaultTrustManagerHostnameCallback(host), new DefaultCertificateStore()),
                new CertificateStoreX509KeyManager(new DisabledCertificateIdentityCallback(), host, new DefaultCertificateStore()));
        try {
            session.open(new DisabledProxyFinder(), new DisabledHostKeyCallback(), new DisabledLoginCallback(), new DisabledCancelCallback());
            session.login(new DisabledLoginCallback(), new DisabledCancelCallback());
        }
        catch(ConnectionRefusedException e) {
            assertEquals("Connection failed", e.getMessage());
            throw e;
        }
    }