/* HTMLDocument.java --
   Copyright (C) 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.text.html;

import gnu.classpath.NotImplementedException;

import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;
import java.util.Vector;

import javax.swing.ButtonGroup;
import javax.swing.DefaultButtonModel;
import javax.swing.JEditorPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.UndoableEditEvent;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
import javax.swing.text.ElementIterator;
import javax.swing.text.GapContent;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.PlainDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.html.HTML.Tag;

/**
 * Represents the HTML document that is constructed by defining the text and
 * other components (images, buttons, etc) in HTML language. This class can
 * becomes the default document for {@link JEditorPane} after setting its
 * content type to "text/html". HTML document also serves as an intermediate
 * data structure when it is needed to parse HTML and then obtain the content of
 * the certain types of tags. This class also has methods for modifying the HTML
 * content.
 *
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 * @author Anthony Balkissoon (abalkiss@redhat.com)
 * @author Lillian Angel (langel@redhat.com)
 */
public class HTMLDocument extends DefaultStyledDocument
{
  /** A key for document properies.  The value for the key is
   * a Vector of Strings of comments not found in the body.
   */
  public static final String AdditionalComments = "AdditionalComments";
  URL baseURL = null;
  boolean preservesUnknownTags = true;
  int tokenThreshold = Integer.MAX_VALUE;
  HTMLEditorKit.Parser parser;

  /**
   * Indicates whether this document is inside a frame or not.
   */
  private boolean frameDocument;

  /**
   * Package private to avoid accessor methods.
   */
  String baseTarget;

  /**
   * Constructs an HTML document using the default buffer size and a default
   * StyleSheet.
   */
  public HTMLDocument()
  {
    this(new GapContent(BUFFER_SIZE_DEFAULT), new StyleSheet());
  }

  /**
   * Constructs an HTML document with the default content storage
   * implementation and the specified style/attribute storage mechanism.
   *
   * @param styles - the style sheet
   */
  public HTMLDocument(StyleSheet styles)
  {
   this(new GapContent(BUFFER_SIZE_DEFAULT), styles);
  }

  /**
   * Constructs an HTML document with the given content storage implementation
   * and the given style/attribute storage mechanism.
   *
   * @param c - the document's content
   * @param styles - the style sheet
   */
  public HTMLDocument(AbstractDocument.Content c, StyleSheet styles)
  {
    super(c, styles);
  }

  /**
   * Gets the style sheet with the document display rules (CSS) that were specified
   * in the HTML document.
   *
   * @return - the style sheet
   */
  public StyleSheet getStyleSheet()
  {
    return (StyleSheet) getAttributeContext();
  }

  /**
   * This method creates a root element for the new document.
   *
   * @return the new default root
   */
  protected AbstractElement createDefaultRoot()
  {
    AbstractDocument.AttributeContext ctx = getAttributeContext();

    // Create html element.
    AttributeSet atts = ctx.getEmptySet();
    atts = ctx.addAttribute(atts, StyleConstants.NameAttribute, HTML.Tag.HTML);
    BranchElement html = (BranchElement) createBranchElement(null, atts);

    // Create body element.
    atts = ctx.getEmptySet();
    atts = ctx.addAttribute(atts, StyleConstants.NameAttribute, HTML.Tag.BODY);
    BranchElement body = (BranchElement) createBranchElement(html, atts);
    html.replace(0, 0, new Element[] { body });

    // Create p element.
    atts = ctx.getEmptySet();
    atts = ctx.addAttribute(atts, StyleConstants.NameAttribute, HTML.Tag.P);
    BranchElement p = (BranchElement) createBranchElement(body, atts);
    body.replace(0, 0, new Element[] { p });

    // Create an empty leaf element.
    atts = ctx.getEmptySet();
    atts = ctx.addAttribute(atts, StyleConstants.NameAttribute,
                            HTML.Tag.CONTENT);
    Element leaf = createLeafElement(p, atts, 0, 1);
    p.replace(0, 0, new Element[]{ leaf });

    return html;
  }

  /**
   * This method returns an HTMLDocument.RunElement object attached to
   * parent representing a run of text from p0 to p1. The run has
   * attributes described by a.
   *
   * @param parent - the parent element
   * @param a - the attributes for the element
   * @param p0 - the beginning of the range >= 0
   * @param p1 - the end of the range >= p0
   *
   * @return the new element
   */
  protected Element createLeafElement(Element parent, AttributeSet a, int p0,
                                      int p1)
  {
    return new RunElement(parent, a, p0, p1);
  }

  /**
   * This method returns an HTMLDocument.BlockElement object representing the
   * attribute set a and attached to parent.
   *
   * @param parent - the parent element
   * @param a - the attributes for the element
   *
   * @return the new element
   */
  protected Element createBranchElement(Element parent, AttributeSet a)
  {
    return new BlockElement(parent, a);
  }

  /**
   * Returns the parser used by this HTMLDocument to insert HTML.
   *
   * @return the parser used by this HTMLDocument to insert HTML.
   */
  public HTMLEditorKit.Parser getParser()
  {
    return parser;
  }

  /**
   * Sets the parser used by this HTMLDocument to insert HTML.
   *
   * @param p the parser to use
   */
  public void setParser (HTMLEditorKit.Parser p)
  {
    parser = p;
  }
  /**
   * Sets the number of tokens to buffer before trying to display the
   * Document.
   *
   * @param n the number of tokens to buffer
   */
  public void setTokenThreshold (int n)
  {
    tokenThreshold = n;
  }

  /**
   * Returns the number of tokens that are buffered before the document
   * is rendered.
   *
   * @return the number of tokens buffered
   */
  public int getTokenThreshold ()
  {
    return tokenThreshold;
  }

  /**
   * Returns the location against which to resolve relative URLs.
   * This is the document's URL if the document was loaded from a URL.
   * If a <code>base</code> tag is found, it will be used.
   * @return the base URL
   */
  public URL getBase()
  {
    return baseURL;
  }

  /**
   * Sets the location against which to resolve relative URLs.
   * @param u the new base URL
   */
  public void setBase(URL u)
  {
    baseURL = u;
    getStyleSheet().setBase(u);
  }

  /**
   * Returns whether or not the parser preserves unknown HTML tags.
   * @return true if the parser preserves unknown tags
   */
  public boolean getPreservesUnknownTags()
  {
    return preservesUnknownTags;
  }

  /**
   * Sets the behaviour of the parser when it encounters unknown HTML tags.
   * @param preservesTags true if the parser should preserve unknown tags.
   */
  public void setPreservesUnknownTags(boolean preservesTags)
  {
    preservesUnknownTags = preservesTags;
  }

  /**
   * An iterator to iterate through LeafElements in the document.
   */
  class LeafIterator extends Iterator
  {
    HTML.Tag tag;
    HTMLDocument doc;
    ElementIterator it;

    public LeafIterator (HTML.Tag t, HTMLDocument d)
    {
      doc = d;
      tag = t;
      it = new ElementIterator(doc);
    }

    /**
     * Return the attributes for the tag associated with this iteartor
     * @return the AttributeSet
     */
    public AttributeSet getAttributes()
    {
      if (it.current() != null)
        return it.current().getAttributes();
      return null;
    }

