public synchronized void emailUser(User user, String message, String subject, boolean emailme) throws IOException, CredentialException
    {
        long start = System.currentTimeMillis();

        // check if blocked, logged in
        if (this.user == null || !this.user.isAllowedTo("sendemail"))
            throw new CredentialNotFoundException("Permission denied: cannot email.");

        // is this user emailable?
        if (!(Boolean)user.getUserInfo().get("emailable"))
        {
            // should throw an exception here
            logger.log(Level.WARNING, "User {0} is not emailable", user.getUsername());
            return;
        }
        String token = (String)getPageInfo("User:" + user.getUsername()).get("token");
        if (cookies2.isEmpty())
        {
            logger.log(Level.SEVERE, "Cookies have expired.");
            logout();
            throw new CredentialExpiredException("Cookies have expired.");
        }

        // post email
        StringBuilder buffer = new StringBuilder(20000);
        buffer.append("token=");
        buffer.append(URLEncoder.encode(token, "UTF-8"));
        buffer.append("&target=");
        buffer.append(URLEncoder.encode(user.getUsername(), "UTF-8"));
        if (emailme)
            buffer.append("&ccme=true");
        buffer.append("&text=");
        buffer.append(URLEncoder.encode(message, "UTF-8"));
        buffer.append("&subject=");
        buffer.append(URLEncoder.encode(subject, "UTF-8"));
        post(query + "action=emailuser", buffer.toString(), "emailUser");

        // something

        // throttle
        try
        {
            long time = throttle - System.currentTimeMillis() + start;
            if (time > 0)
                Thread.sleep(time);
        }
        catch (InterruptedException e)
        {
            // nobody cares
        }

        log(Level.INFO, "Successfully emailed " + user.getUsername() + ".", "emailUser");
    }