/*
 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package javax.swing.text.html;

import sun.swing.SwingUtilities2;
import java.util.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.UIManager;
import javax.swing.border.*;
import javax.swing.event.ChangeListener;
import javax.swing.text.*;

/**
 * Support for defining the visual characteristics of
 * HTML views being rendered.  The StyleSheet is used to
 * translate the HTML model into visual characteristics.
 * This enables views to be customized by a look-and-feel,
 * multiple views over the same model can be rendered
 * differently, etc.  This can be thought of as a CSS
 * rule repository.  The key for CSS attributes is an
 * object of type CSS.Attribute.  The type of the value
 * is up to the StyleSheet implementation, but the
 * <code>toString</code> method is required
 * to return a string representation of CSS value.
 * <p>
 * The primary entry point for HTML View implementations
 * to get their attributes is the
 * <a href="#getViewAttributes">getViewAttributes</a>
 * method.  This should be implemented to establish the
 * desired policy used to associate attributes with the view.
 * Each HTMLEditorKit (i.e. and therefore each associated
 * JEditorPane) can have its own StyleSheet, but by default one
 * sheet will be shared by all of the HTMLEditorKit instances.
 * HTMLDocument instance can also have a StyleSheet, which
 * holds the document-specific CSS specifications.
 * <p>
 * In order for Views to store less state and therefore be
 * more lightweight, the StyleSheet can act as a factory for
 * painters that handle some of the rendering tasks.  This allows
 * implementations to determine what they want to cache
 * and have the sharing potentially at the level that a
 * selector is common to multiple views.  Since the StyleSheet
 * may be used by views over multiple documents and typically
 * the HTML attributes don't effect the selector being used,
 * the potential for sharing is significant.
 * <p>
 * The rules are stored as named styles, and other information
 * is stored to translate the context of an element to a
 * rule quickly.  The following code fragment will display
 * the named styles, and therefore the CSS rules contained.
 * <code><pre>
 * &nbsp;
 * &nbsp; import java.util.*;
 * &nbsp; import javax.swing.text.*;
 * &nbsp; import javax.swing.text.html.*;
 * &nbsp;
 * &nbsp; public class ShowStyles {
 * &nbsp;
 * &nbsp;     public static void main(String[] args) {
 * &nbsp;       HTMLEditorKit kit = new HTMLEditorKit();
 * &nbsp;       HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
 * &nbsp;       StyleSheet styles = doc.getStyleSheet();
 * &nbsp;
 * &nbsp;       Enumeration rules = styles.getStyleNames();
 * &nbsp;       while (rules.hasMoreElements()) {
 * &nbsp;           String name = (String) rules.nextElement();
 * &nbsp;           Style rule = styles.getStyle(name);
 * &nbsp;           System.out.println(rule.toString());
 * &nbsp;       }
 * &nbsp;       System.exit(0);
 * &nbsp;     }
 * &nbsp; }
 * &nbsp;
 * </pre></code>
 * <p>
 * The semantics for when a CSS style should overide visual attributes
 * defined by an element are not well defined. For example, the html
 * <code>&lt;body bgcolor=red&gt;</code> makes the body have a red
 * background. But if the html file also contains the CSS rule
 * <code>body { background: blue }</code> it becomes less clear as to
 * what color the background of the body should be. The current
 * implemention gives visual attributes defined in the element the
 * highest precedence, that is they are always checked before any styles.
 * Therefore, in the previous example the background would have a
 * red color as the body element defines the background color to be red.
 * <p>
 * As already mentioned this supports CSS. We don't support the full CSS
 * spec. Refer to the javadoc of the CSS class to see what properties
 * we support. The two major CSS parsing related
 * concepts we do not currently
 * support are pseudo selectors, such as <code>A:link { color: red }</code>,
 * and the <code>important</code> modifier.
 * <p>
 * <font color="red">Note: This implementation is currently
 * incomplete.  It can be replaced with alternative implementations
 * that are complete.  Future versions of this class will provide
 * better CSS support.</font>
 *
 * @author  Timothy Prinzing
 * @author  Sunita Mani
 * @author  Sara Swanson
 * @author  Jill Nakata
 */
public class StyleSheet extends StyleContext {
    // As the javadoc states, this class maintains a mapping between
    // a CSS selector (such as p.bar) and a Style.
    // This consists of a number of parts:
    // . Each selector is broken down into its constituent simple selectors,
    //   and stored in an inverted graph, for example:
    //     p { color: red } ol p { font-size: 10pt } ul p { font-size: 12pt }
    //   results in the graph:
    //          root
    //           |
    //           p
    //          / \
    //         ol ul
    //   each node (an instance of SelectorMapping) has an associated
    //   specificity and potentially a Style.
    // . Every rule that is asked for (either by way of getRule(String) or
    //   getRule(HTML.Tag, Element)) results in a unique instance of
    //   ResolvedStyle. ResolvedStyles contain the AttributeSets from the
    //   SelectorMapping.
    // . When a new rule is created it is inserted into the graph, and
    //   the AttributeSets of each ResolvedStyles are updated appropriately.
    // . This class creates special AttributeSets, LargeConversionSet and
    //   SmallConversionSet, that maintain a mapping between StyleConstants
    //   and CSS so that developers that wish to use the StyleConstants
    //   methods can do so.
    // . When one of the AttributeSets is mutated by way of a
    //   StyleConstants key, all the associated CSS keys are removed. This is
    //   done so that the two representations don't get out of sync. For
    //   example, if the developer adds StyleConsants.BOLD, FALSE to an
    //   AttributeSet that contains HTML.Tag.B, the HTML.Tag.B entry will
    //   be removed.

    /**
     * Construct a StyleSheet
     */
    public StyleSheet() {
        super();
        selectorMapping = new SelectorMapping(0);
        resolvedStyles = new Hashtable<String, ResolvedStyle>();
        if (css == null) {
            css = new CSS();
        }
    }

    /**
     * Fetches the style to use to render the given type
     * of HTML tag.  The element given is representing
     * the tag and can be used to determine the nesting
     * for situations where the attributes will differ
     * if nesting inside of elements.
     *
     * @param t the type to translate to visual attributes
     * @param e the element representing the tag; the element
     *  can be used to determine the nesting for situations where
     *  the attributes will differ if nested inside of other
     *  elements
     * @return the set of CSS attributes to use to render
     *  the tag
     */
    public Style getRule(HTML.Tag t, Element e) {
        SearchBuffer sb = SearchBuffer.obtainSearchBuffer();

        try {
            // Build an array of all the parent elements.
            Vector<Element> searchContext = sb.getVector();

            for (Element p = e; p != null; p = p.getParentElement()) {
                searchContext.addElement(p);
            }

            // Build a fully qualified selector.
            int              n = searchContext.size();
            StringBuffer     cacheLookup = sb.getStringBuffer();
            AttributeSet     attr;
            String           eName;
            Object           name;

            // >= 1 as the HTML.Tag for the 0th element is passed in.
            for (int counter = n - 1; counter >= 1; counter--) {
                e = searchContext.elementAt(counter);
                attr = e.getAttributes();
                name = attr.getAttribute(StyleConstants.NameAttribute);
                eName = name.toString();
                cacheLookup.append(eName);
                if (attr != null) {
                    if (attr.isDefined(HTML.Attribute.ID)) {
                        cacheLookup.append('#');
                        cacheLookup.append(attr.getAttribute
                                           (HTML.Attribute.ID));
                    }
                    else if (attr.isDefined(HTML.Attribute.CLASS)) {
                        cacheLookup.append('.');
                        cacheLookup.append(attr.getAttribute
                                           (HTML.Attribute.CLASS));
                    }
                }
                cacheLookup.append(' ');
            }
            cacheLookup.append(t.toString());
            e = searchContext.elementAt(0);
            attr = e.getAttributes();
            if (e.isLeaf()) {
                // For leafs, we use the second tier attributes.
                Object testAttr = attr.getAttribute(t);
                if (testAttr instanceof AttributeSet) {
                    attr = (AttributeSet)testAttr;
                }
                else {
                    attr = null;
                }
            }
            if (attr != null) {
                if (attr.isDefined(HTML.Attribute.ID)) {
                    cacheLookup.append('#');
                    cacheLookup.append(attr.getAttribute(HTML.Attribute.ID));
                }
                else if (attr.isDefined(HTML.Attribute.CLASS)) {
                    cacheLookup.append('.');
                    cacheLookup.append(attr.getAttribute
                                       (HTML.Attribute.CLASS));
                }
            }

            Style style = getResolvedStyle(cacheLookup.toString(),
                                           searchContext, t);
            return style;
        }
        finally {
            SearchBuffer.releaseSearchBuffer(sb);
        }
    }

    /**
     * Fetches the rule that best matches the selector given
     * in string form. Where <code>selector</code> is a space separated
     * String of the element names. For example, <code>selector</code>
     * might be 'html body tr td''<p>
     * The attributes of the returned Style will change
     * as rules are added and removed. That is if you to ask for a rule
     * with a selector "table p" and a new rule was added with a selector
     * of "p" the returned Style would include the new attributes from
     * the rule "p".
     */
    public Style getRule(String selector) {
        selector = cleanSelectorString(selector);
        if (selector != null) {
            Style style = getResolvedStyle(selector);
            return style;
        }
        return null;
    }

    /**
     * Adds a set of rules to the sheet.  The rules are expected to
     * be in valid CSS format.  Typically this would be called as
     * a result of parsing a &lt;style&gt; tag.
     */
    public void addRule(String rule) {
        if (rule != null) {
            //tweaks to control display properties
            //see BasicEditorPaneUI
            final String baseUnitsDisable = "BASE_SIZE_DISABLE";
            final String baseUnits = "BASE_SIZE ";
            final String w3cLengthUnitsEnable = "W3C_LENGTH_UNITS_ENABLE";
            final String w3cLengthUnitsDisable = "W3C_LENGTH_UNITS_DISABLE";
            if (rule == baseUnitsDisable) {
                sizeMap = sizeMapDefault;
            } else if (rule.startsWith(baseUnits)) {
                rebaseSizeMap(Integer.
                              parseInt(rule.substring(baseUnits.length())));
            } else if (rule == w3cLengthUnitsEnable) {
                w3cLengthUnits = true;
            } else if (rule == w3cLengthUnitsDisable) {
                w3cLengthUnits = false;
            } else {
                CssParser parser = new CssParser();
                try {
                    parser.parse(getBase(), new StringReader(rule), false, false);
                } catch (IOException ioe) { }
            }
        }
    }

    /**
     * Translates a CSS declaration to an AttributeSet that represents
     * the CSS declaration.  Typically this would be called as a
     * result of encountering an HTML style attribute.
     */
    public AttributeSet getDeclaration(String decl) {
        if (decl == null) {
            return SimpleAttributeSet.EMPTY;
        }
        CssParser parser = new CssParser();
        return parser.parseDeclaration(decl);
    }

    /**
     * Loads a set of rules that have been specified in terms of
     * CSS1 grammar.  If there are collisions with existing rules,
     * the newly specified rule will win.
     *
     * @param in the stream to read the CSS grammar from
     * @param ref the reference URL.  This value represents the
     *  location of the stream and may be null.  All relative
     *  URLs specified in the stream will be based upon this
     *  parameter.
     */
    public void loadRules(Reader in, URL ref) throws IOException {
        CssParser parser = new CssParser();
        parser.parse(ref, in, false, false);
    }

    /**
     * Fetches a set of attributes to use in the view for
     * displaying.  This is basically a set of attributes that
     * can be used for View.getAttributes.
     */
    public AttributeSet getViewAttributes(View v) {
        return new ViewAttributeSet(v);
    }

    /**
     * Removes a named style previously added to the document.
     *
     * @param nm  the name of the style to remove
     */
    public void removeStyle(String nm) {
        Style       aStyle = getStyle(nm);

        if (aStyle != null) {
            String selector = cleanSelectorString(nm);
            String[] selectors = getSimpleSelectors(selector);
            synchronized(this) {
                SelectorMapping mapping = getRootSelectorMapping();
                for (int i = selectors.length - 1; i >= 0; i--) {
                    mapping = mapping.getChildSelectorMapping(selectors[i],
                                                              true);
                }
                Style rule = mapping.getStyle();
                if (rule != null) {
                    mapping.setStyle(null);
                    if (resolvedStyles.size() > 0) {
                        Enumeration<ResolvedStyle> values = resolvedStyles.elements();
                        while (values.hasMoreElements()) {
                            ResolvedStyle style = values.nextElement();
                            style.removeStyle(rule);
                        }
                    }
                }
            }
        }
        super.removeStyle(nm);
    }

