/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.swing.text.html;

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.accessibility.*;
import java.text.BreakIterator;

/*
 * The AccessibleHTML class provide information about the contents
 * of a HTML document to assistive technologies.
 *
 * @author  Lynn Monsanto
 */
class AccessibleHTML implements Accessible {

    /**
     * The editor.
     */
    private JEditorPane editor;
    /**
     * Current model.
     */
    private Document model;
    /**
     * DocumentListener installed on the current model.
     */
    private DocumentListener docListener;
    /**
     * PropertyChangeListener installed on the editor
     */
    private PropertyChangeListener propChangeListener;
    /**
     * The root ElementInfo for the document
     */
    private ElementInfo rootElementInfo;
    /*
     * The root accessible context for the document
     */
    private RootHTMLAccessibleContext rootHTMLAccessibleContext;

    public AccessibleHTML(JEditorPane pane) {
        editor = pane;
        propChangeListener = new PropertyChangeHandler();
        setDocument(editor.getDocument());

        docListener = new DocumentHandler();
    }

    /**
     * Sets the document.
     */
    private void setDocument(Document document) {
        if (model != null) {
            model.removeDocumentListener(docListener);
        }
        if (editor != null) {
            editor.removePropertyChangeListener(propChangeListener);
        }
        this.model = document;
        if (model != null) {
            if (rootElementInfo != null) {
                rootElementInfo.invalidate(false);
            }
            buildInfo();
            model.addDocumentListener(docListener);
        }
        else {
            rootElementInfo = null;
        }
        if (editor != null) {
            editor.addPropertyChangeListener(propChangeListener);
        }
    }

    /**
     * Returns the Document currently presenting information for.
     */
    private Document getDocument() {
        return model;
    }

    /**
     * Returns the JEditorPane providing information for.
     */
    private JEditorPane getTextComponent() {
        return editor;
    }

    /**
     * Returns the ElementInfo representing the root Element.
     */
    private ElementInfo getRootInfo() {
        return rootElementInfo;
    }

    /**
     * Returns the root <code>View</code> associated with the current text
     * component.
     */
    private View getRootView() {
        return getTextComponent().getUI().getRootView(getTextComponent());
    }

    /**
     * Returns the bounds the root View will be rendered in.
     */
    private Rectangle getRootEditorRect() {
        Rectangle alloc = getTextComponent().getBounds();
        if ((alloc.width > 0) && (alloc.height > 0)) {
            alloc.x = alloc.y = 0;
            Insets insets = editor.getInsets();
            alloc.x += insets.left;
            alloc.y += insets.top;
            alloc.width -= insets.left + insets.right;
            alloc.height -= insets.top + insets.bottom;
            return alloc;
        }
        return null;
    }

    /**
     * If possible acquires a lock on the Document.  If a lock has been
     * obtained a key will be retured that should be passed to
     * <code>unlock</code>.
     */
    private Object lock() {
        Document document = getDocument();

        if (document instanceof AbstractDocument) {
            ((AbstractDocument)document).readLock();
            return document;
        }
        return null;
    }

    /**
     * Releases a lock previously obtained via <code>lock</code>.
     */
    private void unlock(Object key) {
        if (key != null) {
            ((AbstractDocument)key).readUnlock();
        }
    }

    /**
     * Rebuilds the information from the current info.
     */
    private void buildInfo() {
        Object lock = lock();

        try {
            Document doc = getDocument();
            Element root = doc.getDefaultRootElement();

            rootElementInfo = new ElementInfo(root);
            rootElementInfo.validate();
        } finally {
            unlock(lock);
        }
    }

    /*
     * Create an ElementInfo subclass based on the passed in Element.
     */
    ElementInfo createElementInfo(Element e, ElementInfo parent) {
        AttributeSet attrs = e.getAttributes();

        if (attrs != null) {
            Object name = attrs.getAttribute(StyleConstants.NameAttribute);

            if (name == HTML.Tag.IMG) {
                return new IconElementInfo(e, parent);
            }
            else if (name == HTML.Tag.CONTENT || name == HTML.Tag.CAPTION) {
                return new TextElementInfo(e, parent);
            }
            else if (name == HTML.Tag.TABLE) {
                return new TableElementInfo(e, parent);
            }
        }
        return null;
    }

    /**
     * Returns the root AccessibleContext for the document
     */
    public AccessibleContext getAccessibleContext() {
        if (rootHTMLAccessibleContext == null) {
            rootHTMLAccessibleContext =
                new RootHTMLAccessibleContext(rootElementInfo);
        }
        return rootHTMLAccessibleContext;
    }

    /*
     * The roow AccessibleContext for the document
     */
    private class RootHTMLAccessibleContext extends HTMLAccessibleContext {

        public RootHTMLAccessibleContext(ElementInfo elementInfo) {
            super(elementInfo);
        }

        /**
         * Gets the accessibleName property of this object.  The accessibleName
         * property of an object is a localized String that designates the purpose
         * of the object.  For example, the accessibleName property of a label
         * or button might be the text of the label or button itself.  In the
         * case of an object that doesn't display its name, the accessibleName
         * should still be set.  For example, in the case of a text field used
         * to enter the name of a city, the accessibleName for the en_US locale
         * could be 'city.'
         *
         * @return the localized name of the object; null if this
         * object does not have a name
         *
         * @see #setAccessibleName
         */
        public String getAccessibleName() {
            if (model != null) {
                return (String)model.getProperty(Document.TitleProperty);
            } else {
                return null;
            }
        }

        /**
         * Gets the accessibleDescription property of this object.  If this
         * property isn't set, returns the content type of this
         * <code>JEditorPane</code> instead (e.g. "plain/text", "html/text").
         *
         * @return the localized description of the object; <code>null</code>
         *      if this object does not have a description
         *
         * @see #setAccessibleName
         */
        public String getAccessibleDescription() {
            return editor.getContentType();
        }

