@Override
    public void connect(final Session<?> session, final CancelCallback cancel) throws BackgroundException {
        if(session.isConnected()) {
            this.close(session);
        }
        final Host bookmark = session.getHost();
        // Try to resolve the hostname first
        final String hostname = HostnameConfiguratorFactory.get(bookmark.getProtocol()).getHostname(bookmark.getHostname());
        listener.message(MessageFormat.format(LocaleFactory.localizedString("Resolving {0}", "Status"), hostname));
        if(proxy.find(new ProxyHostUrlProvider().get(bookmark)) == Proxy.DIRECT) {
            // Only try to resolve target hostname if direct connection
            if(null == JumpHostConfiguratorFactory.get(bookmark.getProtocol()).getJumphost(bookmark.getHostname())) {
                // Do not attempt to resolve hostname that may only be reachable in internal network from jump host
                try {
                    resolver.resolve(hostname, cancel);
                }
                catch(ResolveFailedException e) {
                    log.warn(String.format("DNS resolver failed for %s", hostname));
                    throw e;
                }
            }
        }
        listener.message(MessageFormat.format(LocaleFactory.localizedString("Opening {0} connection to {1}", "Status"),
            bookmark.getProtocol().getName(), hostname));
        // The IP address could successfully be determined
        session.open(proxy, key, prompt, cancel);
        listener.message(MessageFormat.format(LocaleFactory.localizedString("{0} connection opened", "Status"),
            bookmark.getProtocol().getName()));
        // Update last accessed timestamp
        bookmark.setTimestamp(new Date());
        // Warning about insecure connection prior authenticating
        if(session.alert(prompt)) {
            // Warning if credentials are sent plaintext.
            prompt.warn(bookmark, MessageFormat.format(LocaleFactory.localizedString("Unsecured {0} connection", "Credentials"),
                bookmark.getProtocol().getName()),
                MessageFormat.format("{0} {1}.", MessageFormat.format(LocaleFactory.localizedString("{0} will be sent in plaintext.", "Credentials"),
                    bookmark.getProtocol().getPasswordPlaceholder()),
                    LocaleFactory.localizedString("Please contact your web hosting service provider for assistance", "Support")),
                LocaleFactory.localizedString("Continue", "Credentials"),
                LocaleFactory.localizedString("Disconnect", "Credentials"),
                String.format("connection.unsecure.%s", bookmark.getHostname()));
        }
        // Login
        try {
            this.authenticate(proxy, session, cancel);
        }
        catch(BackgroundException e) {
            this.close(session);
            throw e;
        }
    }
@Test(expected = LoginCanceledException.class)
    public void testConnectionWarning() throws Exception {
        final Host host = new Host(new TestProtocol(), "test.cyberduck.ch", new Credentials(
            "u", "p"
        ));
        final AtomicBoolean warned = new AtomicBoolean(false);
        final Session session = new NullSession(host);
        final LoginConnectionService l = new LoginConnectionService(new DisabledLoginCallback() {
            @Override
            public void warn(final Host bookmark, final String title, final String message,
                             final String continueButton, final String disconnectButton, final String preference) throws LoginCanceledException {
                warned.set(true);
                throw new LoginCanceledException();
            }
        }, new DisabledHostKeyCallback(), new DisabledPasswordStore(),
            new DisabledProgressListener());
        try {
            l.connect(session, new DisabledCancelCallback());
            fail();
        }
        catch(LoginCanceledException e) {
            assertTrue(warned.get());
            throw e;
        }
    }