    /**
     * Adds the rules from the StyleSheet <code>ss</code> to those of
     * the receiver. <code>ss's</code> rules will override the rules of
     * any previously added style sheets. An added StyleSheet will never
     * override the rules of the receiving style sheet.
     *
     * @since 1.3
     */
    public void addStyleSheet(StyleSheet ss) {
        synchronized(this) {
            if (linkedStyleSheets == null) {
                linkedStyleSheets = new Vector<StyleSheet>();
            }
            if (!linkedStyleSheets.contains(ss)) {
                int index = 0;
                if (ss instanceof javax.swing.plaf.UIResource
                    && linkedStyleSheets.size() > 1) {
                    index = linkedStyleSheets.size() - 1;
                }
                linkedStyleSheets.insertElementAt(ss, index);
                linkStyleSheetAt(ss, index);
            }
        }
    }

    /**
     * Removes the StyleSheet <code>ss</code> from those of the receiver.
     *
     * @since 1.3
     */
    public void removeStyleSheet(StyleSheet ss) {
        synchronized(this) {
            if (linkedStyleSheets != null) {
                int index = linkedStyleSheets.indexOf(ss);
                if (index != -1) {
                    linkedStyleSheets.removeElementAt(index);
                    unlinkStyleSheet(ss, index);
                    if (index == 0 && linkedStyleSheets.size() == 0) {
                        linkedStyleSheets = null;
                    }
                }
            }
        }
    }

    //
    // The following is used to import style sheets.
    //

    /**
     * Returns an array of the linked StyleSheets. Will return null
     * if there are no linked StyleSheets.
     *
     * @since 1.3
     */
    public StyleSheet[] getStyleSheets() {
        StyleSheet[] retValue;

        synchronized(this) {
            if (linkedStyleSheets != null) {
                retValue = new StyleSheet[linkedStyleSheets.size()];
                linkedStyleSheets.copyInto(retValue);
            }
            else {
                retValue = null;
            }
        }
        return retValue;
    }

    /**
     * Imports a style sheet from <code>url</code>. The resulting rules
     * are directly added to the receiver. If you do not want the rules
     * to become part of the receiver, create a new StyleSheet and use
     * addStyleSheet to link it in.
     *
     * @since 1.3
     */
    public void importStyleSheet(URL url) {
        try {
            InputStream is;

            is = url.openStream();
            Reader r = new BufferedReader(new InputStreamReader(is));
            CssParser parser = new CssParser();
            parser.parse(url, r, false, true);
            r.close();
            is.close();
        } catch (Throwable e) {
            // on error we simply have no styles... the html
            // will look mighty wrong but still function.
        }
    }

    /**
     * Sets the base. All import statements that are relative, will be
     * relative to <code>base</code>.
     *
     * @since 1.3
     */
    public void setBase(URL base) {
        this.base = base;
    }

    /**
     * Returns the base.
     *
     * @since 1.3
     */
    public URL getBase() {
        return base;
    }

    /**
     * Adds a CSS attribute to the given set.
     *
     * @since 1.3
     */
    public void addCSSAttribute(MutableAttributeSet attr, CSS.Attribute key,
                                String value) {
        css.addInternalCSSValue(attr, key, value);
    }

    /**
     * Adds a CSS attribute to the given set.
     *
     * @since 1.3
     */
    public boolean addCSSAttributeFromHTML(MutableAttributeSet attr,
                                           CSS.Attribute key, String value) {
        Object iValue = css.getCssValue(key, value);
        if (iValue != null) {
            attr.addAttribute(key, iValue);
            return true;
        }
        return false;
    }

    // ---- Conversion functionality ---------------------------------

