@Override
    public boolean check(final Session<?> session, final CancelCallback callback) throws BackgroundException {
        final Host bookmark = session.getHost();
        if(bookmark.getProtocol().isHostnameConfigurable() && StringUtils.isBlank(bookmark.getHostname())) {
            throw new ConnectionCanceledException();
        }
        if(session.isConnected()) {
            if(log.isDebugEnabled()) {
                log.debug(String.format("Skip opening connection for session %s", session));
            }
            // Connection already open
            return false;
        }
        // Obtain password from keychain or prompt
        synchronized(login) {
            login.validate(bookmark, prompt, new LoginOptions(bookmark.getProtocol()));
        }
        this.connect(session, callback);
        return true;
    }
@Test(expected = LoginCanceledException.class)
    public void testPasswordChange() throws Exception {
        final AtomicBoolean connected = new AtomicBoolean();
        final AtomicBoolean keychain = new AtomicBoolean();
        final AtomicBoolean prompt = new AtomicBoolean();
        final LoginConnectionService s = 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) {
                //
            }

            @Override
            public Credentials prompt(final Host bookmark, final String username, final String title, final String reason, final LoginOptions options) {
                prompt.set(true);
                // New password entered
                return new Credentials(username, "b");
            }
        }, new DisabledHostKeyCallback(), new DisabledPasswordStore() {
            @Override
            public String findLoginPassword(final Host bookmark) {
                keychain.set(true);
                // Old password stored
                return "a";
            }
        }, new DisabledProgressListener());
        final Session session = new NullSession(new Host(new TestProtocol(), "localhost", new Credentials("user", ""))) {
            @Override
            public Void connect(final ProxyFinder proxy, final HostKeyCallback key, final LoginCallback prompt, final CancelCallback cancel) {
                connected.set(true);
                return null;
            }

            @Override
            public boolean isConnected() {
                return connected.get();
            }

            @Override
            public void login(final LoginCallback l, final CancelCallback cancel) throws BackgroundException {
                if(prompt.get()) {
                    assertEquals("b", host.getCredentials().getPassword());
                    throw new LoginCanceledException();
                }
                if(keychain.get()) {
                    assertFalse(prompt.get());
                    assertEquals("a", host.getCredentials().getPassword());
                    throw new LoginFailureException("f");
                }
            }
        };
        try {
            s.check(session, new DisabledCancelCallback());
        }
        finally {
            assertTrue(keychain.get());
            assertTrue(prompt.get());
        }
    }