    /**
     * Get the end of the range for the current occurrence of the tag
     * being defined and having the same attributes.
     * @return the end of the range
     */
    public int getEndOffset()
    {
      if (it.current() != null)
        return it.current().getEndOffset();
      return -1;
    }

    /**
     * Get the start of the range for the current occurrence of the tag
     * being defined and having the same attributes.
     * @return the start of the range (-1 if it can't be found).
     */

    public int getStartOffset()
    {
      if (it.current() != null)
        return it.current().getStartOffset();
      return -1;
    }

    /**
     * Advance the iterator to the next LeafElement .
     */
    public void next()
    {
      it.next();
      while (it.current()!= null && !it.current().isLeaf())
        it.next();
    }

    /**
     * Indicates whether or not the iterator currently represents an occurrence
     * of the tag.
     * @return true if the iterator currently represents an occurrence of the
     * tag.
     */
    public boolean isValid()
    {
      return it.current() != null;
    }

    /**
     * Type of tag for this iterator.
     */
    public Tag getTag()
    {
      return tag;
    }

  }

  public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent event)
  {
    String target = event.getTarget();
    Element el = event.getSourceElement();
    URL url = event.getURL();
    if (target.equals("_self"))
      {
        updateFrame(el, url);
      }
    else if (target.equals("_parent"))
      {
        updateFrameSet(el.getParentElement(), url);
      }
    else
      {
        Element targetFrame = findFrame(target);
        if (targetFrame != null)
          updateFrame(targetFrame, url);
      }
  }

  /**
   * Finds the named frame inside this document.
   *
   * @param target the name to look for
   *
   * @return the frame if there is a matching frame, <code>null</code>
   *         otherwise
   */
  private Element findFrame(String target)
  {
    ElementIterator i = new ElementIterator(this);
    Element next = null;
    while ((next = i.next()) != null)
      {
        AttributeSet atts = next.getAttributes();
        if (atts.getAttribute(StyleConstants.NameAttribute) == HTML.Tag.FRAME)
          {
            String name = (String) atts.getAttribute(HTML.Attribute.NAME);
            if (name != null && name.equals(target))
              break;
          }
      }
    return next;
  }

  /**
   * Updates the frame that is represented by the specified element to
   * refer to the specified URL.
   *
   * @param el the element
   * @param url the new url
   */
  private void updateFrame(Element el, URL url)
  {
    try
      {
        writeLock();
        DefaultDocumentEvent ev =
          new DefaultDocumentEvent(el.getStartOffset(), 1,
                                   DocumentEvent.EventType.CHANGE);
        AttributeSet elAtts = el.getAttributes();
        AttributeSet copy = elAtts.copyAttributes();
        MutableAttributeSet matts = (MutableAttributeSet) elAtts;
        ev.addEdit(new AttributeUndoableEdit(el, copy, false));
        matts.removeAttribute(HTML.Attribute.SRC);
        matts.addAttribute(HTML.Attribute.SRC, url.toString());
        ev.end();
        fireChangedUpdate(ev);
        fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
      }
    finally
      {
        writeUnlock();
      }
  }

  /**
   * Updates the frameset that is represented by the specified element
   * to create a frame that refers to the specified URL.
   *
   * @param el the element
   * @param url the url
   */
  private void updateFrameSet(Element el, URL url)
  {
    int start = el.getStartOffset();
    int end = el.getEndOffset();

    StringBuilder html = new StringBuilder();
    html.append("<frame");
    if (url != null)
      {
        html.append(" src=\"");
        html.append(url.toString());
        html.append("\"");
      }
    html.append('>');
    if (getParser() == null)
      setParser(new HTMLEditorKit().getParser());
    try
      {
        setOuterHTML(el, html.toString());
      }
    catch (BadLocationException ex)
      {
        ex.printStackTrace();
      }
    catch (IOException ex)
      {
        ex.printStackTrace();
      }
  }

  /**
   * Gets an iterator for the given HTML.Tag.
   * @param t the requested HTML.Tag
   * @return the Iterator
   */
  public HTMLDocument.Iterator getIterator (HTML.Tag t)
  {
    return new HTMLDocument.LeafIterator(t, this);
  }

  /**
   * An iterator over a particular type of tag.
   */
  public abstract static class Iterator
  {
    /**
     * Return the attribute set for this tag.
     * @return the <code>AttributeSet</code> (null if none found).
     */
    public abstract AttributeSet getAttributes();

    /**
     * Get the end of the range for the current occurrence of the tag
     * being defined and having the same attributes.
     * @return the end of the range
     */
    public abstract int getEndOffset();

    /**
     * Get the start of the range for the current occurrence of the tag
     * being defined and having the same attributes.
     * @return the start of the range (-1 if it can't be found).
     */
    public abstract int getStartOffset();

    /**
     * Move the iterator forward.
     */
    public abstract void next();

    /**
     * Indicates whether or not the iterator currently represents an occurrence
     * of the tag.
     * @return true if the iterator currently represents an occurrence of the
     * tag.
     */
    public abstract boolean isValid();

    /**
     * Type of tag this iterator represents.
     * @return the tag.
     */
    public abstract HTML.Tag getTag();
  }

  public class BlockElement extends AbstractDocument.BranchElement
  {
    public BlockElement (Element parent, AttributeSet a)
    {
      super(parent, a);
    }

    /**
     * Gets the resolving parent.  Since HTML attributes are not
     * inherited at the model level, this returns null.
     */
    public AttributeSet getResolveParent()
    {
      return null;
    }

    /**
     * Gets the name of the element.
     *
     * @return the name of the element if it exists, null otherwise.
     */
    public String getName()
    {
      Object tag = getAttribute(StyleConstants.NameAttribute);
      String name = null;
      if (tag != null)
        name = tag.toString();
      if (name == null)
        name = super.getName();
      return name;
    }
  }

  /**
   * RunElement represents a section of text that has a set of
   * HTML character level attributes assigned to it.
   */
  public class RunElement extends AbstractDocument.LeafElement
  {

    /**
     * Constructs an element that has no children. It represents content
     * within the document.
     *
     * @param parent - parent of this
     * @param a - elements attributes
     * @param start - the start offset >= 0
     * @param end - the end offset
     */
    public RunElement(Element parent, AttributeSet a, int start, int end)
    {
      super(parent, a, start, end);
    }

    /**
     * Gets the name of the element.
     *
     * @return the name of the element if it exists, null otherwise.
     */
    public String getName()
    {
      Object tag = getAttribute(StyleConstants.NameAttribute);
      String name = null;
      if (tag != null)
        name = tag.toString();
      if (name == null)
        name = super.getName();
      return name;
    }

    /**
     * Gets the resolving parent. HTML attributes do not inherit at the
     * model level, so this method returns null.
     *
     * @return null
     */
    public AttributeSet getResolveParent()
    {
      return null;
    }
  }

  /**
   * A reader to load an HTMLDocument with HTML structure.
   *
   * @author Anthony Balkissoon abalkiss at redhat dot com
   */
  public class HTMLReader extends HTMLEditorKit.ParserCallback
  {
    /**
     * The maximum token threshold. We don't grow it larger than this.
     */
    private static final int MAX_THRESHOLD = 10000;

    /**
     * The threshold growth factor.
     */
    private static final int GROW_THRESHOLD = 5;

    /**
     * Holds the current character attribute set *
     */
    protected MutableAttributeSet charAttr = new SimpleAttributeSet();

    protected Vector<ElementSpec> parseBuffer = new Vector<ElementSpec>();

    /**
     * The parse stack. It holds the current element tree path.
     */
    private Stack<HTML.Tag> parseStack = new Stack<HTML.Tag>();

    /**
     * A stack for character attribute sets *
     */
    Stack charAttrStack = new Stack();

    /** A mapping between HTML.Tag objects and the actions that handle them **/
    HashMap tagToAction;

    /** Tells us whether we've received the '</html>' tag yet **/
    boolean endHTMLEncountered = false;

    /**
     * Related to the constructor with explicit insertTag
     */
    int popDepth;

    /**
     * Related to the constructor with explicit insertTag
     */
    int pushDepth;

    /**
     * Related to the constructor with explicit insertTag
     */
    int offset;

    /**
     * The tag (inclusve), after that the insertion should start.
     */
    HTML.Tag insertTag;

    /**
     * This variable becomes true after the insert tag has been encountered.
     */
    boolean insertTagEncountered;


    /** A temporary variable that helps with the printing out of debug information **/
    boolean debug = false;

    /**
     * This is true when we are inside a pre tag.
     */
    boolean inPreTag = false;

    /**
     * This is true when we are inside a style tag. This will add text
     * content inside this style tag beeing parsed as CSS.
     *
     * This is package private to avoid accessor methods.
     */
    boolean inStyleTag = false;

    /**
     * This is true when we are inside a &lt;textarea&gt; tag. Any text
     * content will then be added to the text area.
     *
     * This is package private to avoid accessor methods.
     */
    boolean inTextArea = false;

    /**
     * This contains all stylesheets that are somehow read, either
     * via embedded style tags, or via linked stylesheets. The
     * elements will be String objects containing a stylesheet each.
     */
    ArrayList styles;

    /**
     * The document model for a textarea.
     *
     * This is package private to avoid accessor methods.
     */
    ResetablePlainDocument textAreaDocument;

    /**
     * The current model of a select tag. Can be a ComboBoxModel or a
     * ListModel depending on the type of the select box.
     */
    Object selectModel;

    /**
     * The current option beeing read.
     */
    Option option;

    /**
     * The current number of options in the current select model.
     */
    int numOptions;

    /**
     * The current button groups mappings.
     */
    HashMap buttonGroups;

    /**
     * The token threshold. This gets increased while loading.
     */
    private int threshold;

    public class TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.  By default this does nothing.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        // Nothing to do here.
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.  By default does nothing.
       */
      public void end(HTML.Tag t)
      {
        // Nothing to do here.
      }
    }

    public class BlockAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        // Tell the parse buffer to open a new block for this tag.
        blockOpen(t, a);
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
      {
        // Tell the parse buffer to close this block.
        blockClose(t);
      }
    }

    public class CharacterAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        // Put the old attribute set on the stack.
        pushCharacterStyle();

        // Initialize with link pseudo class.
        if (t == HTML.Tag.A)
          a.addAttribute(HTML.Attribute.PSEUDO_CLASS, "link");

        // Just add the attributes in <code>a</code>.
        charAttr.addAttribute(t, a.copyAttributes());
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
      {
        popCharacterStyle();
      }
    }

    /**
     * Processes elements that make up forms: &lt;input&gt;, &lt;textarea&gt;,
     * &lt;select&gt; and &lt;option&gt;.
     */
    public class FormAction extends SpecialAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        if (t == HTML.Tag.INPUT)
          {
            String type = (String) a.getAttribute(HTML.Attribute.TYPE);
            if (type == null)
              {
                type = "text"; // Default to 'text' when nothing was specified.
                a.addAttribute(HTML.Attribute.TYPE, type);
              }
            setModel(type, a);
          }
        else if (t == HTML.Tag.TEXTAREA)
          {
            inTextArea = true;
            textAreaDocument = new ResetablePlainDocument();
            a.addAttribute(StyleConstants.ModelAttribute, textAreaDocument);
          }
        else if (t == HTML.Tag.SELECT)
          {
            int size = HTML.getIntegerAttributeValue(a, HTML.Attribute.SIZE,
                                                     1);
            boolean multi = a.getAttribute(HTML.Attribute.MULTIPLE) != null;
            if (size > 1 || multi)
              {
                SelectListModel m = new SelectListModel();
                if (multi)
                  m.getSelectionModel().setSelectionMode(ListSelectionModel
                                                 .MULTIPLE_INTERVAL_SELECTION);
                selectModel = m;
              }
            else
              {
                selectModel = new SelectComboBoxModel();
              }
            a.addAttribute(StyleConstants.ModelAttribute, selectModel);
          }
        if (t == HTML.Tag.OPTION)
          {
            option = new Option(a);
            if (selectModel instanceof SelectListModel)
              {
                SelectListModel m = (SelectListModel) selectModel;
                m.addElement(option);
                if (option.isSelected())
                  {
                    m.getSelectionModel().addSelectionInterval(numOptions,
                                                               numOptions);
                    m.addInitialSelection(numOptions);
                  }
              }
            else if (selectModel instanceof SelectComboBoxModel)
              {
                SelectComboBoxModel m = (SelectComboBoxModel) selectModel;
                m.addElement(option);
                if (option.isSelected())
                  {
                    m.setSelectedItem(option);
                    m.setInitialSelection(option);
                  }
              }
            numOptions++;
          }
        else
          {
            // Build the element.
            super.start(t, a);
          }
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
      {
        if (t == HTML.Tag.OPTION)
          {
            option = null;
          }
        else
          {
            if (t == HTML.Tag.TEXTAREA)
              {
                inTextArea = false;
              }
            else if (t == HTML.Tag.SELECT)
              {
                selectModel = null;
                numOptions = 0;
              }
            // Finish the element.
            super.end(t);
          }
      }

      private void setModel(String type, MutableAttributeSet attrs)
      {
        if (type.equals("submit") || type.equals("reset")
            || type.equals("image"))
          {
            // Create button.
            attrs.addAttribute(StyleConstants.ModelAttribute,
                               new DefaultButtonModel());
          }
        else if (type.equals("text") || type.equals("password"))
          {
            String text = (String) attrs.getAttribute(HTML.Attribute.VALUE);
            ResetablePlainDocument doc = new ResetablePlainDocument();
            if (text != null)
              {
                doc.setInitialText(text);
                try
                  {
                    doc.insertString(0, text, null);
                  }
                catch (BadLocationException ex)
                  {
                    // Shouldn't happen.
                    assert false;
                  }
              }
            attrs.addAttribute(StyleConstants.ModelAttribute, doc);
          }
        else if (type.equals("file"))
          {
            attrs.addAttribute(StyleConstants.ModelAttribute,
                               new PlainDocument());
          }
        else if (type.equals("checkbox") || type.equals("radio"))
          {
            ResetableToggleButtonModel model =
              new ResetableToggleButtonModel();
            if (attrs.getAttribute(HTML.Attribute.SELECTED) != null)
              {
                model.setSelected(true);
                model.setInitial(true);
              }
            if (type.equals("radio"))
              {
                String name = (String) attrs.getAttribute(HTML.Attribute.NAME);
                if (name != null)
                  {
                    if (buttonGroups == null)
                      buttonGroups = new HashMap();
                    ButtonGroup group = (ButtonGroup) buttonGroups.get(name);
                    if (group == null)
                      {
                        group = new ButtonGroup();
                        buttonGroups.put(name, group);
                      }
                    model.setGroup(group);
                  }
              }
            attrs.addAttribute(StyleConstants.ModelAttribute, model);
          }
      }
    }

    /**
     * Called for form tags.
     */
    class FormTagAction
      extends BlockAction
    {
      /**
       * Clears the button group mapping.
       */
      public void end(HTML.Tag t)
      {
        super.end(t);
        buttonGroups = null;
      }
    }

    /**
     * This action indicates that the content between starting and closing HTML
     * elements (like script - /script) should not be visible. The content is
     * still inserted and can be accessed when iterating the HTML document. The
     * parser will only fire
     * {@link javax.swing.text.html.HTMLEditorKit.ParserCallback#handleText} for
     * the hidden tags, regardless from that html tags the hidden section may
     * contain.
     */
    public class HiddenAction
        extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        blockOpen(t, a);
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
      {
        blockClose(t);
      }
    }

    /**
     * Handles &lt;isindex&gt; tags.
     */
    public class IsindexAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        blockOpen(HTML.Tag.IMPLIED, new SimpleAttributeSet());
        addSpecialElement(t, a);
        blockClose(HTML.Tag.IMPLIED);
      }
    }

    public class ParagraphAction extends BlockAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        super.start(t, a);
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
      {
        super.end(t);
      }
    }

    /**
     * This action is performed when a &lt;pre&gt; tag is parsed.
     */
    public class PreAction extends BlockAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        inPreTag = true;
        blockOpen(t, a);
        a.addAttribute(CSS.Attribute.WHITE_SPACE, "pre");
        blockOpen(HTML.Tag.IMPLIED, a);
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
      {
        blockClose(HTML.Tag.IMPLIED);
        inPreTag = false;
        blockClose(t);
      }
    }

    /**
     * Inserts the elements that are represented by ths single tag with
     * attributes (only). The closing tag, even if present, mut follow
     * immediately after the starting tag without providing any additional
     * information. Hence the {@link TagAction#end} method need not be
     * overridden and still does nothing.
     */
    public class SpecialAction extends TagAction
    {
      /**
       * The functionality is delegated to {@link HTMLReader#addSpecialElement}
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        addSpecialElement(t, a);
      }
    }

    class AreaAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
        throws NotImplementedException
      {
        // FIXME: Implement.
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
        throws NotImplementedException
      {
        // FIXME: Implement.
      }
    }

    /**
     * Converts HTML tags to CSS attributes.
     */
    class ConvertAction
      extends TagAction
    {

      public void start(HTML.Tag tag, MutableAttributeSet atts)
      {
        pushCharacterStyle();
        charAttr.addAttribute(tag, atts.copyAttributes());
        StyleSheet styleSheet = getStyleSheet();
        // TODO: Add other tags here.
        if (tag == HTML.Tag.FONT)
          {
            String color = (String) atts.getAttribute(HTML.Attribute.COLOR);
            if (color != null)
              styleSheet.addCSSAttribute(charAttr, CSS.Attribute.COLOR, color);
            String face = (String) atts.getAttribute(HTML.Attribute.FACE);
            if (face != null)
              styleSheet.addCSSAttribute(charAttr, CSS.Attribute.FONT_FAMILY,
                                         face);
            String size = (String) atts.getAttribute(HTML.Attribute.SIZE);
            if (size != null)
              styleSheet.addCSSAttribute(charAttr, CSS.Attribute.FONT_SIZE,
                                         size);
          }
      }

      public void end(HTML.Tag tag)
      {
        popCharacterStyle();
      }
    }

    class BaseAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        baseTarget = (String) a.getAttribute(HTML.Attribute.TARGET);
      }
    }

    class HeadAction extends BlockAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
        throws NotImplementedException
      {
        // FIXME: Implement.
        super.start(t, a);
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
      {
        // We read in all the stylesheets that are embedded or referenced
        // inside the header.
        if (styles != null)
          {
            int numStyles = styles.size();
            for (int i = 0; i < numStyles; i++)
              {
                String style = (String) styles.get(i);
                getStyleSheet().addRule(style);
              }
          }
        super.end(t);
      }
    }

    class LinkAction extends HiddenAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        super.start(t, a);
        String type = (String) a.getAttribute(HTML.Attribute.TYPE);
        if (type == null)
          type = "text/css";
        if (type.equals("text/css"))
          {
            String rel = (String) a.getAttribute(HTML.Attribute.REL);
            String media = (String) a.getAttribute(HTML.Attribute.MEDIA);
            String title = (String) a.getAttribute(HTML.Attribute.TITLE);
            if (media == null)
              media = "all";
            else
              media = media.toLowerCase();
            if (rel != null)
              {
                rel = rel.toLowerCase();
                if ((media.indexOf("all") != -1
                     || media.indexOf("screen") != -1)
                    && (rel.equals("stylesheet")))
                  {
                    String href = (String) a.getAttribute(HTML.Attribute.HREF);
                    URL url = null;
                    try
                      {
                        url = new URL(baseURL, href);
                      }
                    catch (MalformedURLException ex)
                      {
                        try
                          {
                            url = new URL(href);
                          }
                        catch (MalformedURLException ex2)
                          {
                            url = null;
                          }
                      }
                    if (url != null)
                      {
                        try
                          {
                            getStyleSheet().importStyleSheet(url);
                          }
                        catch (Exception ex)
                          {
                            // Don't let exceptions and runtime exceptions
                            // in CSS parsing disprupt the HTML parsing
                            // process. But inform the user/developer
                            // on the console about it.
                            ex.printStackTrace();
                          }
                      }
                  }
              }
          }
      }

    }

    class MapAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
        throws NotImplementedException
      {
        // FIXME: Implement.
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
        throws NotImplementedException
      {
        // FIXME: Implement.
      }
    }

    class MetaAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
        throws NotImplementedException
      {
        // FIXME: Implement.
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
        throws NotImplementedException
      {
        // FIXME: Implement.
      }
    }

    class StyleAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
      {
        inStyleTag = true;
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
      {
        inStyleTag = false;
      }
    }

    class TitleAction extends TagAction
    {
      /**
       * This method is called when a start tag is seen for one of the types
       * of tags associated with this Action.
       */
      public void start(HTML.Tag t, MutableAttributeSet a)
        throws NotImplementedException
      {
        // FIXME: Implement.
      }

      /**
       * Called when an end tag is seen for one of the types of tags associated
       * with this Action.
       */
      public void end(HTML.Tag t)
        throws NotImplementedException
      {
        // FIXME: Implement.
      }
    }

    public HTMLReader(int offset)
    {
      this (offset, 0, 0, null);
    }

    public HTMLReader(int offset, int popDepth, int pushDepth,
                      HTML.Tag insertTag)
    {
      this.insertTag = insertTag;
      this.offset = offset;
      this.popDepth = popDepth;
      this.pushDepth = pushDepth;
      threshold = getTokenThreshold();
      initTags();
    }

    void initTags()
    {
      tagToAction = new HashMap(72);
      CharacterAction characterAction = new CharacterAction();
      HiddenAction hiddenAction = new HiddenAction();
      AreaAction areaAction = new AreaAction();
      BaseAction baseAction = new BaseAction();
      BlockAction blockAction = new BlockAction();
      SpecialAction specialAction = new SpecialAction();
      ParagraphAction paragraphAction = new ParagraphAction();
      HeadAction headAction = new HeadAction();
      FormAction formAction = new FormAction();
      IsindexAction isindexAction = new IsindexAction();
      LinkAction linkAction = new LinkAction();
      MapAction mapAction = new MapAction();
      PreAction preAction = new PreAction();
      MetaAction metaAction = new MetaAction();
      StyleAction styleAction = new StyleAction();
      TitleAction titleAction = new TitleAction();

      ConvertAction convertAction = new ConvertAction();
      tagToAction.put(HTML.Tag.A, characterAction);
      tagToAction.put(HTML.Tag.ADDRESS, characterAction);
      tagToAction.put(HTML.Tag.APPLET, hiddenAction);
      tagToAction.put(HTML.Tag.AREA, areaAction);
      tagToAction.put(HTML.Tag.B, characterAction);
      tagToAction.put(HTML.Tag.BASE, baseAction);
      tagToAction.put(HTML.Tag.BASEFONT, characterAction);
      tagToAction.put(HTML.Tag.BIG, characterAction);
      tagToAction.put(HTML.Tag.BLOCKQUOTE, blockAction);
      tagToAction.put(HTML.Tag.BODY, blockAction);
      tagToAction.put(HTML.Tag.BR, specialAction);
      tagToAction.put(HTML.Tag.CAPTION, blockAction);
      tagToAction.put(HTML.Tag.CENTER, blockAction);
      tagToAction.put(HTML.Tag.CITE, characterAction);
      tagToAction.put(HTML.Tag.CODE, characterAction);
      tagToAction.put(HTML.Tag.DD, blockAction);
      tagToAction.put(HTML.Tag.DFN, characterAction);
      tagToAction.put(HTML.Tag.DIR, blockAction);
      tagToAction.put(HTML.Tag.DIV, blockAction);
      tagToAction.put(HTML.Tag.DL, blockAction);
      tagToAction.put(HTML.Tag.DT, paragraphAction);
      tagToAction.put(HTML.Tag.EM, characterAction);
      tagToAction.put(HTML.Tag.FONT, convertAction);
      tagToAction.put(HTML.Tag.FORM, new FormTagAction());
      tagToAction.put(HTML.Tag.FRAME, specialAction);
      tagToAction.put(HTML.Tag.FRAMESET, blockAction);
      tagToAction.put(HTML.Tag.H1, paragraphAction);
      tagToAction.put(HTML.Tag.H2, paragraphAction);
      tagToAction.put(HTML.Tag.H3, paragraphAction);
      tagToAction.put(HTML.Tag.H4, paragraphAction);
      tagToAction.put(HTML.Tag.H5, paragraphAction);
      tagToAction.put(HTML.Tag.H6, paragraphAction);
      tagToAction.put(HTML.Tag.HEAD, headAction);
      tagToAction.put(HTML.Tag.HR, specialAction);
      tagToAction.put(HTML.Tag.HTML, blockAction);
      tagToAction.put(HTML.Tag.I, characterAction);
      tagToAction.put(HTML.Tag.IMG, specialAction);
      tagToAction.put(HTML.Tag.INPUT, formAction);
      tagToAction.put(HTML.Tag.ISINDEX, isindexAction);
      tagToAction.put(HTML.Tag.KBD, characterAction);
      tagToAction.put(HTML.Tag.LI, blockAction);
      tagToAction.put(HTML.Tag.LINK, linkAction);
      tagToAction.put(HTML.Tag.MAP, mapAction);
      tagToAction.put(HTML.Tag.MENU, blockAction);
      tagToAction.put(HTML.Tag.META, metaAction);
      tagToAction.put(HTML.Tag.NOFRAMES, blockAction);
      tagToAction.put(HTML.Tag.OBJECT, specialAction);
      tagToAction.put(HTML.Tag.OL, blockAction);
      tagToAction.put(HTML.Tag.OPTION, formAction);
      tagToAction.put(HTML.Tag.P, paragraphAction);
      tagToAction.put(HTML.Tag.PARAM, hiddenAction);
      tagToAction.put(HTML.Tag.PRE, preAction);
      tagToAction.put(HTML.Tag.SAMP, characterAction);
      tagToAction.put(HTML.Tag.SCRIPT, hiddenAction);
      tagToAction.put(HTML.Tag.SELECT, formAction);
      tagToAction.put(HTML.Tag.SMALL, characterAction);
      tagToAction.put(HTML.Tag.STRIKE, characterAction);
      tagToAction.put(HTML.Tag.S, characterAction);
      tagToAction.put(HTML.Tag.STRONG, characterAction);
      tagToAction.put(HTML.Tag.STYLE, styleAction);
      tagToAction.put(HTML.Tag.SUB, characterAction);
      tagToAction.put(HTML.Tag.SUP, characterAction);
      tagToAction.put(HTML.Tag.TABLE, blockAction);
      tagToAction.put(HTML.Tag.TD, blockAction);
      tagToAction.put(HTML.Tag.TEXTAREA, formAction);
      tagToAction.put(HTML.Tag.TH, blockAction);
      tagToAction.put(HTML.Tag.TITLE, titleAction);
      tagToAction.put(HTML.Tag.TR, blockAction);
      tagToAction.put(HTML.Tag.TT, characterAction);
      tagToAction.put(HTML.Tag.U, characterAction);
      tagToAction.put(HTML.Tag.UL, blockAction);
      tagToAction.put(HTML.Tag.VAR, characterAction);
    }

    /**
     * Pushes the current character style onto the stack.
     *
     */
    protected void pushCharacterStyle()
    {
      charAttrStack.push(charAttr.copyAttributes());
    }

    /**
     * Pops a character style off of the stack and uses it as the
     * current character style.
     *
     */
    protected void popCharacterStyle()
    {
      if (!charAttrStack.isEmpty())
        charAttr = (MutableAttributeSet) charAttrStack.pop();
    }

    /**
     * Registers a given tag with a given Action.  All of the well-known tags
     * are registered by default, but this method can change their behaviour
     * or add support for custom or currently unsupported tags.
     *
     * @param t the Tag to register
     * @param a the Action for the Tag
     */
    protected void registerTag(HTML.Tag t, HTMLDocument.HTMLReader.TagAction a)
    {
      tagToAction.put (t, a);
    }

    /**
     * This is the last method called on the HTMLReader, allowing any pending
     * changes to be flushed to the HTMLDocument.
     */
    public void flush() throws BadLocationException
    {
      flushImpl();
    }

    /**
     * Flushes the buffer and handle partial inserts.
     *
     */
    private void flushImpl()
      throws BadLocationException
    {
      int oldLen = getLength();
      int size = parseBuffer.size();
      ElementSpec[] elems = new ElementSpec[size];
      parseBuffer.copyInto(elems);
      if (oldLen == 0)
        create(elems);
      else
        insert(offset, elems);
      parseBuffer.removeAllElements();
      offset += getLength() - oldLen;
    }

    /**
     * This method is called by the parser to indicate a block of
     * text was encountered.  Should insert the text appropriately.
     *
     * @param data the text that was inserted
     * @param pos the position at which the text was inserted
     */
    public void handleText(char[] data, int pos)
    {
      if (shouldInsert() && data != null && data.length > 0)
        {
          if (inTextArea)
            textAreaContent(data);
          else if (inPreTag)
            preContent(data);
          else if (option != null)
            option.setLabel(new String(data));
          else if (inStyleTag)
            {
              if (styles == null)
                styles = new ArrayList();
              styles.add(new String(data));
            }
          else
            addContent(data, 0, data.length);

        }
    }

    /**
     * Checks if the HTML tag should be inserted. The tags before insert tag (if
     * specified) are not inserted. Also, the tags after the end of the html are
     * not inserted.
     *
     * @return true if the tag should be inserted, false otherwise.
     */
    private boolean shouldInsert()
    {
      return ! endHTMLEncountered
             && (insertTagEncountered || insertTag == null);
    }

    /**
     * This method is called by the parser and should route the call to the
     * proper handler for the tag.
     *
     * @param t the HTML.Tag
     * @param a the attribute set
     * @param pos the position at which the tag was encountered
     */
    public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos)
    {
      if (t == insertTag)
        insertTagEncountered = true;

      if (shouldInsert())
        {
          TagAction action = (TagAction) tagToAction.get(t);
          if (action != null)
            action.start(t, a);
        }
    }

    /**
     * This method called by parser to handle a comment block.
     *
     * @param data the comment
     * @param pos the position at which the comment was encountered
     */
    public void handleComment(char[] data, int pos)
    {
      if (shouldInsert())
        {
          TagAction action = (TagAction) tagToAction.get(HTML.Tag.COMMENT);
          if (action != null)
            {
              action.start(HTML.Tag.COMMENT, new SimpleAttributeSet());
              action.end(HTML.Tag.COMMENT);
            }
        }
    }

    /**
     * This method is called by the parser and should route the call to the
     * proper handler for the tag.
     *
     * @param t the HTML.Tag
     * @param pos the position at which the tag was encountered
     */
    public void handleEndTag(HTML.Tag t, int pos)
    {
      if (shouldInsert())
        {
          // If this is the </html> tag we need to stop calling the Actions
          if (t == HTML.Tag.HTML)
            endHTMLEncountered = true;

          TagAction action = (TagAction) tagToAction.get(t);
          if (action != null)
            action.end(t);
        }
    }

    /**
     * This is a callback from the parser that should be routed to the
     * appropriate handler for the tag.
     *
     * @param t the HTML.Tag that was encountered
     * @param a the attribute set
     * @param pos the position at which the tag was encountered
     */
    public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos)
    {
      if (t == insertTag)
        insertTagEncountered = true;

      if (shouldInsert())
        {
          TagAction action = (TagAction) tagToAction.get(t);
          if (action != null)
            {
              action.start(t, a);
              action.end(t);
            }
        }
    }

    /**
     * This is invoked after the stream has been parsed but before it has been
     * flushed.
     *
     * @param eol one of \n, \r, or \r\n, whichever was encountered the most in
     * parsing the stream
     * @since 1.3
     */
    public void handleEndOfLineString(String eol)
    {
      // FIXME: Implement.
    }

    /**
     * Adds the given text to the textarea document.  Called only when we are
     * within a textarea.
     *
     * @param data the text to add to the textarea
     */
    protected void textAreaContent(char[] data)
    {
      try
        {
          int offset = textAreaDocument.getLength();
          String text = new String(data);
          textAreaDocument.setInitialText(text);
          textAreaDocument.insertString(offset, text, null);
        }
      catch (BadLocationException ex)
        {
          // Must not happen as we insert at a model location that we
          // got from the document itself.
          assert false;
        }
    }

    /**
     * Adds the given text that was encountered in a <PRE> element.
     * This adds synthesized lines to hold the text runs.
     *
     * @param data the text
     */
    protected void preContent(char[] data)
    {
      int start = 0;
      for (int i = 0; i < data.length; i++)
        {
          if (data[i] == '\n')
            {
              addContent(data, start, i - start + 1);
              blockClose(HTML.Tag.IMPLIED);
              MutableAttributeSet atts = new SimpleAttributeSet();
              atts.addAttribute(CSS.Attribute.WHITE_SPACE, "pre");
              blockOpen(HTML.Tag.IMPLIED, atts);
              start = i + 1;
            }
        }
      if (start < data.length)
        {
          // Add remaining last line.
          addContent(data, start, data.length - start);
        }
    }

    /**
     * Instructs the parse buffer to create a block element with the given
     * attributes.
     *
     * @param t the tag that requires opening a new block
     * @param attr the attribute set for the new block
     */
    protected void blockOpen(HTML.Tag t, MutableAttributeSet attr)
    {
      if (inImpliedParagraph())
        blockClose(HTML.Tag.IMPLIED);

      // Push the new tag on top of the stack.
      parseStack.push(t);

      DefaultStyledDocument.ElementSpec element;

      AbstractDocument.AttributeContext ctx = getAttributeContext();
      AttributeSet copy = attr.copyAttributes();
      copy = ctx.addAttribute(copy, StyleConstants.NameAttribute, t);
      element = new DefaultStyledDocument.ElementSpec(copy,
                               DefaultStyledDocument.ElementSpec.StartTagType);
      parseBuffer.addElement(element);
    }

    /**
     * Returns true when we are currently inside a paragraph, either
     * a real one or an implied, false otherwise.
     *
     * @return
     */
    private boolean inParagraph()
    {
      boolean inParagraph = false;
      if (! parseStack.isEmpty())
        {
          HTML.Tag top = parseStack.peek();
          inParagraph = top == HTML.Tag.P || top == HTML.Tag.IMPLIED;
        }
      return inParagraph;
    }

    private boolean inImpliedParagraph()
    {
      boolean inParagraph = false;
      if (! parseStack.isEmpty())
        {
          HTML.Tag top = parseStack.peek();
          inParagraph = top == HTML.Tag.IMPLIED;
        }
      return inParagraph;
    }

    /**
     * Instructs the parse buffer to close the block element associated with
     * the given HTML.Tag
     *
     * @param t the HTML.Tag that is closing its block
     */
    protected void blockClose(HTML.Tag t)
    {
      DefaultStyledDocument.ElementSpec element;

      if (inImpliedParagraph() && t != HTML.Tag.IMPLIED)
        blockClose(HTML.Tag.IMPLIED);

      // Pull the token from the stack.
      if (! parseStack.isEmpty()) // Just to be sure.
        parseStack.pop();

      // If the previous tag is a start tag then we insert a synthetic
      // content tag.
      DefaultStyledDocument.ElementSpec prev;
      prev = parseBuffer.size() > 0 ? (DefaultStyledDocument.ElementSpec)
                                parseBuffer.get(parseBuffer.size() - 1) : null;
      if (prev != null &&
          prev.getType() == DefaultStyledDocument.ElementSpec.StartTagType)
        {
          addContent(new char[]{' '}, 0, 1);
        }

      element = new DefaultStyledDocument.ElementSpec(null,
                                DefaultStyledDocument.ElementSpec.EndTagType);
      parseBuffer.addElement(element);
    }

    /**
     * Adds text to the appropriate context using the current character
     * attribute set.
     *
     * @param data the text to add
     * @param offs the offset at which to add it
     * @param length the length of the text to add
     */
    protected void addContent(char[] data, int offs, int length)
    {
      addContent(data, offs, length, true);
    }

    /**
     * Adds text to the appropriate context using the current character
     * attribute set, and possibly generating an IMPLIED Tag if necessary.
     *
     * @param data the text to add
     * @param offs the offset at which to add it
     * @param length the length of the text to add
     * @param generateImpliedPIfNecessary whether or not we should generate
     * an HTML.Tag.IMPLIED tag if necessary
     */
    protected void addContent(char[] data, int offs, int length,
                              boolean generateImpliedPIfNecessary)
    {
      if (generateImpliedPIfNecessary && ! inParagraph())
        {
          blockOpen(HTML.Tag.IMPLIED, new SimpleAttributeSet());
        }

      AbstractDocument.AttributeContext ctx = getAttributeContext();
      DefaultStyledDocument.ElementSpec element;
      AttributeSet attributes = null;

      // Copy the attribute set, don't use the same object because
      // it may change
      if (charAttr != null)
        attributes = charAttr.copyAttributes();
      else
        attributes = ctx.getEmptySet();
      attributes = ctx.addAttribute(attributes, StyleConstants.NameAttribute,
                                    HTML.Tag.CONTENT);
      element = new DefaultStyledDocument.ElementSpec(attributes,
                                DefaultStyledDocument.ElementSpec.ContentType,
                                data, offs, length);

      // Add the element to the buffer
      parseBuffer.addElement(element);

      if (parseBuffer.size() > threshold)
        {
          if (threshold <= MAX_THRESHOLD)
            threshold *= GROW_THRESHOLD;
          try
            {
              flushImpl();
            }
          catch (BadLocationException ble)
            {
              // TODO: what to do here?
            }
        }
    }

    /**
     * Adds content that is specified in the attribute set.
     *
     * @param t the HTML.Tag
     * @param a the attribute set specifying the special content
     */
    protected void addSpecialElement(HTML.Tag t, MutableAttributeSet a)
    {
      if (t != HTML.Tag.FRAME && ! inParagraph())
        {
          blockOpen(HTML.Tag.IMPLIED, new SimpleAttributeSet());
        }

      a.addAttribute(StyleConstants.NameAttribute, t);

      // The two spaces are required because some special elements like HR
      // must be broken. At least two characters are needed to break into the
      // two parts.
      DefaultStyledDocument.ElementSpec spec =
        new DefaultStyledDocument.ElementSpec(a.copyAttributes(),
          DefaultStyledDocument.ElementSpec.ContentType,
          new char[] {' '}, 0, 1 );
      parseBuffer.add(spec);
    }

  }

  /**
   * Gets the reader for the parser to use when loading the document with HTML.
   *
   * @param pos - the starting position
   * @return - the reader
   */
  public HTMLEditorKit.ParserCallback getReader(int pos)
  {
    return new HTMLReader(pos);
  }

  /**
   * Gets the reader for the parser to use when loading the document with HTML.
   *
   * @param pos - the starting position
   * @param popDepth - the number of EndTagTypes to generate before inserting
   * @param pushDepth - the number of StartTagTypes with a direction
   * of JoinNextDirection that should be generated before inserting,
   * but after the end tags have been generated.
   * @param insertTag - the first tag to start inserting into document
   * @return - the reader
   */
  public HTMLEditorKit.ParserCallback getReader(int pos,
                                                int popDepth,
                                                int pushDepth,
                                                HTML.Tag insertTag)
  {
    return new HTMLReader(pos, popDepth, pushDepth, insertTag);
  }

  /**
   * Gets the reader for the parser to use when inserting the HTML fragment into
   * the document. Checks if the parser is present, sets the parent in the
   * element stack and removes any actions for BODY (it can be only one body in
   * a HTMLDocument).
   *
   * @param pos - the starting position
   * @param popDepth - the number of EndTagTypes to generate before inserting
   * @param pushDepth - the number of StartTagTypes with a direction of
   *          JoinNextDirection that should be generated before inserting, but
   *          after the end tags have been generated.
   * @param insertTag - the first tag to start inserting into document
   * @param parent the element that will be the parent in the document. HTML
   *          parsing includes checks for the parent, so it must be available.
   * @return - the reader
   * @throws IllegalStateException if the parsert is not set.
   */
  public HTMLEditorKit.ParserCallback getInsertingReader(int pos, int popDepth,
                                                         int pushDepth,
                                                         HTML.Tag insertTag,
                                                         final Element parent)
      throws IllegalStateException
  {
    if (parser == null)
      throw new IllegalStateException("Parser has not been set");

    HTMLReader reader = new HTMLReader(pos, popDepth, pushDepth, insertTag)
    {
      /**
       * Ignore BODY.
       */
      public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos)
      {
        if (t != HTML.Tag.BODY)
          super.handleStartTag(t, a, pos);
      }

      /**
       * Ignore BODY.
       */
      public void handleEndTag(HTML.Tag t, int pos)
      {
        if (t != HTML.Tag.BODY)
          super.handleEndTag(t, pos);
      }
    };

    return reader;
  }

  /**
   * Gets the child element that contains the attribute with the value or null.
   * Not thread-safe.
   *
   * @param e - the element to begin search at
   * @param attribute - the desired attribute
   * @param value - the desired value
   * @return the element found with the attribute and value specified or null if
   *         it is not found.
   */
  public Element getElement(Element e, Object attribute, Object value)
  {
    if (e != null)
      {
        if (e.getAttributes().containsAttribute(attribute, value))
          return e;

        int count = e.getElementCount();
        for (int j = 0; j < count; j++)
          {
            Element child = e.getElement(j);
            if (child.getAttributes().containsAttribute(attribute, value))
              return child;

            Element grandChild = getElement(child, attribute, value);
            if (grandChild != null)
              return grandChild;
          }
      }
    return null;
  }

  /**
   * Returns the element that has the given id Attribute (for instance, &lt;p id
   * ='my paragraph &gt;'). If it is not found, null is returned. The HTML tag,
   * having this attribute, is not checked by this method and can be any. The
   * method is not thread-safe.
   *
   * @param attrId - the value of the attribute id to look for
   * @return the element that has the given id.
   */
  public Element getElement(String attrId)
  {
    return getElement(getDefaultRootElement(), HTML.Attribute.ID,
                      attrId);
  }

  /**
   * Replaces the children of the given element with the contents of
   * the string. The document must have an HTMLEditorKit.Parser set.
   * This will be seen as at least two events, n inserts followed by a remove.
   *
   * @param elem - the brance element whose children will be replaced
   * @param htmlText - the string to be parsed and assigned to element.
   * @throws BadLocationException
   * @throws IOException
   * @throws IllegalArgumentException - if elem is a leaf
   * @throws IllegalStateException - if an HTMLEditorKit.Parser has not been set
   */
  public void setInnerHTML(Element elem, String htmlText)
    throws BadLocationException, IOException
  {
    if (elem.isLeaf())
      throw new IllegalArgumentException("Element is a leaf");

    int start = elem.getStartOffset();
    int end = elem.getEndOffset();

    HTMLEditorKit.ParserCallback reader = getInsertingReader(
      end, 0, 0, HTML.Tag.BODY, elem);

    // TODO charset
    getParser().parse(new StringReader(htmlText), reader, true);

    // Remove the previous content
    remove(start, end - start);
  }

  /**
   * Replaces the given element in the parent with the string. When replacing a
   * leaf, this will attempt to make sure there is a newline present if one is
   * needed. This may result in an additional element being inserted. This will
   * be seen as at least two events, n inserts followed by a remove. The
   * HTMLEditorKit.Parser must be set.
   *
   * @param elem - the branch element whose parent will be replaced
   * @param htmlText - the string to be parsed and assigned to elem
   * @throws BadLocationException
   * @throws IOException
   * @throws IllegalStateException - if parser is not set
   */