        /**
         * Gets the role of this object.  The role of the object is the generic
         * purpose or use of the class of this object.  For example, the role
         * of a push button is AccessibleRole.PUSH_BUTTON.  The roles in
         * AccessibleRole are provided so component developers can pick from
         * a set of predefined roles.  This enables assistive technologies to
         * provide a consistent interface to various tweaked subclasses of
         * components (e.g., use AccessibleRole.PUSH_BUTTON for all components
         * that act like a push button) as well as distinguish between sublasses
         * that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
         * and AccessibleRole.RADIO_BUTTON for radio buttons).
         * <p>Note that the AccessibleRole class is also extensible, so
         * custom component developers can define their own AccessibleRole's
         * if the set of predefined roles is inadequate.
         *
         * @return an instance of AccessibleRole describing the role of the object
         * @see AccessibleRole
         */
        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.TEXT;
        }
    }

    /*
     * Base AccessibleContext class for HTML elements
     */
    protected abstract class HTMLAccessibleContext extends AccessibleContext
        implements Accessible, AccessibleComponent {

        protected ElementInfo elementInfo;

        public HTMLAccessibleContext(ElementInfo elementInfo) {
            this.elementInfo = elementInfo;
        }

        // begin AccessibleContext implementation ...
        public AccessibleContext getAccessibleContext() {
            return this;
        }

        /**
         * Gets the state set of this object.
         *
         * @return an instance of AccessibleStateSet describing the states
         * of the object
         * @see AccessibleStateSet
         */
        public AccessibleStateSet getAccessibleStateSet() {
            AccessibleStateSet states = new AccessibleStateSet();
            Component comp = getTextComponent();

            if (comp.isEnabled()) {
                states.add(AccessibleState.ENABLED);
            }
            if (comp instanceof JTextComponent &&
                ((JTextComponent)comp).isEditable()) {

                states.add(AccessibleState.EDITABLE);
                states.add(AccessibleState.FOCUSABLE);
            }
            if (comp.isVisible()) {
                states.add(AccessibleState.VISIBLE);
            }
            if (comp.isShowing()) {
                states.add(AccessibleState.SHOWING);
            }
            return states;
        }

        /**
         * Gets the 0-based index of this object in its accessible parent.
         *
         * @return the 0-based index of this object in its parent; -1 if this
         * object does not have an accessible parent.
         *
         * @see #getAccessibleParent
         * @see #getAccessibleChildrenCount
         * @see #getAccessibleChild
         */
        public int getAccessibleIndexInParent() {
            return elementInfo.getIndexInParent();
        }

        /**
         * Returns the number of accessible children of the object.
         *
         * @return the number of accessible children of the object.
         */
        public int getAccessibleChildrenCount() {
            return elementInfo.getChildCount();
        }

        /**
         * Returns the specified Accessible child of the object.  The Accessible
         * children of an Accessible object are zero-based, so the first child
         * of an Accessible child is at index 0, the second child is at index 1,
         * and so on.
         *
         * @param i zero-based index of child
         * @return the Accessible child of the object
         * @see #getAccessibleChildrenCount
         */
        public Accessible getAccessibleChild(int i) {
            ElementInfo childInfo = elementInfo.getChild(i);
            if (childInfo != null && childInfo instanceof Accessible) {
                return (Accessible)childInfo;
            } else {
                return null;
            }
        }

        /**
         * Gets the locale of the component. If the component does not have a
         * locale, then the locale of its parent is returned.
         *
         * @return this component's locale.  If this component does not have
         * a locale, the locale of its parent is returned.
         *
         * @exception IllegalComponentStateException
         * If the Component does not have its own locale and has not yet been
         * added to a containment hierarchy such that the locale can be
         * determined from the containing parent.
         */
        public Locale getLocale() throws IllegalComponentStateException {
            return editor.getLocale();
        }
        // ... end AccessibleContext implementation

        // begin AccessibleComponent implementation ...
        public AccessibleComponent getAccessibleComponent() {
            return this;
        }

        /**
         * Gets the background color of this object.
         *
         * @return the background color, if supported, of the object;
         * otherwise, null
         * @see #setBackground
         */
        public Color getBackground() {
            return getTextComponent().getBackground();
        }

        /**
         * Sets the background color of this object.
         *
         * @param c the new Color for the background
         * @see #setBackground
         */
        public void setBackground(Color c) {
            getTextComponent().setBackground(c);
        }

        /**
         * Gets the foreground color of this object.
         *
         * @return the foreground color, if supported, of the object;
         * otherwise, null
         * @see #setForeground
         */
        public Color getForeground() {
            return getTextComponent().getForeground();
        }

        /**
         * Sets the foreground color of this object.
         *
         * @param c the new Color for the foreground
         * @see #getForeground
         */
        public void setForeground(Color c) {
            getTextComponent().setForeground(c);
        }

        /**
         * Gets the Cursor of this object.
         *
         * @return the Cursor, if supported, of the object; otherwise, null
         * @see #setCursor
         */
        public Cursor getCursor() {
            return getTextComponent().getCursor();
        }

        /**
         * Sets the Cursor of this object.
         *
         * @param c the new Cursor for the object
         * @see #getCursor
         */
        public void setCursor(Cursor cursor) {
            getTextComponent().setCursor(cursor);
        }

        /**
         * Gets the Font of this object.
         *
         * @return the Font,if supported, for the object; otherwise, null
         * @see #setFont
         */
        public Font getFont() {
            return getTextComponent().getFont();
        }

        /**
         * Sets the Font of this object.
         *
         * @param f the new Font for the object
         * @see #getFont
         */
        public void setFont(Font f) {
            getTextComponent().setFont(f);
        }

        /**
         * Gets the FontMetrics of this object.
         *
         * @param f the Font
         * @return the FontMetrics, if supported, the object; otherwise, null
         * @see #getFont
         */
        public FontMetrics getFontMetrics(Font f) {
            return getTextComponent().getFontMetrics(f);
        }

        /**
         * Determines if the object is enabled.  Objects that are enabled
         * will also have the AccessibleState.ENABLED state set in their
         * AccessibleStateSets.
         *
         * @return true if object is enabled; otherwise, false
         * @see #setEnabled
         * @see AccessibleContext#getAccessibleStateSet
         * @see AccessibleState#ENABLED
         * @see AccessibleStateSet
         */
        public boolean isEnabled() {
            return getTextComponent().isEnabled();
        }

        /**
         * Sets the enabled state of the object.
         *
         * @param b if true, enables this object; otherwise, disables it
         * @see #isEnabled
         */
        public void setEnabled(boolean b) {
            getTextComponent().setEnabled(b);
        }

        /**
         * Determines if the object is visible.  Note: this means that the
         * object intends to be visible; however, it may not be
         * showing on the screen because one of the objects that this object
         * is contained by is currently not visible.  To determine if an object
         * is showing on the screen, use isShowing().
         * <p>Objects that are visible will also have the
         * AccessibleState.VISIBLE state set in their AccessibleStateSets.
         *
         * @return true if object is visible; otherwise, false
         * @see #setVisible
         * @see AccessibleContext#getAccessibleStateSet
         * @see AccessibleState#VISIBLE
         * @see AccessibleStateSet
         */
        public boolean isVisible() {
            return getTextComponent().isVisible();
        }

        /**
         * Sets the visible state of the object.
         *
         * @param b if true, shows this object; otherwise, hides it
         * @see #isVisible
         */
        public void setVisible(boolean b) {
            getTextComponent().setVisible(b);
        }

        /**
         * Determines if the object is showing.  This is determined by checking
         * the visibility of the object and its ancestors.
         * Note: this
         * will return true even if the object is obscured by another (for
         * example, it is underneath a menu that was pulled down).
         *
         * @return true if object is showing; otherwise, false
         */
        public boolean isShowing() {
            return getTextComponent().isShowing();
        }

        /**
         * Checks whether the specified point is within this object's bounds,
         * where the point's x and y coordinates are defined to be relative
         * to the coordinate system of the object.
         *
         * @param p the Point relative to the coordinate system of the object
         * @return true if object contains Point; otherwise false
         * @see #getBounds
         */
        public boolean contains(Point p) {
            Rectangle r = getBounds();
            if (r != null) {
                return r.contains(p.x, p.y);
            } else {
                return false;
            }
        }

        /**
         * Returns the location of the object on the screen.
         *
         * @return the location of the object on screen; null if this object
         * is not on the screen
         * @see #getBounds
         * @see #getLocation
         */
        public Point getLocationOnScreen() {
            Point editorLocation = getTextComponent().getLocationOnScreen();
            Rectangle r = getBounds();
            if (r != null) {
                return new Point(editorLocation.x + r.x,
                                 editorLocation.y + r.y);
            } else {
                return null;
            }
        }

        /**
         * Gets the location of the object relative to the parent in the form
         * of a point specifying the object's top-left corner in the screen's
         * coordinate space.
         *
         * @return An instance of Point representing the top-left corner of the
         * object's bounds in the coordinate space of the screen; null if
         * this object or its parent are not on the screen
         * @see #getBounds
         * @see #getLocationOnScreen
         */
        public Point getLocation() {
            Rectangle r = getBounds();
            if (r != null) {
                return new Point(r.x, r.y);
            } else {
                return null;
            }
        }

        /**
         * Sets the location of the object relative to the parent.
         * @param p the new position for the top-left corner
         * @see #getLocation
         */
        public void setLocation(Point p) {
        }

        /**
         * Gets the bounds of this object in the form of a Rectangle object.
         * The bounds specify this object's width, height, and location
         * relative to its parent.
         *
         * @return A rectangle indicating this component's bounds; null if
         * this object is not on the screen.
         * @see #contains
         */
        public Rectangle getBounds() {
            return elementInfo.getBounds();
        }

        /**
         * Sets the bounds of this object in the form of a Rectangle object.
         * The bounds specify this object's width, height, and location
         * relative to its parent.
         *
         * @param r rectangle indicating this component's bounds
         * @see #getBounds
         */
        public void setBounds(Rectangle r) {
        }

        /**
         * Returns the size of this object in the form of a Dimension object.
         * The height field of the Dimension object contains this object's
         * height, and the width field of the Dimension object contains this
         * object's width.
         *
         * @return A Dimension object that indicates the size of this component;
         * null if this object is not on the screen
         * @see #setSize
         */
        public Dimension getSize() {
            Rectangle r = getBounds();
            if (r != null) {
                return new Dimension(r.width, r.height);
            } else {
                return null;
            }
        }

        /**
         * Resizes this object so that it has width and height.
         *
         * @param d The dimension specifying the new size of the object.
         * @see #getSize
         */
        public void setSize(Dimension d) {
            Component comp = getTextComponent();
            comp.setSize(d);
        }

        /**
         * Returns the Accessible child, if one exists, contained at the local
         * coordinate Point.
         *
         * @param p The point relative to the coordinate system of this object.
         * @return the Accessible, if it exists, at the specified location;
         * otherwise null
         */
        public Accessible getAccessibleAt(Point p) {
            ElementInfo innerMostElement = getElementInfoAt(rootElementInfo, p);
            if (innerMostElement instanceof Accessible) {
                return (Accessible)innerMostElement;
            } else {
                return null;
            }
        }

        private ElementInfo getElementInfoAt(ElementInfo elementInfo, Point p) {
            if (elementInfo.getBounds() == null) {
                return null;
            }
            if (elementInfo.getChildCount() == 0 &&
                elementInfo.getBounds().contains(p)) {
                return elementInfo;

            } else {
                if (elementInfo instanceof TableElementInfo) {
                    // Handle table caption as a special case since it's the
                    // only table child that is not a table row.
                    ElementInfo captionInfo =
                        ((TableElementInfo)elementInfo).getCaptionInfo();
                    if (captionInfo != null) {
                        Rectangle bounds = captionInfo.getBounds();
                        if (bounds != null && bounds.contains(p)) {
                            return captionInfo;
                        }
                    }
                }
                for (int i = 0; i < elementInfo.getChildCount(); i++)
{
                    ElementInfo childInfo = elementInfo.getChild(i);
                    ElementInfo retValue = getElementInfoAt(childInfo, p);
                    if (retValue != null) {
                        return retValue;
                    }
                }
            }
            return null;
        }

        /**
         * Returns whether this object can accept focus or not.   Objects that
         * can accept focus will also have the AccessibleState.FOCUSABLE state
         * set in their AccessibleStateSets.
         *
         * @return true if object can accept focus; otherwise false
         * @see AccessibleContext#getAccessibleStateSet
         * @see AccessibleState#FOCUSABLE
         * @see AccessibleState#FOCUSED
         * @see AccessibleStateSet
         */
        public boolean isFocusTraversable() {
            Component comp = getTextComponent();
            if (comp instanceof JTextComponent) {
                if (((JTextComponent)comp).isEditable()) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Requests focus for this object.  If this object cannot accept focus,
         * nothing will happen.  Otherwise, the object will attempt to take
         * focus.
         * @see #isFocusTraversable
         */
        public void requestFocus() {
            // TIGER - 4856191
            if (! isFocusTraversable()) {
                return;
            }

            Component comp = getTextComponent();
            if (comp instanceof JTextComponent) {

                comp.requestFocusInWindow();

                try {
                    if (elementInfo.validateIfNecessary()) {
                        // set the caret position to the start of this component
                        Element elem = elementInfo.getElement();
                        ((JTextComponent)comp).setCaretPosition(elem.getStartOffset());

                        // fire a AccessibleState.FOCUSED property change event
                        AccessibleContext ac = editor.getAccessibleContext();
                        PropertyChangeEvent pce = new PropertyChangeEvent(this,
                            AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
                            null, AccessibleState.FOCUSED);
                        ac.firePropertyChange(
                            AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
                            null, pce);
                    }
                } catch (IllegalArgumentException e) {
                    // don't fire property change event
                }
            }
        }

        /**
         * Adds the specified focus listener to receive focus events from this
         * component.
         *
         * @param l the focus listener
         * @see #removeFocusListener
         */
        public void addFocusListener(FocusListener l) {
            getTextComponent().addFocusListener(l);
        }

        /**
         * Removes the specified focus listener so it no longer receives focus
         * events from this component.
         *
         * @param l the focus listener
         * @see #addFocusListener
         */
        public void removeFocusListener(FocusListener l) {
            getTextComponent().removeFocusListener(l);
        }
        // ... end AccessibleComponent implementation
    } // ... end HTMLAccessibleContext



    /*
     * ElementInfo for text
     */
    class TextElementInfo extends ElementInfo implements Accessible {

        TextElementInfo(Element element, ElementInfo parent) {
            super(element, parent);
        }

        // begin AccessibleText implementation ...
        private AccessibleContext accessibleContext;

        public AccessibleContext getAccessibleContext() {
            if (accessibleContext == null) {
                accessibleContext = new TextAccessibleContext(this);
            }
            return accessibleContext;
        }

        /*
         * AccessibleContext for text elements
         */
        public class TextAccessibleContext extends HTMLAccessibleContext
            implements AccessibleText {

            public TextAccessibleContext(ElementInfo elementInfo) {
                super(elementInfo);
            }

            public AccessibleText getAccessibleText() {
                return this;
            }

            /**
             * Gets the accessibleName property of this object.  The accessibleName
             * property of an object is a localized String that designates the purpose
             * of the object.  For example, the accessibleName property of a label
             * or button might be the text of the label or button itself.  In the
             * case of an object that doesn't display its name, the accessibleName
             * should still be set.  For example, in the case of a text field used
             * to enter the name of a city, the accessibleName for the en_US locale
             * could be 'city.'
             *
             * @return the localized name of the object; null if this
             * object does not have a name
             *
             * @see #setAccessibleName
             */
            public String getAccessibleName() {
                if (model != null) {
                    return (String)model.getProperty(Document.TitleProperty);
                } else {
                    return null;
                }
            }

            /**
             * Gets the accessibleDescription property of this object.  If this
             * property isn't set, returns the content type of this
             * <code>JEditorPane</code> instead (e.g. "plain/text", "html/text").
             *
             * @return the localized description of the object; <code>null</code>
             *  if this object does not have a description
             *
             * @see #setAccessibleName
             */
            public String getAccessibleDescription() {
                return editor.getContentType();
            }

            /**
             * Gets the role of this object.  The role of the object is the generic
             * purpose or use of the class of this object.  For example, the role
             * of a push button is AccessibleRole.PUSH_BUTTON.  The roles in
             * AccessibleRole are provided so component developers can pick from
             * a set of predefined roles.  This enables assistive technologies to
             * provide a consistent interface to various tweaked subclasses of
             * components (e.g., use AccessibleRole.PUSH_BUTTON for all components
             * that act like a push button) as well as distinguish between sublasses
             * that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
             * and AccessibleRole.RADIO_BUTTON for radio buttons).
             * <p>Note that the AccessibleRole class is also extensible, so
             * custom component developers can define their own AccessibleRole's
             * if the set of predefined roles is inadequate.
             *
             * @return an instance of AccessibleRole describing the role of the object
             * @see AccessibleRole
             */
            public AccessibleRole getAccessibleRole() {
                return AccessibleRole.TEXT;
            }

            /**
             * Given a point in local coordinates, return the zero-based index
             * of the character under that Point.  If the point is invalid,
             * this method returns -1.
             *
             * @param p the Point in local coordinates
             * @return the zero-based index of the character under Point p; if
             * Point is invalid returns -1.
             */
            public int getIndexAtPoint(Point p) {
                View v = getView();
                if (v != null) {
                    return v.viewToModel(p.x, p.y, getBounds());
                } else {
                    return -1;
                }
            }

            /**
             * Determine the bounding box of the character at the given
             * index into the string.  The bounds are returned in local
             * coordinates.  If the index is invalid an empty rectangle is
             * returned.
             *
             * @param i the index into the String
             * @return the screen coordinates of the character's the bounding box,
             * if index is invalid returns an empty rectangle.
             */
            public Rectangle getCharacterBounds(int i) {
                try {
                    return editor.getUI().modelToView(editor, i);
                } catch (BadLocationException e) {
                    return null;
                }
            }

            /**
             * Return the number of characters (valid indicies)
             *
             * @return the number of characters
             */
            public int getCharCount() {
                if (validateIfNecessary()) {
                    Element elem = elementInfo.getElement();
                    return elem.getEndOffset() - elem.getStartOffset();
                }
                return 0;
            }

            /**
             * Return the zero-based offset of the caret.
             *
             * Note: That to the right of the caret will have the same index
             * value as the offset (the caret is between two characters).
             * @return the zero-based offset of the caret.
             */
            public int getCaretPosition() {
                View v = getView();
                if (v == null) {
                    return -1;
                }
                Container c = v.getContainer();
                if (c == null) {
                    return -1;
                }
                if (c instanceof JTextComponent) {
                    return ((JTextComponent)c).getCaretPosition();
                } else {
                    return -1;
                }
            }

            /**
             * IndexedSegment extends Segment adding the offset into the
             * the model the <code>Segment</code> was asked for.
             */
            private class IndexedSegment extends Segment {
                /**
                 * Offset into the model that the position represents.
                 */
                public int modelOffset;
            }

            public String getAtIndex(int part, int index) {
                return getAtIndex(part, index, 0);
            }


            public String getAfterIndex(int part, int index) {
                return getAtIndex(part, index, 1);
            }

            public String getBeforeIndex(int part, int index) {
                return getAtIndex(part, index, -1);
            }

            /**
             * Gets the word, sentence, or character at <code>index</code>.
             * If <code>direction</code> is non-null this will find the
             * next/previous word/sentence/character.
             */
            private String getAtIndex(int part, int index, int direction) {
                if (model instanceof AbstractDocument) {
                    ((AbstractDocument)model).readLock();
                }
                try {
                    if (index < 0 || index >= model.getLength()) {
                        return null;
                    }
                    switch (part) {
                    case AccessibleText.CHARACTER:
                        if (index + direction < model.getLength() &&
                            index + direction >= 0) {
                            return model.getText(index + direction, 1);
                        }
                        break;


                    case AccessibleText.WORD:
                    case AccessibleText.SENTENCE:
                        IndexedSegment seg = getSegmentAt(part, index);
                        if (seg != null) {
                            if (direction != 0) {
                                int next;


                                if (direction < 0) {
                                    next = seg.modelOffset - 1;
                                }
                                else {
                                    next = seg.modelOffset + direction * seg.count;
                                }
                                if (next >= 0 && next <= model.getLength()) {
                                    seg = getSegmentAt(part, next);
                                }
                                else {
                                    seg = null;
                                }
                            }
                            if (seg != null) {
                                return new String(seg.array, seg.offset,
                                                  seg.count);
                            }
                        }
                        break;

                    default:
                        break;
                    }
                } catch (BadLocationException e) {
                } finally {
                    if (model instanceof AbstractDocument) {
                        ((AbstractDocument)model).readUnlock();
                    }
                }
                return null;
            }

            /*
             * Returns the paragraph element for the specified index.
             */
            private Element getParagraphElement(int index) {
                if (model instanceof PlainDocument ) {
                    PlainDocument sdoc = (PlainDocument)model;
                    return sdoc.getParagraphElement(index);
                } else if (model instanceof StyledDocument) {
                    StyledDocument sdoc = (StyledDocument)model;
                    return sdoc.getParagraphElement(index);
                } else {
                    Element para = null;
                    for (para = model.getDefaultRootElement(); ! para.isLeaf(); ) {
                        int pos = para.getElementIndex(index);
                        para = para.getElement(pos);
                    }
                    if (para == null) {
                        return null;
                    }
                    return para.getParentElement();
                }
            }

            /*
             * Returns a <code>Segment</code> containing the paragraph text
             * at <code>index</code>, or null if <code>index</code> isn't
             * valid.
             */
            private IndexedSegment getParagraphElementText(int index)
                throws BadLocationException {
                Element para = getParagraphElement(index);


                if (para != null) {
                    IndexedSegment segment = new IndexedSegment();
                    try {
                        int length = para.getEndOffset() - para.getStartOffset();
                        model.getText(para.getStartOffset(), length, segment);
                    } catch (BadLocationException e) {
                        return null;
                    }
                    segment.modelOffset = para.getStartOffset();
                    return segment;
                }
                return null;
            }


            /**
             * Returns the Segment at <code>index</code> representing either
             * the paragraph or sentence as identified by <code>part</code>, or
             * null if a valid paragraph/sentence can't be found. The offset
             * will point to the start of the word/sentence in the array, and
             * the modelOffset will point to the location of the word/sentence
             * in the model.
             */
            private IndexedSegment getSegmentAt(int part, int index)
                throws BadLocationException {

                IndexedSegment seg = getParagraphElementText(index);
                if (seg == null) {
                    return null;
                }
                BreakIterator iterator;
                switch (part) {
                case AccessibleText.WORD:
                    iterator = BreakIterator.getWordInstance(getLocale());
                    break;
                case AccessibleText.SENTENCE:
                    iterator = BreakIterator.getSentenceInstance(getLocale());
                    break;
                default:
                    return null;
                }
                seg.first();
                iterator.setText(seg);
                int end = iterator.following(index - seg.modelOffset + seg.offset);
                if (end == BreakIterator.DONE) {
                    return null;
                }
                if (end > seg.offset + seg.count) {
                    return null;
                }
                int begin = iterator.previous();
                if (begin == BreakIterator.DONE ||
                    begin >= seg.offset + seg.count) {
                    return null;
                }
                seg.modelOffset = seg.modelOffset + begin - seg.offset;
                seg.offset = begin;
                seg.count = end - begin;
                return seg;
            }

            /**
             * Return the AttributeSet for a given character at a given index
             *
             * @param i the zero-based index into the text
             * @return the AttributeSet of the character
             */
            public AttributeSet getCharacterAttribute(int i) {
                if (model instanceof StyledDocument) {
                    StyledDocument doc = (StyledDocument)model;
                    Element elem = doc.getCharacterElement(i);
                    if (elem != null) {
                        return elem.getAttributes();
                    }
                }
                return null;
            }

            /**
             * Returns the start offset within the selected text.
             * If there is no selection, but there is
             * a caret, the start and end offsets will be the same.
             *
             * @return the index into the text of the start of the selection
             */
            public int getSelectionStart() {
                return editor.getSelectionStart();
            }

            /**
             * Returns the end offset within the selected text.
             * If there is no selection, but there is
             * a caret, the start and end offsets will be the same.
             *
             * @return the index into teh text of the end of the selection
             */
            public int getSelectionEnd() {
                return editor.getSelectionEnd();
            }

            /**
             * Returns the portion of the text that is selected.
             *
             * @return the String portion of the text that is selected
             */
            public String getSelectedText() {
                return editor.getSelectedText();
            }

            /*
             * Returns the text substring starting at the specified
             * offset with the specified length.
             */
            private String getText(int offset, int length)
                throws BadLocationException {

                if (model != null && model instanceof StyledDocument) {
                    StyledDocument doc = (StyledDocument)model;
                    return model.getText(offset, length);
                } else {
                    return null;
                }
            }
        }
    }

    /*
     * ElementInfo for images
     */
    private class IconElementInfo extends ElementInfo implements Accessible {

        private int width = -1;
        private int height = -1;

        IconElementInfo(Element element, ElementInfo parent) {
            super(element, parent);
        }

        protected void invalidate(boolean first) {
            super.invalidate(first);
            width = height = -1;
        }

        private int getImageSize(Object key) {
            if (validateIfNecessary()) {
                int size = getIntAttr(getAttributes(), key, -1);

                if (size == -1) {
                    View v = getView();

                    size = 0;
                    if (v instanceof ImageView) {
                        Image img = ((ImageView)v).getImage();
                        if (img != null) {
                            if (key == HTML.Attribute.WIDTH) {
                                size = img.getWidth(null);
                            }
                            else {
                                size = img.getHeight(null);
                            }
                        }
                    }
                }
                return size;
            }
            return 0;
        }

        // begin AccessibleIcon implementation ...
        private AccessibleContext accessibleContext;

        public AccessibleContext getAccessibleContext() {
            if (accessibleContext == null) {
                accessibleContext = new IconAccessibleContext(this);
            }
            return accessibleContext;
        }

        /*
         * AccessibleContext for images
         */
        protected class IconAccessibleContext extends HTMLAccessibleContext
            implements AccessibleIcon  {

            public IconAccessibleContext(ElementInfo elementInfo) {
                super(elementInfo);
            }

            /**
             * Gets the accessibleName property of this object.  The accessibleName
             * property of an object is a localized String that designates the purpose
             * of the object.  For example, the accessibleName property of a label
             * or button might be the text of the label or button itself.  In the
             * case of an object that doesn't display its name, the accessibleName
             * should still be set.  For example, in the case of a text field used
             * to enter the name of a city, the accessibleName for the en_US locale
             * could be 'city.'
             *
             * @return the localized name of the object; null if this
             * object does not have a name
             *
             * @see #setAccessibleName
             */
            public String getAccessibleName() {
                return getAccessibleIconDescription();
            }

            /**
             * Gets the accessibleDescription property of this object.  If this
             * property isn't set, returns the content type of this
             * <code>JEditorPane</code> instead (e.g. "plain/text", "html/text").
             *
             * @return the localized description of the object; <code>null</code>
             *  if this object does not have a description
             *
             * @see #setAccessibleName
             */
            public String getAccessibleDescription() {
                return editor.getContentType();
            }

            /**
             * Gets the role of this object.  The role of the object is the generic
             * purpose or use of the class of this object.  For example, the role
             * of a push button is AccessibleRole.PUSH_BUTTON.  The roles in
             * AccessibleRole are provided so component developers can pick from
             * a set of predefined roles.  This enables assistive technologies to
             * provide a consistent interface to various tweaked subclasses of
             * components (e.g., use AccessibleRole.PUSH_BUTTON for all components
             * that act like a push button) as well as distinguish between sublasses
             * that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
             * and AccessibleRole.RADIO_BUTTON for radio buttons).
             * <p>Note that the AccessibleRole class is also extensible, so
             * custom component developers can define their own AccessibleRole's
             * if the set of predefined roles is inadequate.
             *
             * @return an instance of AccessibleRole describing the role of the object
             * @see AccessibleRole
             */
            public AccessibleRole getAccessibleRole() {
                return AccessibleRole.ICON;
            }

            public AccessibleIcon [] getAccessibleIcon() {
                AccessibleIcon [] icons = new AccessibleIcon[1];
                icons[0] = this;
                return icons;
            }

            /**
             * Gets the description of the icon.  This is meant to be a brief
             * textual description of the object.  For example, it might be
             * presented to a blind user to give an indication of the purpose
             * of the icon.
             *
             * @return the description of the icon
             */
            public String getAccessibleIconDescription() {
                return ((ImageView)getView()).getAltText();
            }

            /**
             * Sets the description of the icon.  This is meant to be a brief
             * textual description of the object.  For example, it might be
             * presented to a blind user to give an indication of the purpose
             * of the icon.
             *
             * @param description the description of the icon
             */
            public void setAccessibleIconDescription(String description) {
            }

            /**
             * Gets the width of the icon
             *
             * @return the width of the icon.
             */
            public int getAccessibleIconWidth() {
                if (width == -1) {
                    width = getImageSize(HTML.Attribute.WIDTH);
                }
                return width;
            }

            /**
             * Gets the height of the icon
             *
             * @return the height of the icon.
             */
            public int getAccessibleIconHeight() {
                if (height == -1) {
                    height = getImageSize(HTML.Attribute.HEIGHT);
                }
                return height;
            }
        }
        // ... end AccessibleIconImplementation
    }


    /**
     * TableElementInfo encapsulates information about a HTML.Tag.TABLE.
     * To make access fast it crates a grid containing the children to
     * allow for access by row, column. TableElementInfo will contain
     * TableRowElementInfos, which will contain TableCellElementInfos.
     * Any time one of the rows or columns becomes invalid the table is
     * invalidated.  This is because any time one of the child attributes
     * changes the size of the grid may have changed.
     */
    private class TableElementInfo extends ElementInfo
        implements Accessible {

        protected ElementInfo caption;

        /**
         * Allocation of the table by row x column. There may be holes (eg
         * nulls) depending upon the html, any cell that has a rowspan/colspan
         * > 1 will be contained multiple times in the grid.
         */
        private TableCellElementInfo[][] grid;


        TableElementInfo(Element e, ElementInfo parent) {
            super(e, parent);
        }

        public ElementInfo getCaptionInfo() {
            return caption;
        }

        /**
         * Overriden to update the grid when validating.
         */
        protected void validate() {
            super.validate();
            updateGrid();
        }

        /**
         * Overriden to only alloc instances of TableRowElementInfos.
         */
        protected void loadChildren(Element e) {

            for (int counter = 0; counter < e.getElementCount(); counter++) {
                Element child = e.getElement(counter);
                AttributeSet attrs = child.getAttributes();

                if (attrs.getAttribute(StyleConstants.NameAttribute) ==
                                       HTML.Tag.TR) {
                    addChild(new TableRowElementInfo(child, this, counter));

                } else if (attrs.getAttribute(StyleConstants.NameAttribute) ==
                                       HTML.Tag.CAPTION) {
                    // Handle captions as a special case since all other
                    // children are table rows.
                    caption = createElementInfo(child, this);
                }
            }
        }

        /**
         * Updates the grid.
         */
        private void updateGrid() {
            // Determine the max row/col count.
            int delta = 0;
            int maxCols = 0;
            int rows = 0;
            for (int counter = 0; counter < getChildCount(); counter++) {
                TableRowElementInfo row = getRow(counter);
                int prev = 0;
                for (int y = 0; y < delta; y++) {
                    prev = Math.max(prev, getRow(counter - y - 1).
                                    getColumnCount(y + 2));
                }
                delta = Math.max(row.getRowCount(), delta);
                delta--;
                maxCols = Math.max(maxCols, row.getColumnCount() + prev);
            }
            rows = getChildCount() + delta;

            // Alloc
            grid = new TableCellElementInfo[rows][];
            for (int counter = 0; counter < rows; counter++) {
                grid[counter] = new TableCellElementInfo[maxCols];
            }
            // Update
            for (int counter = 0; counter < rows; counter++) {
                getRow(counter).updateGrid(counter);
            }
        }

        /**
         * Returns the TableCellElementInfo at the specified index.
         */
        public TableRowElementInfo getRow(int index) {
            return (TableRowElementInfo)getChild(index);
        }

        /**
         * Returns the TableCellElementInfo by row and column.
         */
        public TableCellElementInfo getCell(int r, int c) {
            if (validateIfNecessary() && r < grid.length &&
                                         c < grid[0].length) {
                return grid[r][c];
            }
            return null;
        }

        /**
         * Returns the rowspan of the specified entry.
         */
        public int getRowExtentAt(int r, int c) {
            TableCellElementInfo cell = getCell(r, c);

            if (cell != null) {
                int rows = cell.getRowCount();
                int delta = 1;

                while ((r - delta) >= 0 && grid[r - delta][c] == cell) {
                    delta++;
                }
                return rows - delta + 1;
            }
            return 0;
        }

        /**
         * Returns the colspan of the specified entry.
         */
        public int getColumnExtentAt(int r, int c) {
            TableCellElementInfo cell = getCell(r, c);

            if (cell != null) {
                int cols = cell.getColumnCount();
                int delta = 1;

                while ((c - delta) >= 0 && grid[r][c - delta] == cell) {
                    delta++;
                }
                return cols - delta + 1;
            }
            return 0;
        }

        /**
         * Returns the number of rows in the table.
         */
        public int getRowCount() {
            if (validateIfNecessary()) {
                return grid.length;
            }
            return 0;
        }

        /**
         * Returns the number of columns in the table.
         */
        public int getColumnCount() {
            if (validateIfNecessary() && grid.length > 0) {
                return grid[0].length;
            }
            return 0;
        }

        // begin AccessibleTable implementation ...
        private AccessibleContext accessibleContext;

        public AccessibleContext getAccessibleContext() {
            if (accessibleContext == null) {
                accessibleContext = new TableAccessibleContext(this);
            }
            return accessibleContext;
        }

        /*
         * AccessibleContext for tables
         */
        public class TableAccessibleContext extends HTMLAccessibleContext
            implements AccessibleTable {

            private AccessibleHeadersTable rowHeadersTable;

            public TableAccessibleContext(ElementInfo elementInfo) {
                super(elementInfo);
            }

            /**
             * Gets the accessibleName property of this object.  The accessibleName
             * property of an object is a localized String that designates the purpose
             * of the object.  For example, the accessibleName property of a label
             * or button might be the text of the label or button itself.  In the
             * case of an object that doesn't display its name, the accessibleName
             * should still be set.  For example, in the case of a text field used
             * to enter the name of a city, the accessibleName for the en_US locale
             * could be 'city.'
             *
             * @return the localized name of the object; null if this
             * object does not have a name
             *
             * @see #setAccessibleName
             */
            public String getAccessibleName() {
                // return the role of the object
                return getAccessibleRole().toString();
            }

            /**
             * Gets the accessibleDescription property of this object.  If this
             * property isn't set, returns the content type of this
             * <code>JEditorPane</code> instead (e.g. "plain/text", "html/text").
             *
             * @return the localized description of the object; <code>null</code>
             *  if this object does not have a description
             *
             * @see #setAccessibleName
             */
            public String getAccessibleDescription() {
                return editor.getContentType();
            }

            /**
             * Gets the role of this object.  The role of the object is the generic
             * purpose or use of the class of this object.  For example, the role
             * of a push button is AccessibleRole.PUSH_BUTTON.  The roles in
             * AccessibleRole are provided so component developers can pick from
             * a set of predefined roles.  This enables assistive technologies to
             * provide a consistent interface to various tweaked subclasses of
             * components (e.g., use AccessibleRole.PUSH_BUTTON for all components
             * that act like a push button) as well as distinguish between sublasses
             * that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
             * and AccessibleRole.RADIO_BUTTON for radio buttons).
             * <p>Note that the AccessibleRole class is also extensible, so
             * custom component developers can define their own AccessibleRole's
             * if the set of predefined roles is inadequate.
             *
             * @return an instance of AccessibleRole describing the role of the object
             * @see AccessibleRole
             */
            public AccessibleRole getAccessibleRole() {
                return AccessibleRole.TABLE;
            }

            /**
             * Gets the 0-based index of this object in its accessible parent.
             *
             * @return the 0-based index of this object in its parent; -1 if this
             * object does not have an accessible parent.
             *
             * @see #getAccessibleParent
             * @see #getAccessibleChildrenCount
             * @gsee #getAccessibleChild
             */
            public int getAccessibleIndexInParent() {
                return elementInfo.getIndexInParent();
            }

            /**
             * Returns the number of accessible children of the object.
             *
             * @return the number of accessible children of the object.
             */
            public int getAccessibleChildrenCount() {
                return ((TableElementInfo)elementInfo).getRowCount() *
                    ((TableElementInfo)elementInfo).getColumnCount();
            }

            /**
             * Returns the specified Accessible child of the object.  The Accessible
             * children of an Accessible object are zero-based, so the first child
             * of an Accessible child is at index 0, the second child is at index 1,
             * and so on.
             *
             * @param i zero-based index of child
             * @return the Accessible child of the object
             * @see #getAccessibleChildrenCount
             */
            public Accessible getAccessibleChild(int i) {
                int rowCount = ((TableElementInfo)elementInfo).getRowCount();
                int columnCount = ((TableElementInfo)elementInfo).getColumnCount();
                int r = i / rowCount;
                int c = i % columnCount;
                if (r < 0 || r >= rowCount || c < 0 || c >= columnCount) {
                    return null;
                } else {
                    return getAccessibleAt(r, c);
                }
            }

            public AccessibleTable getAccessibleTable() {
                return this;
            }

            /**
             * Returns the caption for the table.
             *
             * @return the caption for the table
             */
            public Accessible getAccessibleCaption() {
                ElementInfo captionInfo = getCaptionInfo();
                if (captionInfo instanceof Accessible) {
                    return (Accessible)caption;
                } else {
                    return null;
                }
            }

            /**
             * Sets the caption for the table.
             *
             * @param a the caption for the table
             */
            public void setAccessibleCaption(Accessible a) {
            }

            /**
             * Returns the summary description of the table.
             *
             * @return the summary description of the table
             */
            public Accessible getAccessibleSummary() {
                return null;
            }

            /**
             * Sets the summary description of the table
             *
             * @param a the summary description of the table
             */
            public void setAccessibleSummary(Accessible a) {
            }

            /**
             * Returns the number of rows in the table.
             *
             * @return the number of rows in the table
             */
            public int getAccessibleRowCount() {
                return ((TableElementInfo)elementInfo).getRowCount();
            }

            /**
             * Returns the number of columns in the table.
             *
             * @return the number of columns in the table
             */
            public int getAccessibleColumnCount() {
                return ((TableElementInfo)elementInfo).getColumnCount();
            }

            /**
             * Returns the Accessible at a specified row and column
             * in the table.
             *
             * @param r zero-based row of the table
             * @param c zero-based column of the table
             * @return the Accessible at the specified row and column
             */
            public Accessible getAccessibleAt(int r, int c) {
                TableCellElementInfo cellInfo = getCell(r, c);
                if (cellInfo != null) {
                    return cellInfo.getAccessible();
                } else {
                    return null;
                }
            }

            /**
             * Returns the number of rows occupied by the Accessible at
             * a specified row and column in the table.
             *
             * @return the number of rows occupied by the Accessible at a
             * given specified (row, column)
             */
            public int getAccessibleRowExtentAt(int r, int c) {
                return ((TableElementInfo)elementInfo).getRowExtentAt(r, c);
            }

            /**
             * Returns the number of columns occupied by the Accessible at
             * a specified row and column in the table.
             *
             * @return the number of columns occupied by the Accessible at a
             * given specified row and column
             */
            public int getAccessibleColumnExtentAt(int r, int c) {
                return ((TableElementInfo)elementInfo).getColumnExtentAt(r, c);
            }

            /**
             * Returns the row headers as an AccessibleTable.
             *
             * @return an AccessibleTable representing the row
             * headers
             */
            public AccessibleTable getAccessibleRowHeader() {
                return rowHeadersTable;
            }

            /**
             * Sets the row headers.
             *
             * @param table an AccessibleTable representing the
             * row headers
             */
            public void setAccessibleRowHeader(AccessibleTable table) {
            }

            /**
             * Returns the column headers as an AccessibleTable.
             *
             * @return an AccessibleTable representing the column
             * headers
             */
            public AccessibleTable getAccessibleColumnHeader() {
                return null;
            }

            /**
             * Sets the column headers.
             *
             * @param table an AccessibleTable representing the
             * column headers
             */
            public void setAccessibleColumnHeader(AccessibleTable table) {
            }

            /**
             * Returns the description of the specified row in the table.
             *
             * @param r zero-based row of the table
             * @return the description of the row
             */
            public Accessible getAccessibleRowDescription(int r) {
                return null;
            }

            /**
             * Sets the description text of the specified row of the table.
             *
             * @param r zero-based row of the table
             * @param a the description of the row
             */
            public void setAccessibleRowDescription(int r, Accessible a) {
            }

            /**
             * Returns the description text of the specified column in the table.
             *
             * @param c zero-based column of the table
             * @return the text description of the column
             */
            public Accessible getAccessibleColumnDescription(int c) {
                return null;
            }

            /**
             * Sets the description text of the specified column in the table.
             *
             * @param c zero-based column of the table
             * @param a the text description of the column
             */
            public void setAccessibleColumnDescription(int c, Accessible a) {
            }

            /**
             * Returns a boolean value indicating whether the accessible at
             * a specified row and column is selected.
             *
             * @param r zero-based row of the table
             * @param c zero-based column of the table
             * @return the boolean value true if the accessible at the
             * row and column is selected. Otherwise, the boolean value
             * false
             */
            public boolean isAccessibleSelected(int r, int c) {
                if (validateIfNecessary()) {
                    if (r < 0 || r >= getAccessibleRowCount() ||
                        c < 0 || c >= getAccessibleColumnCount()) {
                        return false;
                    }
                    TableCellElementInfo cell = getCell(r, c);
                    if (cell != null) {
                        Element elem = cell.getElement();
                        int start = elem.getStartOffset();
                        int end = elem.getEndOffset();
                        return start >= editor.getSelectionStart() &&
                            end <= editor.getSelectionEnd();
                    }
                }
                return false;
            }

            /**
             * Returns a boolean value indicating whether the specified row
             * is selected.
             *
             * @param r zero-based row of the table
             * @return the boolean value true if the specified row is selected.
             * Otherwise, false.
             */
            public boolean isAccessibleRowSelected(int r) {
                if (validateIfNecessary()) {
                    if (r < 0 || r >= getAccessibleRowCount()) {
                        return false;
                    }
                    int nColumns = getAccessibleColumnCount();

                    TableCellElementInfo startCell = getCell(r, 0);
                    if (startCell == null) {
                        return false;
                    }
                    int start = startCell.getElement().getStartOffset();

                    TableCellElementInfo endCell = getCell(r, nColumns-1);
                    if (endCell == null) {
                        return false;
                    }
                    int end = endCell.getElement().getEndOffset();

                    return start >= editor.getSelectionStart() &&
                        end <= editor.getSelectionEnd();
                }
                return false;
            }

            /**
             * Returns a boolean value indicating whether the specified column
             * is selected.
             *
             * @param r zero-based column of the table
             * @return the boolean value true if the specified column is selected.
             * Otherwise, false.
             */
            public boolean isAccessibleColumnSelected(int c) {
                if (validateIfNecessary()) {
                    if (c < 0 || c >= getAccessibleColumnCount()) {
                        return false;
                    }
                    int nRows = getAccessibleRowCount();

                    TableCellElementInfo startCell = getCell(0, c);
                    if (startCell == null) {
                        return false;
                    }
                    int start = startCell.getElement().getStartOffset();

                    TableCellElementInfo endCell = getCell(nRows-1, c);
                    if (endCell == null) {
                        return false;
                    }
                    int end = endCell.getElement().getEndOffset();
                    return start >= editor.getSelectionStart() &&
                        end <= editor.getSelectionEnd();
                }
                return false;
            }

            /**
             * Returns the selected rows in a table.
             *
             * @return an array of selected rows where each element is a
             * zero-based row of the table
             */
            public int [] getSelectedAccessibleRows() {
                if (validateIfNecessary()) {
                    int nRows = getAccessibleRowCount();
                    Vector vec = new Vector();

                    for (int i = 0; i < nRows; i++) {
                        if (isAccessibleRowSelected(i)) {
                            vec.addElement(new Integer(i));
                        }
                    }
                    int retval[] = new int[vec.size()];
                    for (int i = 0; i < retval.length; i++) {
                        retval[i] = ((Integer)vec.elementAt(i)).intValue();
                    }
                    return retval;
                }
                return new int[0];
            }

            /**
             * Returns the selected columns in a table.
             *
             * @return an array of selected columns where each element is a
             * zero-based column of the table
             */
            public int [] getSelectedAccessibleColumns() {
                if (validateIfNecessary()) {
                    int nColumns = getAccessibleRowCount();
                    Vector vec = new Vector();

                    for (int i = 0; i < nColumns; i++) {
                        if (isAccessibleColumnSelected(i)) {
                            vec.addElement(new Integer(i));
                        }
                    }
                    int retval[] = new int[vec.size()];
                    for (int i = 0; i < retval.length; i++) {
                        retval[i] = ((Integer)vec.elementAt(i)).intValue();
                    }
                    return retval;
                }
                return new int[0];
            }

            // begin AccessibleExtendedTable implementation -------------

            /**
             * Returns the row number of an index in the table.
             *
             * @param index the zero-based index in the table
             * @return the zero-based row of the table if one exists;
             * otherwise -1.
             */
            public int getAccessibleRow(int index) {
                if (validateIfNecessary()) {
                    int numCells = getAccessibleColumnCount() *
                        getAccessibleRowCount();
                    if (index >= numCells) {
                        return -1;
                    } else {
                        return index / getAccessibleColumnCount();
                    }
                }
                return -1;
            }

            /**
             * Returns the column number of an index in the table.
             *
             * @param index the zero-based index in the table
             * @return the zero-based column of the table if one exists;
             * otherwise -1.
             */
            public int getAccessibleColumn(int index) {
                if (validateIfNecessary()) {
                    int numCells = getAccessibleColumnCount() *
                        getAccessibleRowCount();
                    if (index >= numCells) {
                        return -1;
                    } else {
                        return index % getAccessibleColumnCount();
                    }
                }
                return -1;
            }

            /**
             * Returns the index at a row and column in the table.
             *
             * @param r zero-based row of the table
             * @param c zero-based column of the table
             * @return the zero-based index in the table if one exists;
             * otherwise -1.
             */
            public int getAccessibleIndex(int r, int c) {
                if (validateIfNecessary()) {
                    if (r >= getAccessibleRowCount() ||
                        c >= getAccessibleColumnCount()) {
                        return -1;
                    } else {
                        return r * getAccessibleColumnCount() + c;
                    }
                }
                return -1;
            }

            /**
             * Returns the row header at a row in a table.
             * @param r zero-based row of the table
             *
             * @return a String representing the row header
             * if one exists; otherwise null.
             */
            public String getAccessibleRowHeader(int r) {
                if (validateIfNecessary()) {
                    TableCellElementInfo cellInfo = getCell(r, 0);
                    if (cellInfo.isHeaderCell()) {
                        View v = cellInfo.getView();
                        if (v != null && model != null) {
                            try {
                                return model.getText(v.getStartOffset(),
                                                     v.getEndOffset() -
                                                     v.getStartOffset());
                            } catch (BadLocationException e) {
                                return null;
                            }
                        }
                    }
                }
                return null;
            }

            /**
             * Returns the column header at a column in a table.
             * @param c zero-based column of the table
             *
             * @return a String representing the column header
             * if one exists; otherwise null.
             */
            public String getAccessibleColumnHeader(int c) {
                if (validateIfNecessary()) {
                    TableCellElementInfo cellInfo = getCell(0, c);
                    if (cellInfo.isHeaderCell()) {
                        View v = cellInfo.getView();
                        if (v != null && model != null) {
                            try {
                                return model.getText(v.getStartOffset(),
                                                     v.getEndOffset() -
                                                     v.getStartOffset());
                            } catch (BadLocationException e) {
                                return null;
                            }
                        }
                    }
                }
                return null;
            }

            public void addRowHeader(TableCellElementInfo cellInfo, int rowNumber) {
                if (rowHeadersTable == null) {
                    rowHeadersTable = new AccessibleHeadersTable();
                }
                rowHeadersTable.addHeader(cellInfo, rowNumber);
            }
            // end of AccessibleExtendedTable implementation ------------

            protected class AccessibleHeadersTable implements AccessibleTable {

                // Header information is modeled as a Hashtable of
                // ArrayLists where each Hashtable entry represents
                // a row containing one or more headers.
                private Hashtable headers = new Hashtable();
                private int rowCount = 0;
                private int columnCount = 0;

                public void addHeader(TableCellElementInfo cellInfo, int rowNumber) {
                    Integer rowInteger = new Integer(rowNumber);
                    ArrayList list = (ArrayList)headers.get(rowInteger);
                    if (list == null) {
                        list = new ArrayList();
                        headers.put(rowInteger, list);
                    }
                    list.add(cellInfo);
                }

                /**
                 * Returns the caption for the table.
                 *
                 * @return the caption for the table
                 */
                public Accessible getAccessibleCaption() {
                    return null;
                }

                /**
                 * Sets the caption for the table.
                 *
                 * @param a the caption for the table
                 */
                public void setAccessibleCaption(Accessible a) {
                }

                /**
                 * Returns the summary description of the table.
                 *
                 * @return the summary description of the table
                 */
                public Accessible getAccessibleSummary() {
                    return null;
                }

                /**
                 * Sets the summary description of the table
                 *
                 * @param a the summary description of the table
                 */
                public void setAccessibleSummary(Accessible a) {
                }

                /**
                 * Returns the number of rows in the table.
                 *
                 * @return the number of rows in the table
                 */
                public int getAccessibleRowCount() {
                    return rowCount;
                }

                /**
                 * Returns the number of columns in the table.
                 *
                 * @return the number of columns in the table
                 */
                public int getAccessibleColumnCount() {
                    return columnCount;
                }

                private TableCellElementInfo getElementInfoAt(int r, int c) {
                    ArrayList list = (ArrayList)headers.get(new Integer(r));
                    if (list != null) {
                        return (TableCellElementInfo)list.get(c);
                    } else {
                        return null;
                    }
                }

                /**
                 * Returns the Accessible at a specified row and column
                 * in the table.
                 *
                 * @param r zero-based row of the table
                 * @param c zero-based column of the table
                 * @return the Accessible at the specified row and column
                 */
                public Accessible getAccessibleAt(int r, int c) {
                    ElementInfo elementInfo = getElementInfoAt(r, c);
                    if (elementInfo instanceof Accessible) {
                        return (Accessible)elementInfo;
                    } else {
                        return null;
                    }
                }

                /**
                 * Returns the number of rows occupied by the Accessible at
                 * a specified row and column in the table.
                 *
                 * @return the number of rows occupied by the Accessible at a
                 * given specified (row, column)
                 */
                public int getAccessibleRowExtentAt(int r, int c) {
                    TableCellElementInfo elementInfo = getElementInfoAt(r, c);
                    if (elementInfo != null) {
                        return elementInfo.getRowCount();
                    } else {
                        return 0;
                    }
                }

                /**
                 * Returns the number of columns occupied by the Accessible at
                 * a specified row and column in the table.
                 *
                 * @return the number of columns occupied by the Accessible at a
                 * given specified row and column
                 */
                public int getAccessibleColumnExtentAt(int r, int c) {
                    TableCellElementInfo elementInfo = getElementInfoAt(r, c);
                    if (elementInfo != null) {
                        return elementInfo.getRowCount();
                    } else {
                        return 0;
                    }
                }

                /**
                 * Returns the row headers as an AccessibleTable.
                 *
                 * @return an AccessibleTable representing the row
                 * headers
                 */
                public AccessibleTable getAccessibleRowHeader() {
                    return null;
                }

                /**
                 * Sets the row headers.
                 *
                 * @param table an AccessibleTable representing the
                 * row headers
                 */
                public void setAccessibleRowHeader(AccessibleTable table) {
                }

                /**
                 * Returns the column headers as an AccessibleTable.
                 *
                 * @return an AccessibleTable representing the column
                 * headers
                 */
                public AccessibleTable getAccessibleColumnHeader() {
                    return null;
                }

                /**
                 * Sets the column headers.
                 *
                 * @param table an AccessibleTable representing the
                 * column headers
                 */
                public void setAccessibleColumnHeader(AccessibleTable table) {
                }

                /**
                 * Returns the description of the specified row in the table.
                 *
                 * @param r zero-based row of the table
                 * @return the description of the row
                 */
                public Accessible getAccessibleRowDescription(int r) {
                    return null;
                }

                /**
                 * Sets the description text of the specified row of the table.
                 *
                 * @param r zero-based row of the table
                 * @param a the description of the row
                 */
                public void setAccessibleRowDescription(int r, Accessible a) {
                }

                /**
                 * Returns the description text of the specified column in the table.
                 *
                 * @param c zero-based column of the table
                 * @return the text description of the column
                 */
                public Accessible getAccessibleColumnDescription(int c) {
                    return null;
                }

                /**
                 * Sets the description text of the specified column in the table.
                 *
                 * @param c zero-based column of the table
                 * @param a the text description of the column
                 */
                public void setAccessibleColumnDescription(int c, Accessible a) {
                }

                /**
                 * Returns a boolean value indicating whether the accessible at
                 * a specified row and column is selected.
                 *
                 * @param r zero-based row of the table
                 * @param c zero-based column of the table
                 * @return the boolean value true if the accessible at the
                 * row and column is selected. Otherwise, the boolean value
                 * false
                 */
                public boolean isAccessibleSelected(int r, int c) {
                    return false;
                }

                /**
                 * Returns a boolean value indicating whether the specified row
                 * is selected.
                 *
                 * @param r zero-based row of the table
                 * @return the boolean value true if the specified row is selected.
                 * Otherwise, false.
                 */
                public boolean isAccessibleRowSelected(int r) {
                    return false;
                }

                /**
                 * Returns a boolean value indicating whether the specified column
                 * is selected.
                 *
                 * @param r zero-based column of the table
                 * @return the boolean value true if the specified column is selected.
                 * Otherwise, false.
                 */
                public boolean isAccessibleColumnSelected(int c) {
                    return false;
                }

                /**
                 * Returns the selected rows in a table.
                 *
                 * @return an array of selected rows where each element is a
                 * zero-based row of the table
                 */
                public int [] getSelectedAccessibleRows() {
                    return new int [0];
                }

                /**
                 * Returns the selected columns in a table.
                 *
                 * @return an array of selected columns where each element is a
                 * zero-based column of the table
                 */
                public int [] getSelectedAccessibleColumns() {
                    return new int [0];
                }
            }
        } // ... end AccessibleHeadersTable

        /*
         * ElementInfo for table rows
         */
        private class TableRowElementInfo extends ElementInfo {

            private TableElementInfo parent;
            private int rowNumber;

            TableRowElementInfo(Element e, TableElementInfo parent, int rowNumber) {
                super(e, parent);
                this.parent = parent;
                this.rowNumber = rowNumber;
            }

            protected void loadChildren(Element e) {
                for (int x = 0; x < e.getElementCount(); x++) {
                    AttributeSet attrs = e.getElement(x).getAttributes();

                    if (attrs.getAttribute(StyleConstants.NameAttribute) ==
                            HTML.Tag.TH) {
                        TableCellElementInfo headerElementInfo =
                            new TableCellElementInfo(e.getElement(x), this, true);
                        addChild(headerElementInfo);

                        AccessibleTable at =
                            parent.getAccessibleContext().getAccessibleTable();
                        TableAccessibleContext tableElement =
                            (TableAccessibleContext)at;
                        tableElement.addRowHeader(headerElementInfo, rowNumber);

                    } else if (attrs.getAttribute(StyleConstants.NameAttribute) ==
                            HTML.Tag.TD) {
                        addChild(new TableCellElementInfo(e.getElement(x), this,
                                                          false));
                    }
                }
            }

            /**
             * Returns the max of the rowspans of the cells in this row.
             */
            public int getRowCount() {
                int rowCount = 1;
                if (validateIfNecessary()) {
                    for (int counter = 0; counter < getChildCount();
                         counter++) {

                        TableCellElementInfo cell = (TableCellElementInfo)
                                                    getChild(counter);

                        if (cell.validateIfNecessary()) {
                            rowCount = Math.max(rowCount, cell.getRowCount());
                        }
                    }
                }
                return rowCount;
            }

            /**
             * Returns the sum of the column spans of the individual
             * cells in this row.
             */
            public int getColumnCount() {
                int colCount = 0;
                if (validateIfNecessary()) {
                    for (int counter = 0; counter < getChildCount();
                         counter++) {
                        TableCellElementInfo cell = (TableCellElementInfo)
                                                    getChild(counter);

                        if (cell.validateIfNecessary()) {
                            colCount += cell.getColumnCount();
                        }
                    }
                }
                return colCount;
            }

            /**
             * Overriden to invalidate the table as well as
             * TableRowElementInfo.
             */
            protected void invalidate(boolean first) {
                super.invalidate(first);
                getParent().invalidate(true);
            }

            /**
             * Places the TableCellElementInfos for this element in
             * the grid.
             */
            private void updateGrid(int row) {
                if (validateIfNecessary()) {
                    boolean emptyRow = false;

                    while (!emptyRow) {
                        for (int counter = 0; counter < grid[row].length;
                                 counter++) {
                            if (grid[row][counter] == null) {
                                emptyRow = true;
                                break;
                            }
                        }
                        if (!emptyRow) {
                            row++;
                        }
                    }
                    for (int col = 0, counter = 0; counter < getChildCount();
                             counter++) {
                        TableCellElementInfo cell = (TableCellElementInfo)
                                                    getChild(counter);

                        while (grid[row][col] != null) {
                            col++;
                        }
                        for (int rowCount = cell.getRowCount() - 1;
                             rowCount >= 0; rowCount--) {
                            for (int colCount = cell.getColumnCount() - 1;
                                 colCount >= 0; colCount--) {
                                grid[row + rowCount][col + colCount] = cell;
                            }
                        }
                        col += cell.getColumnCount();
                    }
                }
            }

            /**
             * Returns the column count of the number of columns that have
             * a rowcount >= rowspan.
             */
            private int getColumnCount(int rowspan) {
                if (validateIfNecessary()) {
                    int cols = 0;
                    for (int counter = 0; counter < getChildCount();
                         counter++) {
                        TableCellElementInfo cell = (TableCellElementInfo)
                                                    getChild(counter);

                        if (cell.getRowCount() >= rowspan) {
                            cols += cell.getColumnCount();
                        }
                    }
                    return cols;
                }
                return 0;
            }
        }

        /**
         * TableCellElementInfo is used to represents the cells of
         * the table.
         */
        private class TableCellElementInfo extends ElementInfo {

            private Accessible accessible;
            private boolean isHeaderCell;

            TableCellElementInfo(Element e, ElementInfo parent) {
                super(e, parent);
                this.isHeaderCell = false;
            }

            TableCellElementInfo(Element e, ElementInfo parent,
                                 boolean isHeaderCell) {
                super(e, parent);
                this.isHeaderCell = isHeaderCell;
            }

            /*
             * Returns whether this table cell is a header
             */
            public boolean isHeaderCell() {
                return this.isHeaderCell;
            }

            /*
             * Returns the Accessible representing this table cell
             */
            public Accessible getAccessible() {
                accessible = null;
                getAccessible(this);
                return accessible;
            }

            /*
             * Gets the outermost Accessible in the table cell
             */
            private void getAccessible(ElementInfo elementInfo) {
                if (elementInfo instanceof Accessible) {
                    accessible = (Accessible)elementInfo;
                    return;
                } else {
                    for (int i = 0; i < elementInfo.getChildCount(); i++) {
                        getAccessible(elementInfo.getChild(i));
                    }
                }
            }

            /**
             * Returns the rowspan attribute.
             */
            public int getRowCount() {
                if (validateIfNecessary()) {
                    return Math.max(1, getIntAttr(getAttributes(),
                                                  HTML.Attribute.ROWSPAN, 1));
                }
                return 0;
            }

            /**
             * Returns the colspan attribute.
             */
            public int getColumnCount() {
                if (validateIfNecessary()) {
                    return Math.max(1, getIntAttr(getAttributes(),
                                                  HTML.Attribute.COLSPAN, 1));
                }
                return 0;
            }

            /**
             * Overriden to invalidate the TableRowElementInfo as well as
             * the TableCellElementInfo.
             */
            protected void invalidate(boolean first) {
                super.invalidate(first);
                getParent().invalidate(true);
            }
        }
    }


    /**
     * ElementInfo provides a slim down view of an Element.  Each ElementInfo
     * can have any number of child ElementInfos that are not necessarily
     * direct children of the Element. As the Document changes various
     * ElementInfos become invalidated. Before accessing a particular portion
     * of an ElementInfo you should make sure it is valid by invoking
     * <code>validateIfNecessary</code>, this will return true if
     * successful, on the other hand a false return value indicates the
     * ElementInfo is not valid and can never become valid again (usually
     * the result of the Element the ElementInfo encapsulates being removed).
     */
    private class ElementInfo {

        /**
         * The children of this ElementInfo.
         */
        private ArrayList children;
        /**
         * The Element this ElementInfo is providing information for.
         */
        private Element element;
        /**
         * The parent ElementInfo, will be null for the root.
         */
        private ElementInfo parent;
        /**
         * Indicates the validity of the ElementInfo.
         */
        private boolean isValid;
        /**
         * Indicates if the ElementInfo can become valid.
         */
        private boolean canBeValid;


        /**
         * Creates the root ElementInfo.
         */
        ElementInfo(Element element) {
            this(element, null);
        }

        /**
         * Creates an ElementInfo representing <code>element</code> with
         * the specified parent.
         */
        ElementInfo(Element element, ElementInfo parent) {
            this.element = element;
            this.parent = parent;
            isValid = false;
            canBeValid = true;
        }

        /**
         * Validates the receiver. This recreates the children as well. This
         * will be invoked within a <code>readLock</code>. If this is overriden
         * it MUST invoke supers implementation first!
         */
        protected void validate() {
            isValid = true;
            loadChildren(getElement());
        }

        /**
         * Recreates the direct children of <code>info</code>.
         */
        protected void loadChildren(Element parent) {
            if (!parent.isLeaf()) {
                for (int counter = 0, maxCounter = parent.getElementCount();
                    counter < maxCounter; counter++) {
                    Element e = parent.getElement(counter);
                    ElementInfo childInfo = createElementInfo(e, this);

                    if (childInfo != null) {
                        addChild(childInfo);
                    }
                    else {
                        loadChildren(e);
                    }
                }
            }
        }

        /**
         * Returns the index of the child in the parent, or -1 for the
         * root or if the parent isn't valid.
         */
        public int getIndexInParent() {
            if (parent == null || !parent.isValid()) {
                return -1;
            }
            return parent.indexOf(this);
        }

        /**
         * Returns the Element this <code>ElementInfo</code> represents.
         */
        public Element getElement() {
            return element;
        }

        /**
         * Returns the parent of this Element, or null for the root.
         */
        public ElementInfo getParent() {
            return parent;
        }

        /**
         * Returns the index of the specified child, or -1 if
         * <code>child</code> isn't a valid child.
         */
        public int indexOf(ElementInfo child) {
            ArrayList children = this.children;

            if (children != null) {
                return children.indexOf(child);
            }
            return -1;
        }

        /**
         * Returns the child ElementInfo at <code>index</code>, or null
         * if <code>index</code> isn't a valid index.
         */
        public ElementInfo getChild(int index) {
            if (validateIfNecessary()) {
                ArrayList children = this.children;

                if (children != null && index >= 0 &&
                                        index < children.size()) {
                    return (ElementInfo)children.get(index);
                }
            }
            return null;
        }

        /**
         * Returns the number of children the ElementInfo contains.
         */
        public int getChildCount() {
            validateIfNecessary();
            return (children == null) ? 0 : children.size();
        }

        /**
         * Adds a new child to this ElementInfo.
         */
        protected void addChild(ElementInfo child) {
            if (children == null) {
                children = new ArrayList();
            }
            children.add(child);
        }

        /**
         * Returns the View corresponding to this ElementInfo, or null
         * if the ElementInfo can't be validated.
         */
        protected View getView() {
            if (!validateIfNecessary()) {
                return null;
            }
            Object lock = lock();
            try {
                View rootView = getRootView();
                Element e = getElement();
                int start = e.getStartOffset();

                if (rootView != null) {
                    return getView(rootView, e, start);
                }
                return null;
            } finally {
                unlock(lock);
            }
        }

        /**
         * Returns the Bounds for this ElementInfo, or null
         * if the ElementInfo can't be validated.
         */
        public Rectangle getBounds() {
            if (!validateIfNecessary()) {
                return null;
            }
            Object lock = lock();
            try {
                Rectangle bounds = getRootEditorRect();
                View rootView = getRootView();
                Element e = getElement();

                if (bounds != null && rootView != null) {
                    try {
                        return rootView.modelToView(e.getStartOffset(),
                                                    Position.Bias.Forward,
                                                    e.getEndOffset(),
                                                    Position.Bias.Backward,
                                                    bounds).getBounds();
                    } catch (BadLocationException ble) { }
                }
            } finally {
                unlock(lock);
            }
            return null;
        }

        /**
         * Returns true if this ElementInfo is valid.
         */
        protected boolean isValid() {
            return isValid;
        }

        /**
         * Returns the AttributeSet associated with the Element, this will
         * return null if the ElementInfo can't be validated.
         */
        protected AttributeSet getAttributes() {
            if (validateIfNecessary()) {
                return getElement().getAttributes();
            }
            return null;
        }

        /**
         * Returns the AttributeSet associated with the View that is
         * representing this Element, this will
         * return null if the ElementInfo can't be validated.
         */
        protected AttributeSet getViewAttributes() {
            if (validateIfNecessary()) {
                View view = getView();

                if (view != null) {
                    return view.getElement().getAttributes();
                }
                return getElement().getAttributes();
            }
            return null;
        }

        /**
         * Convenience method for getting an integer attribute from the passed
         * in AttributeSet.
         */
        protected int getIntAttr(AttributeSet attrs, Object key, int deflt) {
            if (attrs != null && attrs.isDefined(key)) {
                int i;
                String val = (String)attrs.getAttribute(key);
                if (val == null) {
                    i = deflt;
                }
                else {
                    try {
                        i = Math.max(0, Integer.parseInt(val));
                    } catch (NumberFormatException x) {
                        i = deflt;
                    }
                }
                return i;
            }
            return deflt;
        }

        /**
         * Validates the ElementInfo if necessary.  Some ElementInfos may
         * never be valid again.  You should check <code>isValid</code> before
         * using one.  This will reload the children and invoke
         * <code>validate</code> if the ElementInfo is invalid and can become
         * valid again. This will return true if the receiver is valid.
         */
        protected boolean validateIfNecessary() {
            if (!isValid() && canBeValid) {
                children = null;
                Object lock = lock();

                try {
                    validate();
                } finally {
                    unlock(lock);
                }
            }
            return isValid();
        }

        /**
         * Invalidates the ElementInfo. Subclasses should override this
         * if they need to reset state once invalid.
         */
        protected void invalidate(boolean first) {
            if (!isValid()) {
                if (canBeValid && !first) {
                    canBeValid = false;
                }
                return;
            }
            isValid = false;
            canBeValid = first;
            if (children != null) {
                for (int counter = 0; counter < children.size(); counter++) {
                    ((ElementInfo)children.get(counter)).invalidate(false);
                }
                children = null;
            }
        }

        private View getView(View parent, Element e, int start) {
            if (parent.getElement() == e) {
                return parent;
            }
            int index = parent.getViewIndex(start, Position.Bias.Forward);

            if (index != -1 && index < parent.getViewCount()) {
                return getView(parent.getView(index), e, start);
            }
            return null;
        }

        private int getClosestInfoIndex(int index) {
            for (int counter = 0; counter < getChildCount(); counter++) {
                ElementInfo info = getChild(counter);

                if (index < info.getElement().getEndOffset() ||
                    index == info.getElement().getStartOffset()) {
                    return counter;
                }
            }
            return -1;
        }

        private void update(DocumentEvent e) {
            if (!isValid()) {
                return;
            }
            ElementInfo parent = getParent();
            Element element = getElement();

            do {
                DocumentEvent.ElementChange ec = e.getChange(element);
                if (ec != null) {
                    if (element == getElement()) {
                        // One of our children changed.
                        invalidate(true);
                    }
                    else if (parent != null) {
                        parent.invalidate(parent == getRootInfo());
                    }
                    return;
                }
                element = element.getParentElement();
            } while (parent != null && element != null &&
                     element != parent.getElement());

            if (getChildCount() > 0) {
                Element elem = getElement();
                int pos = e.getOffset();
                int index0 = getClosestInfoIndex(pos);
                if (index0 == -1 &&
                    e.getType() == DocumentEvent.EventType.REMOVE &&
                    pos >= elem.getEndOffset()) {
                    // Event beyond our offsets. We may have represented this,
                    // that is the remove may have removed one of our child
                    // Elements that represented this, so, we should foward
                    // to last element.
                    index0 = getChildCount() - 1;
                }
                ElementInfo info = (index0 >= 0) ? getChild(index0) : null;
                if (info != null &&
                    (info.getElement().getStartOffset() == pos) && (pos > 0)) {
                    // If at a boundary, forward the event to the previous
                    // ElementInfo too.
                    index0 = Math.max(index0 - 1, 0);
                }
                int index1;
                if (e.getType() != DocumentEvent.EventType.REMOVE) {
                    index1 = getClosestInfoIndex(pos + e.getLength());
                    if (index1 < 0) {
                        index1 = getChildCount() - 1;
                    }
                }
                else {
                    index1 = index0;
                    // A remove may result in empty elements.
                    while ((index1 + 1) < getChildCount() &&
                           getChild(index1 + 1).getElement().getEndOffset() ==
                           getChild(index1 + 1).getElement().getStartOffset()){
                        index1++;
                    }
                }
                index0 = Math.max(index0, 0);
                // The check for isValid is here as in the process of
                // forwarding update our child may invalidate us.
                for (int i = index0; i <= index1 && isValid(); i++) {
                    getChild(i).update(e);
                }
            }
        }
    }

    /**
     * DocumentListener installed on the current Document.  Will invoke
     * <code>update</code> on the <code>RootInfo</code> in response to
     * any event.
     */
    private class DocumentHandler implements DocumentListener {
        public void insertUpdate(DocumentEvent e) {
            getRootInfo().update(e);
        }
        public void removeUpdate(DocumentEvent e) {
            getRootInfo().update(e);
        }
        public void changedUpdate(DocumentEvent e) {
            getRootInfo().update(e);
        }
    }

    /*
     * PropertyChangeListener installed on the editor.
     */
    private class PropertyChangeHandler implements PropertyChangeListener {
        public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getPropertyName().equals("document")) {
                // handle the document change
                setDocument(editor.getDocument());
            }
        }
    }
}
