*  @throws IOException if a network error occurs
     *  @throws CredentialNotFoundException if the user lacks the permission to
     *  delete
     *  @throws CredentialExpiredException if cookies have expired
     *  @throws AccountLockedException if user is blocked
     *  @since 0.24
     */
    public synchronized void delete(String title, String reason) throws IOException, LoginException
    {
        long start = System.currentTimeMillis();
        statusCheck();

        if (user == null || !user.isAllowedTo("delete"))
            throw new CredentialNotFoundException("Cannot delete: Permission denied");

        // edit token
        HashMap<String, Object> info = getPageInfo(title);
        if (!(Boolean)info.get("exists"))
        {
            logger.log(Level.INFO, "Page \"{0}\" does not exist.", title);
            return;
        }
        String deleteToken = (String)info.get("token");

        // post data
        StringBuilder buffer = new StringBuilder(500);
        buffer.append("title=");
        buffer.append(URLEncoder.encode(normalize(title), "UTF-8"));
        buffer.append("&reason=");
        buffer.append(URLEncoder.encode(reason, "UTF-8"));
        buffer.append("&token=");
        buffer.append(URLEncoder.encode(deleteToken, "UTF-8"));
        String response = post(apiUrl + "action=delete", buffer.toString(), "delete");

        // done
        try
        {
            if (!response.contains("<delete title="))
                checkErrors(response, "delete");
        }
        catch (IOException e)
        {
            // retry once
            if (retry)
            {
                retry = false;
                log(Level.WARNING, "Exception: " + e.getMessage() + " Retrying...", "delete");
                delete(title, reason);
            }
            else
            {
                logger.logp(Level.SEVERE, "Wiki", "delete()", "[" + domain + "] EXCEPTION:  ", e);
                throw e;
            }
        }
        if (retry)
            log(Level.INFO, "Successfully deleted " + title, "delete");
        retry = true;

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