public void setOuterHTML(Element elem, String htmlText)
      throws BadLocationException, IOException
  {
    // Remove the current element:
    int start = elem.getStartOffset();
    int end = elem.getEndOffset();

    remove(start, end-start);

    HTMLEditorKit.ParserCallback reader = getInsertingReader(
      start, 0, 0, HTML.Tag.BODY, elem);

    // TODO charset
    getParser().parse(new StringReader(htmlText), reader, true);
  }

  /**
   * Inserts the string before the start of the given element. The parser must
   * be set.
   *
   * @param elem - the element to be the root for the new text.
   * @param htmlText - the string to be parsed and assigned to elem
   * @throws BadLocationException
   * @throws IOException
   * @throws IllegalStateException - if parser has not been set
   */
  public void insertBeforeStart(Element elem, String htmlText)
      throws BadLocationException, IOException
  {
    HTMLEditorKit.ParserCallback reader = getInsertingReader(
      elem.getStartOffset(), 0, 0, HTML.Tag.BODY, elem);

    // TODO charset
    getParser().parse(new StringReader(htmlText), reader, true);
  }

  /**
   * Inserts the string at the end of the element. If elem's children are
   * leaves, and the character at elem.getEndOffset() - 1 is a newline, then it
   * will be inserted before the newline. The parser must be set.
   *
   * @param elem - the element to be the root for the new text
   * @param htmlText - the text to insert
   * @throws BadLocationException
   * @throws IOException
   * @throws IllegalStateException - if parser is not set
   */
  public void insertBeforeEnd(Element elem, String htmlText)
      throws BadLocationException, IOException
  {
    HTMLEditorKit.ParserCallback reader = getInsertingReader(
      elem.getEndOffset(), 0, 0, HTML.Tag.BODY, elem);

    // TODO charset
    getParser().parse(new StringReader(htmlText), reader, true);

  }

  /**
   * Inserts the string after the end of the given element.
   * The parser must be set.
   *
   * @param elem - the element to be the root for the new text
   * @param htmlText - the text to insert
   * @throws BadLocationException
   * @throws IOException
   * @throws IllegalStateException - if parser is not set
   */
  public void insertAfterEnd(Element elem, String htmlText)
      throws BadLocationException, IOException
  {
    HTMLEditorKit.ParserCallback reader = getInsertingReader(
      elem.getEndOffset(), 0, 0, HTML.Tag.BODY, elem);

    // TODO charset
    getParser().parse(new StringReader(htmlText), reader, true);
  }

  /**
   * Inserts the string at the start of the element.
   * The parser must be set.
   *
   * @param elem - the element to be the root for the new text
   * @param htmlText - the text to insert
   * @throws BadLocationException
   * @throws IOException
   * @throws IllegalStateException - if parser is not set
   */
  public void insertAfterStart(Element elem, String htmlText)
      throws BadLocationException, IOException
  {
    HTMLEditorKit.ParserCallback reader = getInsertingReader(
      elem.getStartOffset(), 0, 0, HTML.Tag.BODY, elem);

    // TODO charset
    getParser().parse(new StringReader(htmlText), reader, true);
  }

  /**
   * Overridden to tag content with the synthetic HTML.Tag.CONTENT
   * tag.
   */
  protected void insertUpdate(DefaultDocumentEvent evt, AttributeSet att)
  {
    if (att == null)
      {
        SimpleAttributeSet sas = new SimpleAttributeSet();
        sas.addAttribute(StyleConstants.NameAttribute, HTML.Tag.CONTENT);
        att = sas;
      }
    super.insertUpdate(evt, att);
  }

  /**
   * Returns <code>true</code> when this document is inside a frame,
   * <code>false</code> otherwise.
   *
   * @return <code>true</code> when this document is inside a frame,
   *         <code>false</code> otherwise
   */
  boolean isFrameDocument()
  {
    return frameDocument;
  }

  /**
   * Set <code>true</code> when this document is inside a frame,
   * <code>false</code> otherwise.
   *
   * @param frameDoc <code>true</code> when this document is inside a frame,
   *                 <code>false</code> otherwise
   */
  void setFrameDocument(boolean frameDoc)
  {
    frameDocument = frameDoc;
  }

  /**
   * Returns the target that is specified in the base tag, if this is the case.
   *
   * @return the target that is specified in the base tag, if this is the case
   */
  String getBaseTarget()
  {
    return baseTarget;
  }

  /**
   * Updates the A tag's pseudo class value in response to a hyperlink
   * action.
   *
   * @param el the corresponding element
   * @param value the new value
   */
  void updateSpecialClass(Element el, HTML.Attribute cl, String value)
  {
    try
    {
      writeLock();
      DefaultDocumentEvent ev =
        new DefaultDocumentEvent(el.getStartOffset(), 1,
                                 DocumentEvent.EventType.CHANGE);
      AttributeSet elAtts = el.getAttributes();
      AttributeSet anchorAtts = (AttributeSet) elAtts.getAttribute(HTML.Tag.A);
      if (anchorAtts != null)
        {
          AttributeSet copy = elAtts.copyAttributes();
          StyleSheet ss = getStyleSheet();
          if (value != null)
            {
              anchorAtts = ss.addAttribute(anchorAtts, cl, value);
            }
          else
            {
              anchorAtts = ss.removeAttribute(anchorAtts, cl);
            }
          MutableAttributeSet matts = (MutableAttributeSet) elAtts;
          ev.addEdit(new AttributeUndoableEdit(el, copy, false));
          matts.removeAttribute(HTML.Tag.A);
          matts.addAttribute(HTML.Tag.A, anchorAtts);
          ev.end();
          fireChangedUpdate(ev);
          fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
        }
    }
  finally
    {
      writeUnlock();
    }
  }

}