    /**
     * Converts a set of HTML attributes to an equivalent
     * set of CSS attributes.
     *
     * @param htmlAttrSet AttributeSet containing the HTML attributes.
     */
    public AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet) {
        AttributeSet cssAttrSet = css.translateHTMLToCSS(htmlAttrSet);

        MutableAttributeSet cssStyleSet = addStyle(null, null);
        cssStyleSet.addAttributes(cssAttrSet);

        return cssStyleSet;
    }

    /**
     * Adds an attribute to the given set, and returns
     * the new representative set.  This is reimplemented to
     * convert StyleConstant attributes to CSS prior to forwarding
     * to the superclass behavior.  The StyleConstants attribute
     * has no corresponding CSS entry, the StyleConstants attribute
     * is stored (but will likely be unused).
     *
     * @param old the old attribute set
     * @param key the non-null attribute key
     * @param value the attribute value
     * @return the updated attribute set
     * @see MutableAttributeSet#addAttribute
     */
    public AttributeSet addAttribute(AttributeSet old, Object key,
                                     Object value) {
        if (css == null) {
            // supers constructor will call this before returning,
            // and we need to make sure CSS is non null.
            css = new CSS();
        }
        if (key instanceof StyleConstants) {
            HTML.Tag tag = HTML.getTagForStyleConstantsKey(
                                (StyleConstants)key);

            if (tag != null && old.isDefined(tag)) {
                old = removeAttribute(old, tag);
            }

            Object cssValue = css.styleConstantsValueToCSSValue
                              ((StyleConstants)key, value);
            if (cssValue != null) {
                Object cssKey = css.styleConstantsKeyToCSSKey
                                    ((StyleConstants)key);
                if (cssKey != null) {
                    return super.addAttribute(old, cssKey, cssValue);
                }
            }
        }
        return super.addAttribute(old, key, value);
    }

    /**
     * Adds a set of attributes to the element.  If any of these attributes
     * are StyleConstants attributes, they will be converted to CSS prior
     * to forwarding to the superclass behavior.
     *
     * @param old the old attribute set
     * @param attr the attributes to add
     * @return the updated attribute set
     * @see MutableAttributeSet#addAttribute
     */
    public AttributeSet addAttributes(AttributeSet old, AttributeSet attr) {
        if (!(attr instanceof HTMLDocument.TaggedAttributeSet)) {
            old = removeHTMLTags(old, attr);
        }
        return super.addAttributes(old, convertAttributeSet(attr));
    }

    /**
     * Removes an attribute from the set.  If the attribute is a StyleConstants
     * attribute, the request will be converted to a CSS attribute prior to
     * forwarding to the superclass behavior.
     *
     * @param old the old set of attributes
     * @param key the non-null attribute name
     * @return the updated attribute set
     * @see MutableAttributeSet#removeAttribute
     */
    public AttributeSet removeAttribute(AttributeSet old, Object key) {
        if (key instanceof StyleConstants) {
            HTML.Tag tag = HTML.getTagForStyleConstantsKey(
                                   (StyleConstants)key);
            if (tag != null) {
                old = super.removeAttribute(old, tag);
            }

            Object cssKey = css.styleConstantsKeyToCSSKey((StyleConstants)key);
            if (cssKey != null) {
                return super.removeAttribute(old, cssKey);
            }
        }
        return super.removeAttribute(old, key);
    }

    /**
     * Removes a set of attributes for the element.  If any of the attributes
     * is a StyleConstants attribute, the request will be converted to a CSS
     * attribute prior to forwarding to the superclass behavior.
     *
     * @param old the old attribute set
     * @param names the attribute names
     * @return the updated attribute set
     * @see MutableAttributeSet#removeAttributes
     */
    public AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names) {
        // PENDING: Should really be doing something similar to
        // removeHTMLTags here, but it is rather expensive to have to
        // clone names
        return super.removeAttributes(old, names);
    }

    /**
     * Removes a set of attributes. If any of the attributes
     * is a StyleConstants attribute, the request will be converted to a CSS
     * attribute prior to forwarding to the superclass behavior.
     *
     * @param old the old attribute set
     * @param attrs the attributes
     * @return the updated attribute set
     * @see MutableAttributeSet#removeAttributes
     */
    public AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs) {
        if (old != attrs) {
            old = removeHTMLTags(old, attrs);
        }
        return super.removeAttributes(old, convertAttributeSet(attrs));
    }

    /**
     * Creates a compact set of attributes that might be shared.
     * This is a hook for subclasses that want to alter the
     * behavior of SmallAttributeSet.  This can be reimplemented
     * to return an AttributeSet that provides some sort of
     * attribute conversion.
     *
     * @param a The set of attributes to be represented in the
     *  the compact form.
     */
    protected SmallAttributeSet createSmallAttributeSet(AttributeSet a) {
        return new SmallConversionSet(a);
    }

    /**
     * Creates a large set of attributes that should trade off
     * space for time.  This set will not be shared.  This is
     * a hook for subclasses that want to alter the behavior
     * of the larger attribute storage format (which is
     * SimpleAttributeSet by default).   This can be reimplemented
     * to return a MutableAttributeSet that provides some sort of
     * attribute conversion.
     *
     * @param a The set of attributes to be represented in the
     *  the larger form.
     */
    protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) {
        return new LargeConversionSet(a);
    }

    /**
     * For any StyleConstants key in attr that has an associated HTML.Tag,
     * it is removed from old. The resulting AttributeSet is then returned.
     */
    private AttributeSet removeHTMLTags(AttributeSet old, AttributeSet attr) {
        if (!(attr instanceof LargeConversionSet) &&
            !(attr instanceof SmallConversionSet)) {
            Enumeration names = attr.getAttributeNames();

            while (names.hasMoreElements()) {
                Object key = names.nextElement();

                if (key instanceof StyleConstants) {
                    HTML.Tag tag = HTML.getTagForStyleConstantsKey(
                        (StyleConstants)key);

                    if (tag != null && old.isDefined(tag)) {
                        old = super.removeAttribute(old, tag);
                    }
                }
            }
        }
        return old;
    }

    /**
     * Converts a set of attributes (if necessary) so that
     * any attributes that were specified as StyleConstants
     * attributes and have a CSS mapping, will be converted
     * to CSS attributes.
     */
    AttributeSet convertAttributeSet(AttributeSet a) {
        if ((a instanceof LargeConversionSet) ||
            (a instanceof SmallConversionSet)) {
            // known to be converted.
            return a;
        }
        // in most cases, there are no StyleConstants attributes
        // so we iterate the collection of keys to avoid creating
        // a new set.
        Enumeration names = a.getAttributeNames();
        while (names.hasMoreElements()) {
            Object name = names.nextElement();
            if (name instanceof StyleConstants) {
                // we really need to do a conversion, iterate again
                // building a new set.
                MutableAttributeSet converted = new LargeConversionSet();
                Enumeration keys = a.getAttributeNames();
                while (keys.hasMoreElements()) {
                    Object key = keys.nextElement();
                    Object cssValue = null;
                    if (key instanceof StyleConstants) {
                        // convert the StyleConstants attribute if possible
                        Object cssKey = css.styleConstantsKeyToCSSKey
                                            ((StyleConstants)key);
                        if (cssKey != null) {
                            Object value = a.getAttribute(key);
                            cssValue = css.styleConstantsValueToCSSValue
                                           ((StyleConstants)key, value);
                            if (cssValue != null) {
                                converted.addAttribute(cssKey, cssValue);
                            }
                        }
                    }
                    if (cssValue == null) {
                        converted.addAttribute(key, a.getAttribute(key));
                    }
                }
                return converted;
            }
        }
        return a;
    }

    /**
     * Large set of attributes that does conversion of requests
     * for attributes of type StyleConstants.
     */
    class LargeConversionSet extends SimpleAttributeSet {

        /**
         * Creates a new attribute set based on a supplied set of attributes.
         *
         * @param source the set of attributes
         */
        public LargeConversionSet(AttributeSet source) {
            super(source);
        }

        public LargeConversionSet() {
            super();
        }

        /**
         * Checks whether a given attribute is defined.
         *
         * @param key the attribute key
         * @return true if the attribute is defined
         * @see AttributeSet#isDefined
         */
        public boolean isDefined(Object key) {
            if (key instanceof StyleConstants) {
                Object cssKey = css.styleConstantsKeyToCSSKey
                                    ((StyleConstants)key);
                if (cssKey != null) {
                    return super.isDefined(cssKey);
                }
            }
            return super.isDefined(key);
        }

        /**
         * Gets the value of an attribute.
         *
         * @param key the attribute name
         * @return the attribute value
         * @see AttributeSet#getAttribute
         */
        public Object getAttribute(Object key) {
            if (key instanceof StyleConstants) {
                Object cssKey = css.styleConstantsKeyToCSSKey
                                    ((StyleConstants)key);
                if (cssKey != null) {
                    Object value = super.getAttribute(cssKey);
                    if (value != null) {
                        return css.cssValueToStyleConstantsValue
                                           ((StyleConstants)key, value);
                    }
                }
            }
            return super.getAttribute(key);
        }
    }

    /**
     * Small set of attributes that does conversion of requests
     * for attributes of type StyleConstants.
     */
    class SmallConversionSet extends SmallAttributeSet {

        /**
         * Creates a new attribute set based on a supplied set of attributes.
         *
         * @param attrs the set of attributes
         */
        public SmallConversionSet(AttributeSet attrs) {
            super(attrs);
        }

        /**
         * Checks whether a given attribute is defined.
         *
         * @param key the attribute key
         * @return true if the attribute is defined
         * @see AttributeSet#isDefined
         */
        public boolean isDefined(Object key) {
            if (key instanceof StyleConstants) {
                Object cssKey = css.styleConstantsKeyToCSSKey
                                    ((StyleConstants)key);
                if (cssKey != null) {
                    return super.isDefined(cssKey);
                }
            }
            return super.isDefined(key);
        }

        /**
         * Gets the value of an attribute.
         *
         * @param key the attribute name
         * @return the attribute value
         * @see AttributeSet#getAttribute
         */
        public Object getAttribute(Object key) {
            if (key instanceof StyleConstants) {
                Object cssKey = css.styleConstantsKeyToCSSKey
                                    ((StyleConstants)key);
                if (cssKey != null) {
                    Object value = super.getAttribute(cssKey);
                    if (value != null) {
                        return css.cssValueToStyleConstantsValue
                                           ((StyleConstants)key, value);
                    }
                }
            }
            return super.getAttribute(key);
        }
    }

    // ---- Resource handling ----------------------------------------

    /**
     * Fetches the font to use for the given set of attributes.
     */
    public Font getFont(AttributeSet a) {
        return css.getFont(this, a, 12, this);
    }

    /**
     * Takes a set of attributes and turn it into a foreground color
     * specification.  This might be used to specify things
     * like brighter, more hue, etc.
     *
     * @param a the set of attributes
     * @return the color
     */
    public Color getForeground(AttributeSet a) {
        Color c = css.getColor(a, CSS.Attribute.COLOR);
        if (c == null) {
            return Color.black;
        }
        return c;
    }

    /**
     * Takes a set of attributes and turn it into a background color
     * specification.  This might be used to specify things
     * like brighter, more hue, etc.
     *
     * @param a the set of attributes
     * @return the color
     */
    public Color getBackground(AttributeSet a) {
        return css.getColor(a, CSS.Attribute.BACKGROUND_COLOR);
    }

    /**
     * Fetches the box formatter to use for the given set
     * of CSS attributes.
     */
    public BoxPainter getBoxPainter(AttributeSet a) {
        return new BoxPainter(a, css, this);
    }

    /**
     * Fetches the list formatter to use for the given set
     * of CSS attributes.
     */
    public ListPainter getListPainter(AttributeSet a) {
        return new ListPainter(a, this);
    }

    /**
     * Sets the base font size, with valid values between 1 and 7.
     */
    public void setBaseFontSize(int sz) {
        css.setBaseFontSize(sz);
    }

    /**
     * Sets the base font size from the passed in String. The string
     * can either identify a specific font size, with legal values between
     * 1 and 7, or identifiy a relative font size such as +1 or -2.
     */
    public void setBaseFontSize(String size) {
        css.setBaseFontSize(size);
    }

    public static int getIndexOfSize(float pt) {
        return CSS.getIndexOfSize(pt, sizeMapDefault);
    }

    /**
     * Returns the point size, given a size index.
     */
    public float getPointSize(int index) {
        return css.getPointSize(index, this);
    }

    /**
     *  Given a string such as "+2", "-2", or "2",
     *  returns a point size value.
     */
    public float getPointSize(String size) {
        return css.getPointSize(size, this);
    }

    /**
     * Converts a color string such as "RED" or "#NNNNNN" to a Color.
     * Note: This will only convert the HTML3.2 color strings
     *       or a string of length 7;
     *       otherwise, it will return null.
     */
    public Color stringToColor(String string) {
        return CSS.stringToColor(string);
    }

    /**
     * Returns the ImageIcon to draw in the background for
     * <code>attr</code>.
     */
    ImageIcon getBackgroundImage(AttributeSet attr) {
        Object value = attr.getAttribute(CSS.Attribute.BACKGROUND_IMAGE);

        if (value != null) {
            return ((CSS.BackgroundImage)value).getImage(getBase());
        }
        return null;
    }

    /**
     * Adds a rule into the StyleSheet.
     *
     * @param selector the selector to use for the rule.
     *  This will be a set of simple selectors, and must
     *  be a length of 1 or greater.
     * @param declaration the set of CSS attributes that
     *  make up the rule.
     */
    void addRule(String[] selector, AttributeSet declaration,
                 boolean isLinked) {
        int n = selector.length;
        StringBuffer sb = new StringBuffer();
        sb.append(selector[0]);
        for (int counter = 1; counter < n; counter++) {
            sb.append(' ');
            sb.append(selector[counter]);
        }
        String selectorName = sb.toString();
        Style rule = getStyle(selectorName);
        if (rule == null) {
            // Notice how the rule is first created, and it not part of
            // the synchronized block. It is done like this as creating
            // a new rule will fire a ChangeEvent. We do not want to be
            // holding the lock when calling to other objects, it can
            // result in deadlock.
            Style altRule = addStyle(selectorName, null);
            synchronized(this) {
                SelectorMapping mapping = getRootSelectorMapping();
                for (int i = n - 1; i >= 0; i--) {
                    mapping = mapping.getChildSelectorMapping
                                      (selector[i], true);
                }
                rule = mapping.getStyle();
                if (rule == null) {
                    rule = altRule;
                    mapping.setStyle(rule);
                    refreshResolvedRules(selectorName, selector, rule,
                                         mapping.getSpecificity());
                }
            }
        }
        if (isLinked) {
            rule = getLinkedStyle(rule);
        }
        rule.addAttributes(declaration);
    }

    //
    // The following gaggle of methods is used in maintaing the rules from
    // the sheet.
    //

    /**
     * Updates the attributes of the rules to reference any related
     * rules in <code>ss</code>.
     */
    private synchronized void linkStyleSheetAt(StyleSheet ss, int index) {
        if (resolvedStyles.size() > 0) {
            Enumeration<ResolvedStyle> values = resolvedStyles.elements();
            while (values.hasMoreElements()) {
                ResolvedStyle rule = values.nextElement();
                rule.insertExtendedStyleAt(ss.getRule(rule.getName()),
                                           index);
            }
        }
    }

    /**
     * Removes references to the rules in <code>ss</code>.
     * <code>index</code> gives the index the StyleSheet was at, that is
     * how many StyleSheets had been added before it.
     */
    private synchronized void unlinkStyleSheet(StyleSheet ss, int index) {
        if (resolvedStyles.size() > 0) {
            Enumeration<ResolvedStyle> values = resolvedStyles.elements();
            while (values.hasMoreElements()) {
                ResolvedStyle rule = values.nextElement();
                rule.removeExtendedStyleAt(index);
            }
        }
    }

    /**
     * Returns the simple selectors that comprise selector.
     */
    /* protected */
    String[] getSimpleSelectors(String selector) {
        selector = cleanSelectorString(selector);
        SearchBuffer sb = SearchBuffer.obtainSearchBuffer();
        Vector<String> selectors = sb.getVector();
        int lastIndex = 0;
        int length = selector.length();
        while (lastIndex != -1) {
            int newIndex = selector.indexOf(' ', lastIndex);
            if (newIndex != -1) {
                selectors.addElement(selector.substring(lastIndex, newIndex));
                if (++newIndex == length) {
                    lastIndex = -1;
                }
                else {
                    lastIndex = newIndex;
                }
            }
            else {
                selectors.addElement(selector.substring(lastIndex));
                lastIndex = -1;
            }
        }
        String[] retValue = new String[selectors.size()];
        selectors.copyInto(retValue);
        SearchBuffer.releaseSearchBuffer(sb);
        return retValue;
    }

    /**
     * Returns a string that only has one space between simple selectors,
     * which may be the passed in String.
     */
    /*protected*/ String cleanSelectorString(String selector) {
        boolean lastWasSpace = true;
        for (int counter = 0, maxCounter = selector.length();
             counter < maxCounter; counter++) {
            switch(selector.charAt(counter)) {
            case ' ':
                if (lastWasSpace) {
                    return _cleanSelectorString(selector);
                }
                lastWasSpace = true;
                break;
            case '\n':
            case '\r':
            case '\t':
                return _cleanSelectorString(selector);
            default:
                lastWasSpace = false;
            }
        }
        if (lastWasSpace) {
            return _cleanSelectorString(selector);
        }
        // It was fine.
        return selector;
    }

    /**
     * Returns a new String that contains only one space between non
     * white space characters.
     */
    private String _cleanSelectorString(String selector) {
        SearchBuffer sb = SearchBuffer.obtainSearchBuffer();
        StringBuffer buff = sb.getStringBuffer();
        boolean lastWasSpace = true;
        int lastIndex = 0;
        char[] chars = selector.toCharArray();
        int numChars = chars.length;
        String retValue = null;
        try {
            for (int counter = 0; counter < numChars; counter++) {
                switch(chars[counter]) {
                case ' ':
                    if (!lastWasSpace) {
                        lastWasSpace = true;
                        if (lastIndex < counter) {
                            buff.append(chars, lastIndex,
                                        1 + counter - lastIndex);
                        }
                    }
                    lastIndex = counter + 1;
                    break;
                case '\n':
                case '\r':
                case '\t':
                    if (!lastWasSpace) {
                        lastWasSpace = true;
                        if (lastIndex < counter) {
                            buff.append(chars, lastIndex,
                                        counter - lastIndex);
                            buff.append(' ');
                        }
                    }
                    lastIndex = counter + 1;
                    break;
                default:
                    lastWasSpace = false;
                    break;
                }
            }
            if (lastWasSpace && buff.length() > 0) {
                // Remove last space.
                buff.setLength(buff.length() - 1);
            }
            else if (lastIndex < numChars) {
                buff.append(chars, lastIndex, numChars - lastIndex);
            }
            retValue = buff.toString();
        }
        finally {
            SearchBuffer.releaseSearchBuffer(sb);
        }
        return retValue;
    }

    /**
     * Returns the root selector mapping that all selectors are relative
     * to. This is an inverted graph of the selectors.
     */
    private SelectorMapping getRootSelectorMapping() {
        return selectorMapping;
    }

    /**
     * Returns the specificity of the passed in String. It assumes the
     * passed in string doesn't contain junk, that is each selector is
     * separated by a space and each selector at most contains one . or one
     * #. A simple selector has a weight of 1, an id selector has a weight
     * of 100, and a class selector has a weight of 10000.
     */
    /*protected*/ static int getSpecificity(String selector) {
        int specificity = 0;
        boolean lastWasSpace = true;

        for (int counter = 0, maxCounter = selector.length();
             counter < maxCounter; counter++) {
            switch(selector.charAt(counter)) {
            case '.':
                specificity += 100;
                break;
            case '#':
                specificity += 10000;
                break;
            case ' ':
                lastWasSpace = true;
                break;
            default:
                if (lastWasSpace) {
                    lastWasSpace = false;
                    specificity += 1;
                }
            }
        }
        return specificity;
    }

    /**
     * Returns the style that linked attributes should be added to. This
     * will create the style if necessary.
     */
    private Style getLinkedStyle(Style localStyle) {
        // NOTE: This is not synchronized, and the caller of this does
        // not synchronize. There is the chance for one of the callers to
        // overwrite the existing resolved parent, but it is quite rare.
        // The reason this is left like this is because setResolveParent
        // will fire a ChangeEvent. It is really, REALLY bad for us to
        // hold a lock when calling outside of us, it may cause a deadlock.
        Style retStyle = (Style)localStyle.getResolveParent();
        if (retStyle == null) {
            retStyle = addStyle(null, null);
            localStyle.setResolveParent(retStyle);
        }
        return retStyle;
    }

    /**
     * Returns the resolved style for <code>selector</code>. This will
     * create the resolved style, if necessary.
     */
    private synchronized Style getResolvedStyle(String selector,
                                                Vector elements,
                                                HTML.Tag t) {
        Style retStyle = resolvedStyles.get(selector);
        if (retStyle == null) {
            retStyle = createResolvedStyle(selector, elements, t);
        }
        return retStyle;
    }

    /**
     * Returns the resolved style for <code>selector</code>. This will
     * create the resolved style, if necessary.
     */
    private synchronized Style getResolvedStyle(String selector) {
        Style retStyle = resolvedStyles.get(selector);
        if (retStyle == null) {
            retStyle = createResolvedStyle(selector);
        }
        return retStyle;
    }

    /**
     * Adds <code>mapping</code> to <code>elements</code>. It is added
     * such that <code>elements</code> will remain ordered by
     * specificity.
     */
    private void addSortedStyle(SelectorMapping mapping, Vector<SelectorMapping> elements) {
        int       size = elements.size();

        if (size > 0) {
            int     specificity = mapping.getSpecificity();

            for (int counter = 0; counter < size; counter++) {
                if (specificity >= elements.elementAt(counter).getSpecificity()) {
                    elements.insertElementAt(mapping, counter);
                    return;
                }
            }
        }
        elements.addElement(mapping);
    }

    /**
     * Adds <code>parentMapping</code> to <code>styles</code>, and
     * recursively calls this method if <code>parentMapping</code> has
     * any child mappings for any of the Elements in <code>elements</code>.
     */
    private synchronized void getStyles(SelectorMapping parentMapping,
                           Vector<SelectorMapping> styles,
                           String[] tags, String[] ids, String[] classes,
                           int index, int numElements,
                           Hashtable<SelectorMapping, SelectorMapping> alreadyChecked) {
        // Avoid desending the same mapping twice.
        if (alreadyChecked.contains(parentMapping)) {
            return;
        }
        alreadyChecked.put(parentMapping, parentMapping);
        Style style = parentMapping.getStyle();
        if (style != null) {
            addSortedStyle(parentMapping, styles);
        }
        for (int counter = index; counter < numElements; counter++) {
            String tagString = tags[counter];
            if (tagString != null) {
                SelectorMapping childMapping = parentMapping.
                                getChildSelectorMapping(tagString, false);
                if (childMapping != null) {
                    getStyles(childMapping, styles, tags, ids, classes,
                              counter + 1, numElements, alreadyChecked);
                }
                if (classes[counter] != null) {
                    String className = classes[counter];
                    childMapping = parentMapping.getChildSelectorMapping(
                                         tagString + "." + className, false);
                    if (childMapping != null) {
                        getStyles(childMapping, styles, tags, ids, classes,
                                  counter + 1, numElements, alreadyChecked);
                    }
                    childMapping = parentMapping.getChildSelectorMapping(
                                         "." + className, false);
                    if (childMapping != null) {
                        getStyles(childMapping, styles, tags, ids, classes,
                                  counter + 1, numElements, alreadyChecked);
                    }
                }
                if (ids[counter] != null) {
                    String idName = ids[counter];
                    childMapping = parentMapping.getChildSelectorMapping(
                                         tagString + "#" + idName, false);
                    if (childMapping != null) {
                        getStyles(childMapping, styles, tags, ids, classes,
                                  counter + 1, numElements, alreadyChecked);
                    }
                    childMapping = parentMapping.getChildSelectorMapping(
                                   "#" + idName, false);
                    if (childMapping != null) {
                        getStyles(childMapping, styles, tags, ids, classes,
                                  counter + 1, numElements, alreadyChecked);
                    }
                }
            }
        }
    }

    /**
     * Creates and returns a Style containing all the rules that match
     *  <code>selector</code>.
     */
    private synchronized Style createResolvedStyle(String selector,
                                      String[] tags,
                                      String[] ids, String[] classes) {
        SearchBuffer sb = SearchBuffer.obtainSearchBuffer();
        Vector<SelectorMapping> tempVector = sb.getVector();
        Hashtable<SelectorMapping, SelectorMapping> tempHashtable = sb.getHashtable();
        // Determine all the Styles that are appropriate, placing them
        // in tempVector
        try {
            SelectorMapping mapping = getRootSelectorMapping();
            int numElements = tags.length;
            String tagString = tags[0];
            SelectorMapping childMapping = mapping.getChildSelectorMapping(
                                                   tagString, false);
            if (childMapping != null) {
                getStyles(childMapping, tempVector, tags, ids, classes, 1,
                          numElements, tempHashtable);
            }
            if (classes[0] != null) {
                String className = classes[0];
                childMapping = mapping.getChildSelectorMapping(
                                       tagString + "." + className, false);
                if (childMapping != null) {
                    getStyles(childMapping, tempVector, tags, ids, classes, 1,
                              numElements, tempHashtable);
                }
                childMapping = mapping.getChildSelectorMapping(
                                       "." + className, false);
                if (childMapping != null) {
                    getStyles(childMapping, tempVector, tags, ids, classes,
                              1, numElements, tempHashtable);
                }
            }
            if (ids[0] != null) {
                String idName = ids[0];
                childMapping = mapping.getChildSelectorMapping(
                                       tagString + "#" + idName, false);
                if (childMapping != null) {
                    getStyles(childMapping, tempVector, tags, ids, classes,
                              1, numElements, tempHashtable);
                }
                childMapping = mapping.getChildSelectorMapping(
                                       "#" + idName, false);
                if (childMapping != null) {
                    getStyles(childMapping, tempVector, tags, ids, classes,
                              1, numElements, tempHashtable);
                }
            }
            // Create a new Style that will delegate to all the matching
            // Styles.
            int numLinkedSS = (linkedStyleSheets != null) ?
                              linkedStyleSheets.size() : 0;
            int numStyles = tempVector.size();
            AttributeSet[] attrs = new AttributeSet[numStyles + numLinkedSS];
            for (int counter = 0; counter < numStyles; counter++) {
                attrs[counter] = tempVector.elementAt(counter).getStyle();
            }
            // Get the AttributeSet from linked style sheets.
            for (int counter = 0; counter < numLinkedSS; counter++) {
                AttributeSet attr = linkedStyleSheets.elementAt(counter).getRule(selector);
                if (attr == null) {
                    attrs[counter + numStyles] = SimpleAttributeSet.EMPTY;
                }
                else {
                    attrs[counter + numStyles] = attr;
                }
            }
            ResolvedStyle retStyle = new ResolvedStyle(selector, attrs,
                                                       numStyles);
            resolvedStyles.put(selector, retStyle);
            return retStyle;
        }
        finally {
            SearchBuffer.releaseSearchBuffer(sb);
        }
    }

    /**
     * Creates and returns a Style containing all the rules that
     * matches <code>selector</code>.
     *
     * @param elements  a Vector of all the Elements
     *                  the style is being asked for. The
     *                  first Element is the deepest Element, with the last Element
     *                  representing the root.
     * @param t         the Tag to use for
     *                  the first Element in <code>elements</code>
     */
    private Style createResolvedStyle(String selector, Vector elements,
                                      HTML.Tag t) {
        int numElements = elements.size();
        // Build three arrays, one for tags, one for class's, and one for
        // id's
        String tags[] = new String[numElements];
        String ids[] = new String[numElements];
        String classes[] = new String[numElements];
        for (int counter = 0; counter < numElements; counter++) {
            Element e = (Element)elements.elementAt(counter);
            AttributeSet attr = e.getAttributes();
            if (counter == 0 && e.isLeaf()) {
                // For leafs, we use the second tier attributes.
                Object testAttr = attr.getAttribute(t);
                if (testAttr instanceof AttributeSet) {
                    attr = (AttributeSet)testAttr;
                }
                else {
                    attr = null;
                }
            }
            if (attr != null) {
                HTML.Tag tag = (HTML.Tag)attr.getAttribute(StyleConstants.
                                                           NameAttribute);
                if (tag != null) {
                    tags[counter] = tag.toString();
                }
                else {
                    tags[counter] = null;
                }
                if (attr.isDefined(HTML.Attribute.CLASS)) {
                    classes[counter] = attr.getAttribute
                                      (HTML.Attribute.CLASS).toString();
                }
                else {
                    classes[counter] = null;
                }
                if (attr.isDefined(HTML.Attribute.ID)) {
                    ids[counter] = attr.getAttribute(HTML.Attribute.ID).
                                        toString();
                }
                else {
                    ids[counter] = null;
                }
            }
            else {
                tags[counter] = ids[counter] = classes[counter] = null;
            }
        }
        tags[0] = t.toString();
        return createResolvedStyle(selector, tags, ids, classes);
    }

    /**
     * Creates and returns a Style containing all the rules that match
     *  <code>selector</code>. It is assumed that each simple selector
     * in <code>selector</code> is separated by a space.
     */
    private Style createResolvedStyle(String selector) {
        SearchBuffer sb = SearchBuffer.obtainSearchBuffer();
        // Will contain the tags, ids, and classes, in that order.
        Vector<String> elements = sb.getVector();
        try {
            boolean done;
            int dotIndex = 0;
            int spaceIndex;
            int poundIndex = 0;
            int lastIndex = 0;
            int length = selector.length();
            while (lastIndex < length) {
                if (dotIndex == lastIndex) {
                    dotIndex = selector.indexOf('.', lastIndex);
                }
                if (poundIndex == lastIndex) {
                    poundIndex = selector.indexOf('#', lastIndex);
                }
                spaceIndex = selector.indexOf(' ', lastIndex);
                if (spaceIndex == -1) {
                    spaceIndex = length;
                }
                if (dotIndex != -1 && poundIndex != -1 &&
                    dotIndex < spaceIndex && poundIndex < spaceIndex) {
                    if (poundIndex < dotIndex) {
                        // #.
                        if (lastIndex == poundIndex) {
                            elements.addElement("");
                        }
                        else {
                            elements.addElement(selector.substring(lastIndex,
                                                                  poundIndex));
                        }
                        if ((dotIndex + 1) < spaceIndex) {
                            elements.addElement(selector.substring
                                                (dotIndex + 1, spaceIndex));
                        }
                        else {
                            elements.addElement(null);
                        }
                        if ((poundIndex + 1) == dotIndex) {
                            elements.addElement(null);
                        }
                        else {
                            elements.addElement(selector.substring
                                                (poundIndex + 1, dotIndex));
                        }
                    }
                    else if(poundIndex < spaceIndex) {
                        // .#
                        if (lastIndex == dotIndex) {
                            elements.addElement("");
                        }
                        else {
                            elements.addElement(selector.substring(lastIndex,
                                                                  dotIndex));
                        }
                        if ((dotIndex + 1) < poundIndex) {
                            elements.addElement(selector.substring
                                                (dotIndex + 1, poundIndex));
                        }
                        else {
                            elements.addElement(null);
                        }
                        if ((poundIndex + 1) == spaceIndex) {
                            elements.addElement(null);
                        }
                        else {
                            elements.addElement(selector.substring
                                                (poundIndex + 1, spaceIndex));
                        }
                    }
                    dotIndex = poundIndex = spaceIndex + 1;
                }
                else if (dotIndex != -1 && dotIndex < spaceIndex) {
                    // .
                    if (dotIndex == lastIndex) {
                        elements.addElement("");
                    }
                    else {
                        elements.addElement(selector.substring(lastIndex,
                                                               dotIndex));
                    }
                    if ((dotIndex + 1) == spaceIndex) {
                        elements.addElement(null);
                    }
                    else {
                        elements.addElement(selector.substring(dotIndex + 1,
                                                               spaceIndex));
                    }
                    elements.addElement(null);
                    dotIndex = spaceIndex + 1;
                }
                else if (poundIndex != -1 && poundIndex < spaceIndex) {
                    // #
                    if (poundIndex == lastIndex) {
                        elements.addElement("");
                    }
                    else {
                        elements.addElement(selector.substring(lastIndex,
                                                               poundIndex));
                    }
                    elements.addElement(null);
                    if ((poundIndex + 1) == spaceIndex) {
                        elements.addElement(null);
                    }
                    else {
                        elements.addElement(selector.substring(poundIndex + 1,
                                                               spaceIndex));
                    }
                    poundIndex = spaceIndex + 1;
                }
                else {
                    // id
                    elements.addElement(selector.substring(lastIndex,
                                                           spaceIndex));
                    elements.addElement(null);
                    elements.addElement(null);
                }
                lastIndex = spaceIndex + 1;
            }
            // Create the tag, id, and class arrays.
            int total = elements.size();
            int numTags = total / 3;
            String[] tags = new String[numTags];
            String[] ids = new String[numTags];
            String[] classes = new String[numTags];
            for (int index = 0, eIndex = total - 3; index < numTags;
                 index++, eIndex -= 3) {
                tags[index] = elements.elementAt(eIndex);
                classes[index] = elements.elementAt(eIndex + 1);
                ids[index] = elements.elementAt(eIndex + 2);
            }
            return createResolvedStyle(selector, tags, ids, classes);
        }
        finally {
            SearchBuffer.releaseSearchBuffer(sb);
        }
    }

    /**
     * Should be invoked when a new rule is added that did not previously
     * exist. Goes through and refreshes the necessary resolved
     * rules.
     */
    private synchronized void refreshResolvedRules(String selectorName,
                                                   String[] selector,
                                                   Style newStyle,
                                                   int specificity) {
        if (resolvedStyles.size() > 0) {
            Enumeration<ResolvedStyle> values = resolvedStyles.elements();
            while (values.hasMoreElements()) {
                ResolvedStyle style = values.nextElement();
                if (style.matches(selectorName)) {
                    style.insertStyle(newStyle, specificity);
                }
            }
        }
    }


    /**
     * A temporary class used to hold a Vector, a StringBuffer and a
     * Hashtable. This is used to avoid allocing a lot of garbage when
     * searching for rules. Use the static method obtainSearchBuffer and
     * releaseSearchBuffer to get a SearchBuffer, and release it when
     * done.
     */
    private static class SearchBuffer {
        /** A stack containing instances of SearchBuffer. Used in getting
         * rules. */
        static Stack<SearchBuffer> searchBuffers = new Stack<SearchBuffer>();
        // A set of temporary variables that can be used in whatever way.
        Vector vector = null;
        StringBuffer stringBuffer = null;
        Hashtable hashtable = null;

        /**
         * Returns an instance of SearchBuffer. Be sure and issue
         * a releaseSearchBuffer when done with it.
         */
        static SearchBuffer obtainSearchBuffer() {
            SearchBuffer sb;
            try {
                if(!searchBuffers.empty()) {
                   sb = searchBuffers.pop();
                } else {
                   sb = new SearchBuffer();
                }
            } catch (EmptyStackException ese) {
                sb = new SearchBuffer();
            }
            return sb;
        }

        /**
         * Adds <code>sb</code> to the stack of SearchBuffers that can
         * be used.
         */
        static void releaseSearchBuffer(SearchBuffer sb) {
            sb.empty();
            searchBuffers.push(sb);
        }

        StringBuffer getStringBuffer() {
            if (stringBuffer == null) {
                stringBuffer = new StringBuffer();
            }
            return stringBuffer;
        }

        Vector getVector() {
            if (vector == null) {
                vector = new Vector();
            }
            return vector;
        }

        Hashtable getHashtable() {
            if (hashtable == null) {
                hashtable = new Hashtable();
            }
            return hashtable;
        }

        void empty() {
            if (stringBuffer != null) {
                stringBuffer.setLength(0);
            }
            if (vector != null) {
                vector.removeAllElements();
            }
            if (hashtable != null) {
                hashtable.clear();
            }
        }
    }


    static final Border noBorder = new EmptyBorder(0,0,0,0);

    /**
     * Class to carry out some of the duties of
     * CSS formatting.  Implementations of this
     * class enable views to present the CSS formatting
     * while not knowing anything about how the CSS values
     * are being cached.
     * <p>
     * As a delegate of Views, this object is responsible for
     * the insets of a View and making sure the background
     * is maintained according to the CSS attributes.
     */
    public static class BoxPainter implements Serializable {

        BoxPainter(AttributeSet a, CSS css, StyleSheet ss) {
            this.ss = ss;
            this.css = css;
            border = getBorder(a);
            binsets = border.getBorderInsets(null);
            topMargin = getLength(CSS.Attribute.MARGIN_TOP, a);
            bottomMargin = getLength(CSS.Attribute.MARGIN_BOTTOM, a);
            leftMargin = getLength(CSS.Attribute.MARGIN_LEFT, a);
            rightMargin = getLength(CSS.Attribute.MARGIN_RIGHT, a);
            bg = ss.getBackground(a);
            if (ss.getBackgroundImage(a) != null) {
                bgPainter = new BackgroundImagePainter(a, css, ss);
            }
        }

        /**
         * Fetches a border to render for the given attributes.
         * PENDING(prinz) This is pretty badly hacked at the
         * moment.
         */
        Border getBorder(AttributeSet a) {
            return new CSSBorder(a);
        }

        /**
         * Fetches the color to use for borders.  This will either be
         * the value specified by the border-color attribute (which
         * is not inherited), or it will default to the color attribute
         * (which is inherited).
         */
        Color getBorderColor(AttributeSet a) {
            Color color = css.getColor(a, CSS.Attribute.BORDER_COLOR);
            if (color == null) {
                color = css.getColor(a, CSS.Attribute.COLOR);
                if (color == null) {
                    return Color.black;
                }
            }
            return color;
        }

        /**
         * Fetches the inset needed on a given side to
         * account for the margin, border, and padding.
         *
         * @param side The size of the box to fetch the
         *  inset for.  This can be View.TOP,
         *  View.LEFT, View.BOTTOM, or View.RIGHT.
         * @param v the view making the request.  This is
         *  used to get the AttributeSet, and may be used to
         *  resolve percentage arguments.
         * @exception IllegalArgumentException for an invalid direction
         */
        public float getInset(int side, View v) {
            AttributeSet a = v.getAttributes();
            float inset = 0;
            switch(side) {
            case View.LEFT:
                inset += getOrientationMargin(HorizontalMargin.LEFT,
                                              leftMargin, a, isLeftToRight(v));
                inset += binsets.left;
                inset += getLength(CSS.Attribute.PADDING_LEFT, a);
                break;
            case View.RIGHT:
                inset += getOrientationMargin(HorizontalMargin.RIGHT,
                                              rightMargin, a, isLeftToRight(v));
                inset += binsets.right;
                inset += getLength(CSS.Attribute.PADDING_RIGHT, a);
                break;
            case View.TOP:
                inset += topMargin;
                inset += binsets.top;
                inset += getLength(CSS.Attribute.PADDING_TOP, a);
                break;
            case View.BOTTOM:
                inset += bottomMargin;
                inset += binsets.bottom;
                inset += getLength(CSS.Attribute.PADDING_BOTTOM, a);
                break;
            default:
                throw new IllegalArgumentException("Invalid side: " + side);
            }
            return inset;
        }

        /**
         * Paints the CSS box according to the attributes
         * given.  This should paint the border, padding,
         * and background.
         *
         * @param g the rendering surface.
         * @param x the x coordinate of the allocated area to
         *  render into.
         * @param y the y coordinate of the allocated area to
         *  render into.
         * @param w the width of the allocated area to render into.
         * @param h the height of the allocated area to render into.
         * @param v the view making the request.  This is
         *  used to get the AttributeSet, and may be used to
         *  resolve percentage arguments.
         */
        public void paint(Graphics g, float x, float y, float w, float h, View v) {
            // PENDING(prinz) implement real rendering... which would
            // do full set of border and background capabilities.
            // remove margin

            float dx = 0;
            float dy = 0;
            float dw = 0;
            float dh = 0;
            AttributeSet a = v.getAttributes();
            boolean isLeftToRight = isLeftToRight(v);
            float localLeftMargin = getOrientationMargin(HorizontalMargin.LEFT,
                                                         leftMargin,
                                                         a, isLeftToRight);
            float localRightMargin = getOrientationMargin(HorizontalMargin.RIGHT,
                                                          rightMargin,
                                                          a, isLeftToRight);
            if (!(v instanceof HTMLEditorKit.HTMLFactory.BodyBlockView)) {
                dx = localLeftMargin;
                dy = topMargin;
                dw = -(localLeftMargin + localRightMargin);
                dh = -(topMargin + bottomMargin);
            }
            if (bg != null) {
                g.setColor(bg);
                g.fillRect((int) (x + dx),
                           (int) (y + dy),
                           (int) (w + dw),
                           (int) (h + dh));
            }
            if (bgPainter != null) {
                bgPainter.paint(g, x + dx, y + dy, w + dw, h + dh, v);
            }
            x += localLeftMargin;
            y += topMargin;
            w -= localLeftMargin + localRightMargin;
            h -= topMargin + bottomMargin;
            if (border instanceof BevelBorder) {
                //BevelBorder does not support border width
                int bw = (int) getLength(CSS.Attribute.BORDER_TOP_WIDTH, a);
                for (int i = bw - 1; i >= 0; i--) {
                    border.paintBorder(null, g, (int) x + i, (int) y + i,
                                       (int) w - 2 * i, (int) h - 2 * i);
                }
            } else {
                border.paintBorder(null, g, (int) x, (int) y, (int) w, (int) h);
            }
        }

        float getLength(CSS.Attribute key, AttributeSet a) {
            return css.getLength(a, key, ss);
        }

        static boolean isLeftToRight(View v) {
            boolean ret = true;
            if (isOrientationAware(v)) {
                Container container;
                if (v != null && (container = v.getContainer()) != null) {
                    ret = container.getComponentOrientation().isLeftToRight();
                }
            }
            return ret;
        }

        /*
         * only certain tags are concerned about orientation
         * <dir>, <menu>, <ul>, <ol>
         * for all others we return true. It is implemented this way
         * for performance purposes
         */
        static boolean isOrientationAware(View v) {
            boolean ret = false;
            AttributeSet attr;
            Object obj;
            if (v != null
                && (attr = v.getElement().getAttributes()) != null
                && (obj = attr.getAttribute(StyleConstants.NameAttribute)) instanceof HTML.Tag
                && (obj == HTML.Tag.DIR
                    || obj == HTML.Tag.MENU
                    || obj == HTML.Tag.UL
                    || obj == HTML.Tag.OL)) {
                ret = true;
            }

            return ret;
        }

        static enum HorizontalMargin { LEFT, RIGHT }

        /**
         * for <dir>, <menu>, <ul> etc.
         * margins are Left-To-Right/Right-To-Left depended.
         * see 5088268 for more details
         * margin-(left|right)-(ltr|rtl) were introduced to describe it
         * if margin-(left|right) is present we are to use it.
         *
         * @param side The horizontal side to fetch margin for
         *  This can be HorizontalMargin.LEFT or HorizontalMargin.RIGHT
         * @param cssMargin margin from css
         * @param a AttributeSet for the View we getting margin for
         * @param isLeftToRight
         * @return orientation depended margin
         */
        float getOrientationMargin(HorizontalMargin side, float cssMargin,
                                   AttributeSet a, boolean isLeftToRight) {
            float margin = cssMargin;
            float orientationMargin = cssMargin;
            Object cssMarginValue = null;
            switch (side) {
            case RIGHT:
                {
                    orientationMargin = (isLeftToRight) ?
                        getLength(CSS.Attribute.MARGIN_RIGHT_LTR, a) :
                        getLength(CSS.Attribute.MARGIN_RIGHT_RTL, a);
                    cssMarginValue = a.getAttribute(CSS.Attribute.MARGIN_RIGHT);
                }
                break;
            case LEFT :
                {
                    orientationMargin = (isLeftToRight) ?
                        getLength(CSS.Attribute.MARGIN_LEFT_LTR, a) :
                        getLength(CSS.Attribute.MARGIN_LEFT_RTL, a);
                    cssMarginValue = a.getAttribute(CSS.Attribute.MARGIN_LEFT);
                }
                break;
            }

            if (cssMarginValue == null
                && orientationMargin != Integer.MIN_VALUE) {
                margin = orientationMargin;
            }
            return margin;
        }

        float topMargin;
        float bottomMargin;
        float leftMargin;
        float rightMargin;
        // Bitmask, used to indicate what margins are relative:
        // bit 0 for top, 1 for bottom, 2 for left and 3 for right.
        short marginFlags;
        Border border;
        Insets binsets;
        CSS css;
        StyleSheet ss;
        Color bg;
        BackgroundImagePainter bgPainter;
    }

    /**
     * Class to carry out some of the duties of CSS list
     * formatting.  Implementations of this
     * class enable views to present the CSS formatting
     * while not knowing anything about how the CSS values
     * are being cached.
     */
    public static class ListPainter implements Serializable {

        ListPainter(AttributeSet attr, StyleSheet ss) {
            this.ss = ss;
            /* Get the image to use as a list bullet */
            String imgstr = (String)attr.getAttribute(CSS.Attribute.
                                                      LIST_STYLE_IMAGE);
            type = null;
            if (imgstr != null && !imgstr.equals("none")) {
                String tmpstr = null;
                try {
                    StringTokenizer st = new StringTokenizer(imgstr, "()");
                    if (st.hasMoreTokens())
                        tmpstr = st.nextToken();
                    if (st.hasMoreTokens())
                        tmpstr = st.nextToken();
                    URL u = new URL(tmpstr);
                    img = new ImageIcon(u);
                } catch (MalformedURLException e) {
                    if (tmpstr != null && ss != null && ss.getBase() != null) {
                        try {
                            URL u = new URL(ss.getBase(), tmpstr);
                            img = new ImageIcon(u);
                        } catch (MalformedURLException murle) {
                            img = null;
                        }
                    }
                    else {
                        img = null;
                    }
                }
            }

            /* Get the type of bullet to use in the list */
            if (img == null) {
                type = (CSS.Value)attr.getAttribute(CSS.Attribute.
                                                    LIST_STYLE_TYPE);
            }
            start = 1;

            paintRect = new Rectangle();
        }

        /**
         * Returns a string that represents the value
         * of the HTML.Attribute.TYPE attribute.
         * If this attributes is not defined, then
         * then the type defaults to "disc" unless
         * the tag is on Ordered list.  In the case
         * of the latter, the default type is "decimal".
         */
        private CSS.Value getChildType(View childView) {
            CSS.Value childtype = (CSS.Value)childView.getAttributes().
                                  getAttribute(CSS.Attribute.LIST_STYLE_TYPE);

            if (childtype == null) {
                if (type == null) {
                    // Parent view.
                    View v = childView.getParent();
                    HTMLDocument doc = (HTMLDocument)v.getDocument();
                    if (doc.matchNameAttribute(v.getElement().getAttributes(),
                                               HTML.Tag.OL)) {
                        childtype = CSS.Value.DECIMAL;
                    } else {
                        childtype = CSS.Value.DISC;
                    }
                } else {
                    childtype = type;
                }
            }
            return childtype;
        }

        /**
         * Obtains the starting index from <code>parent</code>.
         */
        private void getStart(View parent) {
            checkedForStart = true;
            Element element = parent.getElement();
            if (element != null) {
                AttributeSet attr = element.getAttributes();
                Object startValue;
                if (attr != null && attr.isDefined(HTML.Attribute.START) &&
                    (startValue = attr.getAttribute
                     (HTML.Attribute.START)) != null &&
                    (startValue instanceof String)) {

                    try {
                        start = Integer.parseInt((String)startValue);
                    }
                    catch (NumberFormatException nfe) {}
                }
            }
        }

        /**
         * Returns an integer that should be used to render the child at
         * <code>childIndex</code> with. The retValue will usually be
         * <code>childIndex</code> + 1, unless <code>parentView</code>
         * has some Views that do not represent LI's, or one of the views
         * has a HTML.Attribute.START specified.
         */
        private int getRenderIndex(View parentView, int childIndex) {
            if (!checkedForStart) {
                getStart(parentView);
            }
            int retIndex = childIndex;
            for (int counter = childIndex; counter >= 0; counter--) {
                AttributeSet as = parentView.getElement().getElement(counter).
                                  getAttributes();
                if (as.getAttribute(StyleConstants.NameAttribute) !=
                    HTML.Tag.LI) {
                    retIndex--;
                } else if (as.isDefined(HTML.Attribute.VALUE)) {
                    Object value = as.getAttribute(HTML.Attribute.VALUE);
                    if (value != null &&
                        (value instanceof String)) {
                        try {
                            int iValue = Integer.parseInt((String)value);
                            return retIndex - counter + iValue;
                        }
                        catch (NumberFormatException nfe) {}
                    }
                }
            }
            return retIndex + start;
        }

        /**
         * Paints the CSS list decoration according to the
         * attributes given.
         *
         * @param g the rendering surface.
         * @param x the x coordinate of the list item allocation
         * @param y the y coordinate of the list item allocation
         * @param w the width of the list item allocation
         * @param h the height of the list item allocation
         * @param v the allocated area to paint into.
         * @param item which list item is being painted.  This
         *  is a number greater than or equal to 0.
         */
        public void paint(Graphics g, float x, float y, float w, float h, View v, int item) {
            View cv = v.getView(item);
            Container host = v.getContainer();
            Object name = cv.getElement().getAttributes().getAttribute
                         (StyleConstants.NameAttribute);
            // Only draw something if the View is a list item. This won't
            // be the case for comments.
            if (!(name instanceof HTML.Tag) ||
                name != HTML.Tag.LI) {
                return;
            }
            // deside on what side draw bullets, etc.
            isLeftToRight =
                host.getComponentOrientation().isLeftToRight();

            // How the list indicator is aligned is not specified, it is
            // left up to the UA. IE and NS differ on this behavior.
            // This is closer to NS where we align to the first line of text.
            // If the child is not text we draw the indicator at the
            // origin (0).
            float align = 0;
            if (cv.getViewCount() > 0) {
                View pView = cv.getView(0);
                Object cName = pView.getElement().getAttributes().
                               getAttribute(StyleConstants.NameAttribute);
                if ((cName == HTML.Tag.P || cName == HTML.Tag.IMPLIED) &&
                              pView.getViewCount() > 0) {
                    paintRect.setBounds((int)x, (int)y, (int)w, (int)h);
                    Shape shape = cv.getChildAllocation(0, paintRect);
                    if (shape != null && (shape = pView.getView(0).
                                 getChildAllocation(0, shape)) != null) {
                        Rectangle rect = (shape instanceof Rectangle) ?
                                         (Rectangle)shape : shape.getBounds();

                        align = pView.getView(0).getAlignment(View.Y_AXIS);
                        y = rect.y;
                        h = rect.height;
                    }
                }
            }

            // set the color of a decoration
            Color c = (host.isEnabled()
                ? (ss != null
                    ? ss.getForeground(cv.getAttributes())
                    : host.getForeground())
                : UIManager.getColor("textInactiveText"));
            g.setColor(c);

            if (img != null) {
                drawIcon(g, (int) x, (int) y, (int) w, (int) h, align, host);
                return;
            }
            CSS.Value childtype = getChildType(cv);
            Font font = ((StyledDocument)cv.getDocument()).
                                         getFont(cv.getAttributes());
            if (font != null) {
                g.setFont(font);
            }
            if (childtype == CSS.Value.SQUARE || childtype == CSS.Value.CIRCLE
                || childtype == CSS.Value.DISC) {
                drawShape(g, childtype, (int) x, (int) y,
                          (int) w, (int) h, align);
            } else if (childtype == CSS.Value.DECIMAL) {
                drawLetter(g, '1', (int) x, (int) y, (int) w, (int) h, align,
                           getRenderIndex(v, item));
            } else if (childtype == CSS.Value.LOWER_ALPHA) {
                drawLetter(g, 'a', (int) x, (int) y, (int) w, (int) h, align,
                           getRenderIndex(v, item));
            } else if (childtype == CSS.Value.UPPER_ALPHA) {
                drawLetter(g, 'A', (int) x, (int) y, (int) w, (int) h, align,
                           getRenderIndex(v, item));
            } else if (childtype == CSS.Value.LOWER_ROMAN) {
                drawLetter(g, 'i', (int) x, (int) y, (int) w, (int) h, align,
                           getRenderIndex(v, item));
            } else if (childtype == CSS.Value.UPPER_ROMAN) {
                drawLetter(g, 'I', (int) x, (int) y, (int) w, (int) h, align,
                           getRenderIndex(v, item));
            }
        }

        /**
         * Draws the bullet icon specified by the list-style-image argument.
         *
         * @param g     the graphics context
         * @param ax    x coordinate to place the bullet
         * @param ay    y coordinate to place the bullet
         * @param aw    width of the container the bullet is placed in
         * @param ah    height of the container the bullet is placed in
         * @param align preferred alignment factor for the child view
         */
        void drawIcon(Graphics g, int ax, int ay, int aw, int ah,
                      float align, Component c) {
            // Align to bottom of icon.
            int gap = isLeftToRight ? - (img.getIconWidth() + bulletgap) :
                                        (aw + bulletgap);
            int x = ax + gap;
            int y = Math.max(ay, ay + (int)(align * ah) -img.getIconHeight());

            img.paintIcon(c, g, x, y);
        }

        /**
         * Draws the graphical bullet item specified by the type argument.
         *
         * @param g     the graphics context
         * @param type  type of bullet to draw (circle, square, disc)
         * @param ax    x coordinate to place the bullet
         * @param ay    y coordinate to place the bullet
         * @param aw    width of the container the bullet is placed in
         * @param ah    height of the container the bullet is placed in
         * @param align preferred alignment factor for the child view
         */
        void drawShape(Graphics g, CSS.Value type, int ax, int ay, int aw,
                       int ah, float align) {
            // Align to bottom of shape.
            int gap = isLeftToRight ? - (bulletgap + 8) : (aw + bulletgap);
            int x = ax + gap;
            int y = Math.max(ay, ay + (int)(align * ah) - 8);

            if (type == CSS.Value.SQUARE) {
                g.drawRect(x, y, 8, 8);
            } else if (type == CSS.Value.CIRCLE) {
                g.drawOval(x, y, 8, 8);
            } else {
                g.fillOval(x, y, 8, 8);
            }
        }

        /**
         * Draws the letter or number for an ordered list.
         *
         * @param g     the graphics context
         * @param letter type of ordered list to draw
         * @param ax    x coordinate to place the bullet
         * @param ay    y coordinate to place the bullet
         * @param aw    width of the container the bullet is placed in
         * @param ah    height of the container the bullet is placed in
         * @param index position of the list item in the list
         */
        void drawLetter(Graphics g, char letter, int ax, int ay, int aw,
                        int ah, float align, int index) {
            String str = formatItemNum(index, letter);
            str = isLeftToRight ? str + "." : "." + str;
            FontMetrics fm = SwingUtilities2.getFontMetrics(null, g);
            int stringwidth = SwingUtilities2.stringWidth(null, fm, str);
            int gap = isLeftToRight ? - (stringwidth + bulletgap) :
                                        (aw + bulletgap);
            int x = ax + gap;
            int y = Math.max(ay + fm.getAscent(), ay + (int)(ah * align));
            SwingUtilities2.drawString(null, g, str, x, y);
        }

        /**
         * Converts the item number into the ordered list number
         * (i.e.  1 2 3, i ii iii, a b c, etc.
         *
         * @param itemNum number to format
         * @param type    type of ordered list
         */
        String formatItemNum(int itemNum, char type) {
            String numStyle = "1";

            boolean uppercase = false;

            String formattedNum;

            switch (type) {
            case '1':
            default:
                formattedNum = String.valueOf(itemNum);
                break;

            case 'A':
                uppercase = true;
                // fall through
            case 'a':
                formattedNum = formatAlphaNumerals(itemNum);
                break;

            case 'I':
                uppercase = true;
                // fall through
            case 'i':
                formattedNum = formatRomanNumerals(itemNum);
            }

            if (uppercase) {
                formattedNum = formattedNum.toUpperCase();
            }

            return formattedNum;
        }

        /**
         * Converts the item number into an alphabetic character
         *
         * @param itemNum number to format
         */
        String formatAlphaNumerals(int itemNum) {
            String result;

            if (itemNum > 26) {
                result = formatAlphaNumerals(itemNum / 26) +
                    formatAlphaNumerals(itemNum % 26);
            } else {
                // -1 because item is 1 based.
                result = String.valueOf((char)('a' + itemNum - 1));
            }

            return result;
        }

        /* list of roman numerals */
        static final char romanChars[][] = {
            {'i', 'v'},
            {'x', 'l' },
            {'c', 'd' },
            {'m', '?' },
        };

        /**
         * Converts the item number into a roman numeral
         *
         * @param num  number to format
         */
        String formatRomanNumerals(int num) {
            return formatRomanNumerals(0, num);
        }

        /**
         * Converts the item number into a roman numeral
         *
         * @param num  number to format
         */
        String formatRomanNumerals(int level, int num) {
            if (num < 10) {
                return formatRomanDigit(level, num);
            } else {
                return formatRomanNumerals(level + 1, num / 10) +
                    formatRomanDigit(level, num % 10);
            }
        }


        /**
         * Converts the item number into a roman numeral
         *
         * @param level position
         * @param digit digit to format
         */
        String formatRomanDigit(int level, int digit) {
            String result = "";
            if (digit == 9) {
                result = result + romanChars[level][0];
                result = result + romanChars[level + 1][0];
                return result;
            } else if (digit == 4) {
                result = result + romanChars[level][0];
                result = result + romanChars[level][1];
                return result;
            } else if (digit >= 5) {
                result = result + romanChars[level][1];
                digit -= 5;
            }

            for (int i = 0; i < digit; i++) {
                result = result + romanChars[level][0];
            }

            return result;
        }

        private Rectangle paintRect;
        private boolean checkedForStart;
        private int start;
        private CSS.Value type;
        URL imageurl;
        private StyleSheet ss = null;
        Icon img = null;
        private int bulletgap = 5;
        private boolean isLeftToRight;
    }


    /**
     * Paints the background image.
     */
    static class BackgroundImagePainter implements Serializable {
        ImageIcon   backgroundImage;
        float       hPosition;
        float       vPosition;
        // bit mask: 0 for repeat x, 1 for repeat y, 2 for horiz relative,
        // 3 for vert relative
        short       flags;
        // These are used when painting, updatePaintCoordinates updates them.
        private int paintX;
        private int paintY;
        private int paintMaxX;
        private int paintMaxY;

        BackgroundImagePainter(AttributeSet a, CSS css, StyleSheet ss) {
            backgroundImage = ss.getBackgroundImage(a);
            // Determine the position.
            CSS.BackgroundPosition pos = (CSS.BackgroundPosition)a.getAttribute
                                           (CSS.Attribute.BACKGROUND_POSITION);
            if (pos != null) {
                hPosition = pos.getHorizontalPosition();
                vPosition = pos.getVerticalPosition();
                if (pos.isHorizontalPositionRelativeToSize()) {
                    flags |= 4;
                }
                else if (pos.isHorizontalPositionRelativeToSize()) {
                    hPosition *= css.getFontSize(a, 12, ss);
                }
                if (pos.isVerticalPositionRelativeToSize()) {
                    flags |= 8;
                }
                else if (pos.isVerticalPositionRelativeToFontSize()) {
                    vPosition *= css.getFontSize(a, 12, ss);
                }
            }
            // Determine any repeating values.
            CSS.Value repeats = (CSS.Value)a.getAttribute(CSS.Attribute.
                                                          BACKGROUND_REPEAT);
            if (repeats == null || repeats == CSS.Value.BACKGROUND_REPEAT) {
                flags |= 3;
            }
            else if (repeats == CSS.Value.BACKGROUND_REPEAT_X) {
                flags |= 1;
            }
            else if (repeats == CSS.Value.BACKGROUND_REPEAT_Y) {
                flags |= 2;
            }
        }

        void paint(Graphics g, float x, float y, float w, float h, View v) {
            Rectangle clip = g.getClipRect();
            if (clip != null) {
                // Constrain the clip so that images don't draw outside the
                // legal bounds.
                g.clipRect((int)x, (int)y, (int)w, (int)h);
            }
            if ((flags & 3) == 0) {
                // no repeating
                int width = backgroundImage.getIconWidth();
                int height = backgroundImage.getIconWidth();
                if ((flags & 4) == 4) {
                    paintX = (int)(x + w * hPosition -
                                  (float)width * hPosition);
                }
                else {
                    paintX = (int)x + (int)hPosition;
                }
                if ((flags & 8) == 8) {
                    paintY = (int)(y + h * vPosition -
                                  (float)height * vPosition);
                }
                else {
                    paintY = (int)y + (int)vPosition;
                }
                if (clip == null ||
                    !((paintX + width <= clip.x) ||
                      (paintY + height <= clip.y) ||
                      (paintX >= clip.x + clip.width) ||
                      (paintY >= clip.y + clip.height))) {
                    backgroundImage.paintIcon(null, g, paintX, paintY);
                }
            }
            else {
                int width = backgroundImage.getIconWidth();
                int height = backgroundImage.getIconHeight();
                if (width > 0 && height > 0) {
                    paintX = (int)x;
                    paintY = (int)y;
                    paintMaxX = (int)(x + w);
                    paintMaxY = (int)(y + h);
                    if (updatePaintCoordinates(clip, width, height)) {
                        while (paintX < paintMaxX) {
                            int ySpot = paintY;
                            while (ySpot < paintMaxY) {
                                backgroundImage.paintIcon(null, g, paintX,
                                                          ySpot);
                                ySpot += height;
                            }
                            paintX += width;
                        }
                    }
                }
            }
            if (clip != null) {
                // Reset clip.
                g.setClip(clip.x, clip.y, clip.width, clip.height);
            }
        }

        private boolean updatePaintCoordinates
                 (Rectangle clip, int width, int height){
            if ((flags & 3) == 1) {
                paintMaxY = paintY + 1;
            }
            else if ((flags & 3) == 2) {
                paintMaxX = paintX + 1;
            }
            if (clip != null) {
                if ((flags & 3) == 1 && ((paintY + height <= clip.y) ||
                                         (paintY > clip.y + clip.height))) {
                    // not visible.
                    return false;
                }
                if ((flags & 3) == 2 && ((paintX + width <= clip.x) ||
                                         (paintX > clip.x + clip.width))) {
                    // not visible.
                    return false;
                }
                if ((flags & 1) == 1) {
                    if ((clip.x + clip.width) < paintMaxX) {
                        if ((clip.x + clip.width - paintX) % width == 0) {
                            paintMaxX = clip.x + clip.width;
                        }
                        else {
                            paintMaxX = ((clip.x + clip.width - paintX) /
                                         width + 1) * width + paintX;
                        }
                    }
                    if (clip.x > paintX) {
                        paintX = (clip.x - paintX) / width * width + paintX;
                    }
                }
                if ((flags & 2) == 2) {
                    if ((clip.y + clip.height) < paintMaxY) {
                        if ((clip.y + clip.height - paintY) % height == 0) {
                            paintMaxY = clip.y + clip.height;
                        }
                        else {
                            paintMaxY = ((clip.y + clip.height - paintY) /
                                         height + 1) * height + paintY;
                        }
                    }
                    if (clip.y > paintY) {
                        paintY = (clip.y - paintY) / height * height + paintY;
                    }
                }
            }
            // Valid
            return true;
        }
    }


    /**
     * A subclass of MuxingAttributeSet that translates between
     * CSS and HTML and StyleConstants. The AttributeSets used are
     * the CSS rules that match the Views Elements.
     */
    class ViewAttributeSet extends MuxingAttributeSet {
        ViewAttributeSet(View v) {
            host = v;

            // PENDING(prinz) fix this up to be a more realistic
            // implementation.
            Document doc = v.getDocument();
            SearchBuffer sb = SearchBuffer.obtainSearchBuffer();
            Vector<AttributeSet> muxList = sb.getVector();
            try {
                if (doc instanceof HTMLDocument) {
                    StyleSheet styles = StyleSheet.this;
                    Element elem = v.getElement();
                    AttributeSet a = elem.getAttributes();
                    AttributeSet htmlAttr = styles.translateHTMLToCSS(a);

                    if (htmlAttr.getAttributeCount() != 0) {
                        muxList.addElement(htmlAttr);
                    }
                    if (elem.isLeaf()) {
                        Enumeration keys = a.getAttributeNames();
                        while (keys.hasMoreElements()) {
                            Object key = keys.nextElement();
                            if (key instanceof HTML.Tag) {
                                if (key == HTML.Tag.A) {
                                    Object o = a.getAttribute(key);
                                /**
                                   In the case of an A tag, the css rules
                                   apply only for tags that have their
                                   href attribute defined and not for
                                   anchors that only have their name attributes
                                   defined, i.e anchors that function as
                                   destinations.  Hence we do not add the
                                   attributes for that latter kind of
                                   anchors.  When CSS2 support is added,
                                   it will be possible to specificity this
                                   kind of conditional behaviour in the
                                   stylesheet.
                                 **/
                                    if (o != null && o instanceof AttributeSet) {
                                        AttributeSet attr = (AttributeSet)o;
                                        if (attr.getAttribute(HTML.Attribute.HREF) == null) {
                                            continue;
                                        }
                                    }
                                }
                                AttributeSet cssRule = styles.getRule((HTML.Tag) key, elem);
                                if (cssRule != null) {
                                    muxList.addElement(cssRule);
                                }
                            }
                        }
                    } else {
                        HTML.Tag t = (HTML.Tag) a.getAttribute
                                     (StyleConstants.NameAttribute);
                        AttributeSet cssRule = styles.getRule(t, elem);
                        if (cssRule != null) {
                            muxList.addElement(cssRule);
                        }
                    }
                }
                AttributeSet[] attrs = new AttributeSet[muxList.size()];
                muxList.copyInto(attrs);
                setAttributes(attrs);
            }
            finally {
                SearchBuffer.releaseSearchBuffer(sb);
            }
        }

        //  --- AttributeSet methods ----------------------------

        /**
         * Checks whether a given attribute is defined.
         * This will convert the key over to CSS if the
         * key is a StyleConstants key that has a CSS
         * mapping.
         *
         * @param key the attribute key
         * @return true if the attribute is defined
         * @see AttributeSet#isDefined
         */
        public boolean isDefined(Object key) {
            if (key instanceof StyleConstants) {
                Object cssKey = css.styleConstantsKeyToCSSKey
                                    ((StyleConstants)key);
                if (cssKey != null) {
                    key = cssKey;
                }
            }
            return super.isDefined(key);
        }

        /**
         * Gets the value of an attribute.  If the requested
         * attribute is a StyleConstants attribute that has
         * a CSS mapping, the request will be converted.
         *
         * @param key the attribute name
         * @return the attribute value
         * @see AttributeSet#getAttribute
         */
        public Object getAttribute(Object key) {
            if (key instanceof StyleConstants) {
                Object cssKey = css.styleConstantsKeyToCSSKey
                               ((StyleConstants)key);
                if (cssKey != null) {
                    Object value = doGetAttribute(cssKey);
                    if (value instanceof CSS.CssValue) {
                        return ((CSS.CssValue)value).toStyleConstants
                                     ((StyleConstants)key, host);
                    }
                }
            }
            return doGetAttribute(key);
        }

        Object doGetAttribute(Object key) {
            Object retValue = super.getAttribute(key);
            if (retValue != null) {
                return retValue;
            }
            // didn't find it... try parent if it's a css attribute
            // that is inherited.
            if (key instanceof CSS.Attribute) {
                CSS.Attribute css = (CSS.Attribute) key;
                if (css.isInherited()) {
                    AttributeSet parent = getResolveParent();
                    if (parent != null)
                        return parent.getAttribute(key);
                }
            }
            return null;
        }

        /**
         * If not overriden, the resolving parent defaults to
         * the parent element.
         *
         * @return the attributes from the parent
         * @see AttributeSet#getResolveParent
         */
        public AttributeSet getResolveParent() {
            if (host == null) {
                return null;
            }
            View parent = host.getParent();
            return (parent != null) ? parent.getAttributes() : null;
        }

        /** View created for. */
        View host;
    }


    /**
     * A subclass of MuxingAttributeSet that implements Style. Currently
     * the MutableAttributeSet methods are unimplemented, that is they
     * do nothing.
     */
    // PENDING(sky): Decide what to do with this. Either make it
    // contain a SimpleAttributeSet that modify methods are delegated to,
    // or change getRule to return an AttributeSet and then don't make this
    // implement Style.
    static class ResolvedStyle extends MuxingAttributeSet implements
                  Serializable, Style {
        ResolvedStyle(String name, AttributeSet[] attrs, int extendedIndex) {
            super(attrs);
            this.name = name;
            this.extendedIndex = extendedIndex;
        }

        /**
         * Inserts a Style into the receiver so that the styles the
         * receiver represents are still ordered by specificity.
         * <code>style</code> will be added before any extended styles, that
         * is before extendedIndex.
         */
        synchronized void insertStyle(Style style, int specificity) {
            AttributeSet[] attrs = getAttributes();
            int maxCounter = attrs.length;
            int counter = 0;
            for (;counter < extendedIndex; counter++) {
                if (specificity > getSpecificity(((Style)attrs[counter]).
                                                 getName())) {
                    break;
                }
            }
            insertAttributeSetAt(style, counter);
            extendedIndex++;
        }

        /**
         * Removes a previously added style. This will do nothing if
         * <code>style</code> is not referenced by the receiver.
         */
        synchronized void removeStyle(Style style) {
            AttributeSet[] attrs = getAttributes();

            for (int counter = attrs.length - 1; counter >= 0; counter--) {
                if (attrs[counter] == style) {
                    removeAttributeSetAt(counter);
                    if (counter < extendedIndex) {
                        extendedIndex--;
                    }
                    break;
                }
            }
        }

        /**
         * Adds <code>s</code> as one of the Attributesets to look up
         * attributes in.
         */
        synchronized void insertExtendedStyleAt(Style attr, int index) {
            insertAttributeSetAt(attr, extendedIndex + index);
        }

        /**
         * Adds <code>s</code> as one of the AttributeSets to look up
         * attributes in. It will be the AttributeSet last checked.
         */
        synchronized void addExtendedStyle(Style attr) {
            insertAttributeSetAt(attr, getAttributes().length);
        }

        /**
         * Removes the style at <code>index</code> +
         * <code>extendedIndex</code>.
         */
        synchronized void removeExtendedStyleAt(int index) {
            removeAttributeSetAt(extendedIndex + index);
        }

        /**
         * Returns true if the receiver matches <code>selector</code>, where
         * a match is defined by the CSS rule matching.
         * Each simple selector must be separated by a single space.
         */
        protected boolean matches(String selector) {
            int sLast = selector.length();

            if (sLast == 0) {
                return false;
            }
            int thisLast = name.length();
            int sCurrent = selector.lastIndexOf(' ');
            int thisCurrent = name.lastIndexOf(' ');
            if (sCurrent >= 0) {
                sCurrent++;
            }
            if (thisCurrent >= 0) {
                thisCurrent++;
            }
            if (!matches(selector, sCurrent, sLast, thisCurrent, thisLast)) {
                return false;
            }
            while (sCurrent != -1) {
                sLast = sCurrent - 1;
                sCurrent = selector.lastIndexOf(' ', sLast - 1);
                if (sCurrent >= 0) {
                    sCurrent++;
                }
                boolean match = false;
                while (!match && thisCurrent != -1) {
                    thisLast = thisCurrent - 1;
                    thisCurrent = name.lastIndexOf(' ', thisLast - 1);
                    if (thisCurrent >= 0) {
                        thisCurrent++;
                    }
                    match = matches(selector, sCurrent, sLast, thisCurrent,
                                    thisLast);
                }
                if (!match) {
                    return false;
                }
            }
            return true;
        }

        /**
         * Returns true if the substring of the receiver, in the range
         * thisCurrent, thisLast matches the substring of selector in
         * the ranme sCurrent to sLast based on CSS selector matching.
         */
        boolean matches(String selector, int sCurrent, int sLast,
                       int thisCurrent, int thisLast) {
            sCurrent = Math.max(sCurrent, 0);
            thisCurrent = Math.max(thisCurrent, 0);
            int thisDotIndex = boundedIndexOf(name, '.', thisCurrent,
                                              thisLast);
            int thisPoundIndex = boundedIndexOf(name, '#', thisCurrent,
                                                thisLast);
            int sDotIndex = boundedIndexOf(selector, '.', sCurrent, sLast);
            int sPoundIndex = boundedIndexOf(selector, '#', sCurrent, sLast);
            if (sDotIndex != -1) {
                // Selector has a '.', which indicates name must match it,
                // or if the '.' starts the selector than name must have
                // the same class (doesn't matter what element name).
                if (thisDotIndex == -1) {
                    return false;
                }
                if (sCurrent == sDotIndex) {
                    if ((thisLast - thisDotIndex) != (sLast - sDotIndex) ||
                        !selector.regionMatches(sCurrent, name, thisDotIndex,
                                                (thisLast - thisDotIndex))) {
                        return false;
                    }
                }
                else {
                    // Has to fully match.
                    if ((sLast - sCurrent) != (thisLast - thisCurrent) ||
                        !selector.regionMatches(sCurrent, name, thisCurrent,
                                                (thisLast - thisCurrent))) {
                        return false;
                    }
                }
                return true;
            }
            if (sPoundIndex != -1) {
                // Selector has a '#', which indicates name must match it,
                // or if the '#' starts the selector than name must have
                // the same id (doesn't matter what element name).
                if (thisPoundIndex == -1) {
                    return false;
                }
                if (sCurrent == sPoundIndex) {
                    if ((thisLast - thisPoundIndex) !=(sLast - sPoundIndex) ||
                        !selector.regionMatches(sCurrent, name, thisPoundIndex,
                                                (thisLast - thisPoundIndex))) {
                        return false;
                    }
                }
                else {
                    // Has to fully match.
                    if ((sLast - sCurrent) != (thisLast - thisCurrent) ||
                        !selector.regionMatches(sCurrent, name, thisCurrent,
                                               (thisLast - thisCurrent))) {
                        return false;
                    }
                }
                return true;
            }
            if (thisDotIndex != -1) {
                // Reciever references a class, just check element name.
                return (((thisDotIndex - thisCurrent) == (sLast - sCurrent)) &&
                        selector.regionMatches(sCurrent, name, thisCurrent,
                                               thisDotIndex - thisCurrent));
            }
            if (thisPoundIndex != -1) {
                // Reciever references an id, just check element name.
                return (((thisPoundIndex - thisCurrent) ==(sLast - sCurrent))&&
                        selector.regionMatches(sCurrent, name, thisCurrent,
                                               thisPoundIndex - thisCurrent));
            }
            // Fail through, no classes or ides, just check string.
            return (((thisLast - thisCurrent) == (sLast - sCurrent)) &&
                    selector.regionMatches(sCurrent, name, thisCurrent,
                                           thisLast - thisCurrent));
        }

        /**
         * Similiar to String.indexOf, but allows an upper bound
         * (this is slower in that it will still check string starting at
         * start.
         */
        int boundedIndexOf(String string, char search, int start,
                           int end) {
            int retValue = string.indexOf(search, start);
            if (retValue >= end) {
                return -1;
            }
            return retValue;
        }

        public void addAttribute(Object name, Object value) {}
        public void addAttributes(AttributeSet attributes) {}
        public void removeAttribute(Object name) {}
        public void removeAttributes(Enumeration<?> names) {}
        public void removeAttributes(AttributeSet attributes) {}
        public void setResolveParent(AttributeSet parent) {}
        public String getName() {return name;}
        public void addChangeListener(ChangeListener l) {}
        public void removeChangeListener(ChangeListener l) {}
        public ChangeListener[] getChangeListeners() {
            return new ChangeListener[0];
        }

        /** The name of the Style, which is the selector.
         * This will NEVER change!
         */
        String name;
        /** Start index of styles coming from other StyleSheets. */
        private int extendedIndex;
    }


    /**
     * SelectorMapping contains a specifitiy, as an integer, and an associated
     * Style. It can also reference children <code>SelectorMapping</code>s,
     * so that it behaves like a tree.
     * <p>
     * This is not thread safe, it is assumed the caller will take the
     * necessary precations if this is to be used in a threaded environment.
     */
    static class SelectorMapping implements Serializable {
        public SelectorMapping(int specificity) {
            this.specificity = specificity;
        }

        /**
         * Returns the specificity this mapping represents.
         */
        public int getSpecificity() {
            return specificity;
        }

        /**
         * Sets the Style associated with this mapping.
         */
        public void setStyle(Style style) {
            this.style = style;
        }

        /**
         * Returns the Style associated with this mapping.
         */
        public Style getStyle() {
            return style;
        }

        /**
         * Returns the child mapping identified by the simple selector
         * <code>selector</code>. If a child mapping does not exist for
         *<code>selector</code>, and <code>create</code> is true, a new
         * one will be created.
         */
        public SelectorMapping getChildSelectorMapping(String selector,
                                                       boolean create) {
            SelectorMapping retValue = null;

            if (children != null) {
                retValue = children.get(selector);
            }
            else if (create) {
                children = new HashMap<String, SelectorMapping>(7);
            }
            if (retValue == null && create) {
                int specificity = getChildSpecificity(selector);

                retValue = createChildSelectorMapping(specificity);
                children.put(selector, retValue);
            }
            return retValue;
        }

        /**
         * Creates a child <code>SelectorMapping</code> with the specified
         * <code>specificity</code>.
         */
        protected SelectorMapping createChildSelectorMapping(int specificity) {
            return new SelectorMapping(specificity);
        }

        /**
         * Returns the specificity for the child selector
         * <code>selector</code>.
         */
        protected int getChildSpecificity(String selector) {
            // class (.) 100
            // id (#)    10000
            char    firstChar = selector.charAt(0);
            int     specificity = getSpecificity();

            if (firstChar == '.') {
                specificity += 100;
            }
            else if (firstChar == '#') {
                specificity += 10000;
            }
            else {
                specificity += 1;
                if (selector.indexOf('.') != -1) {
                    specificity += 100;
                }
                if (selector.indexOf('#') != -1) {
                    specificity += 10000;
                }
            }
            return specificity;
        }

        /**
         * The specificity for this selector.
         */
        private int specificity;
        /**
         * Style for this selector.
         */
        private Style style;
        /**
         * Any sub selectors. Key will be String, and value will be
         * another SelectorMapping.
         */
        private HashMap<String, SelectorMapping> children;
    }


    // ---- Variables ---------------------------------------------

    final static int DEFAULT_FONT_SIZE = 3;

    private CSS css;

    /**
     * An inverted graph of the selectors.
     */
    private SelectorMapping selectorMapping;

    /** Maps from selector (as a string) to Style that includes all
     * relevant styles. */
    private Hashtable<String, ResolvedStyle> resolvedStyles;

    /** Vector of StyleSheets that the rules are to reference.
     */
    private Vector<StyleSheet> linkedStyleSheets;

    /** Where the style sheet was found. Used for relative imports. */
    private URL base;


    /**
     * Default parser for CSS specifications that get loaded into
     * the StyleSheet.<p>
     * This class is NOT thread safe, do not ask it to parse while it is
     * in the middle of parsing.
     */
    class CssParser implements CSSParser.CSSParserCallback {

        /**
         * Parses the passed in CSS declaration into an AttributeSet.
         */
        public AttributeSet parseDeclaration(String string) {
            try {
                return parseDeclaration(new StringReader(string));
            } catch (IOException ioe) {}
            return null;
        }

        /**
         * Parses the passed in CSS declaration into an AttributeSet.
         */
        public AttributeSet parseDeclaration(Reader r) throws IOException {
            parse(base, r, true, false);
            return declaration.copyAttributes();
        }

        /**
         * Parse the given CSS stream
         */
        public void parse(URL base, Reader r, boolean parseDeclaration,
                          boolean isLink) throws IOException {
            this.base = base;
            this.isLink = isLink;
            this.parsingDeclaration = parseDeclaration;
            declaration.removeAttributes(declaration);
            selectorTokens.removeAllElements();
            selectors.removeAllElements();
            propertyName = null;
            parser.parse(r, this, parseDeclaration);
        }

        //
        // CSSParserCallback methods, public to implement the interface.
        //

        /**
         * Invoked when a valid @import is encountered, will call
         * <code>importStyleSheet</code> if a
         * <code>MalformedURLException</code> is not thrown in creating
         * the URL.
         */
        public void handleImport(String importString) {
            URL url = CSS.getURL(base, importString);
            if (url != null) {
                importStyleSheet(url);
            }
        }

        /**
         * A selector has been encountered.
         */
        public void handleSelector(String selector) {
            //class and index selectors are case sensitive
            if (!(selector.startsWith(".")
                  || selector.startsWith("#"))) {
                selector = selector.toLowerCase();
            }
            int length = selector.length();

            if (selector.endsWith(",")) {
                if (length > 1) {
                    selector = selector.substring(0, length - 1);
                    selectorTokens.addElement(selector);
                }
                addSelector();
            }
            else if (length > 0) {
                selectorTokens.addElement(selector);
            }
        }

        /**
         * Invoked when the start of a rule is encountered.
         */
        public void startRule() {
            if (selectorTokens.size() > 0) {
                addSelector();
            }
            propertyName = null;
        }

        /**
         * Invoked when a property name is encountered.
         */
        public void handleProperty(String property) {
            propertyName = property;
        }

        /**
         * Invoked when a property value is encountered.
         */
        public void handleValue(String value) {
            if (propertyName != null && value != null && value.length() > 0) {
                CSS.Attribute cssKey = CSS.getAttribute(propertyName);
                if (cssKey != null) {
                    // There is currently no mechanism to determine real
                    // base that style sheet was loaded from. For the time
                    // being, this maps for LIST_STYLE_IMAGE, which appear
                    // to be the only one that currently matters. A more
                    // general mechanism is definately needed.
                    if (cssKey == CSS.Attribute.LIST_STYLE_IMAGE) {
                        if (value != null && !value.equals("none")) {
                            URL url = CSS.getURL(base, value);

                            if (url != null) {
                                value = url.toString();
                            }
                        }
                    }
                    addCSSAttribute(declaration, cssKey, value);
                }
                propertyName = null;
            }
        }

        /**
         * Invoked when the end of a rule is encountered.
         */
        public void endRule() {
            int n = selectors.size();
            for (int i = 0; i < n; i++) {
                String[] selector = selectors.elementAt(i);
                if (selector.length > 0) {
                    StyleSheet.this.addRule(selector, declaration, isLink);
                }
            }
            declaration.removeAttributes(declaration);
            selectors.removeAllElements();
        }

        private void addSelector() {
            String[] selector = new String[selectorTokens.size()];
            selectorTokens.copyInto(selector);
            selectors.addElement(selector);
            selectorTokens.removeAllElements();
        }


        Vector<String[]> selectors = new Vector<String[]>();
        Vector<String> selectorTokens = new Vector<String>();
        /** Name of the current property. */
        String propertyName;
        MutableAttributeSet declaration = new SimpleAttributeSet();
        /** True if parsing a declaration, that is the Reader will not
         * contain a selector. */
        boolean parsingDeclaration;
        /** True if the attributes are coming from a linked/imported style. */
        boolean isLink;
        /** Where the CSS stylesheet lives. */
        URL base;
        CSSParser parser = new CSSParser();
    }

    void rebaseSizeMap(int base) {
        final int minimalFontSize = 4;
        sizeMap = new int[sizeMapDefault.length];
        for (int i = 0; i < sizeMapDefault.length; i++) {
            sizeMap[i] = Math.max(base * sizeMapDefault[i] /
                                  sizeMapDefault[CSS.baseFontSizeIndex],
                                  minimalFontSize);
        }

    }

    int[] getSizeMap() {
        return sizeMap;
    }
    boolean isW3CLengthUnits() {
        return w3cLengthUnits;
    }

    /**
     * The HTML/CSS size model has seven slots
     * that one can assign sizes to.
     */
    static final int sizeMapDefault[] = { 8, 10, 12, 14, 18, 24, 36 };

    private int sizeMap[] = sizeMapDefault;
    private boolean w3cLengthUnits = false;
}
