*  not have the necessary permissions)
     *  @param section the section to edit. Use -1 to specify a new section and
     *  -2 to disable section editing.
     *  @param basetime the timestamp of the revision on which <tt>text</tt> is
     *  based, used to check for edit conflicts. <tt>null</tt> disables this.
     *  @throws IOException if a network error occurs
     *  @throws AccountLockedException if user is blocked
     *  @throws CredentialExpiredException if cookies have expired
     *  @throws CredentialException if page is protected and we can't edit it
     *  @throws UnsupportedOperationException if you try to edit a Special: or
     *  Media: page
     *  @see #getPageText
     *  @since 0.17
     */
    public synchronized void edit(String title, String text, String summary, boolean minor, boolean bot,
        int section, Calendar basetime) throws IOException, LoginException
    {
        // @revised 0.16 to use API edit. No more screenscraping - yay!
        // @revised 0.17 section editing
        // @revised 0.25 optional bot flagging
        long start = System.currentTimeMillis();
        statusCheck();

        // protection and token
        HashMap<String, Object> info = getPageInfo(title);
        if (!checkRights(info, "edit") || (Boolean)info.get("exists") && !checkRights(info, "create"))
        {
            CredentialException ex = new CredentialException("Permission denied: page is protected.");
            logger.logp(Level.WARNING, "Wiki", "edit()", "[" + getDomain() + "] Cannot edit - permission denied.", ex);
            throw ex;
        }
        String wpEditToken = (String)info.get("token");

        // post data
        StringBuilder buffer = new StringBuilder(300000);
        buffer.append("title=");
        buffer.append(URLEncoder.encode(normalize(title), "UTF-8"));
        buffer.append("&text=");
        buffer.append(URLEncoder.encode(text, "UTF-8"));
        buffer.append("&summary=");
        buffer.append(URLEncoder.encode(summary, "UTF-8"));
        buffer.append("&token=");
        buffer.append(URLEncoder.encode(wpEditToken, "UTF-8"));
        if (basetime != null)
        {
            buffer.append("&starttimestamp=");
            buffer.append(calendarToTimestamp((Calendar)info.get("timestamp")));
            buffer.append("&basetimestamp=");
            // I wonder if the time getPageText() was called suffices here
            buffer.append(calendarToTimestamp(basetime));
        }
        if (minor)
            buffer.append("&minor=1");
        if (bot && user.isAllowedTo("bot"))
            buffer.append("&bot=1");
        if (section == -1)
            buffer.append("&section=new");
        else if (section != -2)
        {
            buffer.append("&section=");
            buffer.append(section);
        }
        String response = post(apiUrl + "action=edit", buffer.toString(), "edit");

        // done
        if (response.contains("error code=\"editconflict\""))
        {
            log(Level.WARNING, "Edit conflict on " + title, "edit");
            return; // hmmm, perhaps we should throw an exception. I'm open to ideas.
        }
        try
        {
            checkErrors(response, "edit");
        }
        catch (IOException e)
        {
            // retry once
            if (retry)
            {
                retry = false;
                log(Level.WARNING, "Exception: " + e.getMessage() + " Retrying...", "edit");
                edit(title, text, summary, minor, bot, section, basetime);
            }
            else
            {
                logger.logp(Level.SEVERE, "Wiki", "edit()", "[" + domain + "] EXCEPTION:  ", e);
                throw e;
            }
        }
        if (retry)
            log(Level.INFO, "Successfully edited " + title, "edit");
        retry = true;

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