/*

   Copyright 2002-2006  The Apache Software Foundation

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package org.apache.batik.css.engine;

import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.batik.css.engine.sac.CSSConditionFactory;
import org.apache.batik.css.engine.sac.CSSSelectorFactory;
import org.apache.batik.css.engine.sac.ExtendedSelector;
import org.apache.batik.css.engine.value.ComputedValue;
import org.apache.batik.css.engine.value.InheritValue;
import org.apache.batik.css.engine.value.ShorthandManager;
import org.apache.batik.css.engine.value.Value;
import org.apache.batik.css.engine.value.ValueManager;
import org.apache.batik.css.parser.ExtendedParser;
import org.apache.batik.util.CSSConstants;
import org.apache.batik.util.ParsedURL;

import org.w3c.css.sac.CSSException;
import org.w3c.css.sac.DocumentHandler;
import org.w3c.css.sac.InputSource;
import org.w3c.css.sac.LexicalUnit;
import org.w3c.css.sac.SACMediaList;
import org.w3c.css.sac.SelectorList;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.MutationEvent;


/**
 * This is the base class for all the CSS engines.
 *
 * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
 * @version $Id$
 */
public abstract class CSSEngine {

    /**
     * Returns the CSS parent node of the given node.
     */
    public static Node getCSSParentNode(Node n) {
        if (n instanceof CSSNavigableNode) {
            return ((CSSNavigableNode) n).getCSSParentNode();
        }
        return n.getParentNode();
    }

    /**
     * Returns the CSS first child node of the given node.
     */
    protected static Node getCSSFirstChild(Node n) {
        if (n instanceof CSSNavigableNode) {
            return ((CSSNavigableNode) n).getCSSFirstChild();
        }
        return n.getFirstChild();
    }

    /**
     * Returns the CSS next sibling node of the given node.
     */
    protected static Node getCSSNextSibling(Node n) {
        if (n instanceof CSSNavigableNode) {
            return ((CSSNavigableNode) n).getCSSNextSibling();
        }
        return n.getNextSibling();
    }

    /**
     * Returns the CSS previous sibling node of the given node.
     */
    protected static Node getCSSPreviousSibling(Node n) {
        if (n instanceof CSSNavigableNode) {
            return ((CSSNavigableNode) n).getCSSPreviousSibling();
        }
        return n.getPreviousSibling();
    }

    /**
     * Returns the next stylable parent of the given element.
     */
    public static CSSStylableElement getParentCSSStylableElement(Element elt) {
        Node n = getCSSParentNode(elt);
        while (n != null) {
            if (n instanceof CSSStylableElement) {
                return (CSSStylableElement) n;
            }
            n = getCSSParentNode(n);
        }
        return null;
    }

    /**
     * The user agent used for showing error messages.
     */
    protected CSSEngineUserAgent userAgent;

    /**
     * The CSS context.
     */
    protected CSSContext cssContext;

    /**
     * The associated document.
     */
    protected Document document;

    /**
     * The document URI.
     */
    protected URL documentURI;

    /**
     * Whether the document is a CSSNavigableDocument.
     */
    protected boolean isCSSNavigableDocument;

    /**
     * The property/int mappings.
     */
    protected StringIntMap indexes;

    /**
     * The shorthand-property/int mappings.
     */
    protected StringIntMap shorthandIndexes;

    /**
     * The value managers.
     */
    protected ValueManager[] valueManagers;

    /**
     * The shorthand managers.
     */
    protected ShorthandManager[] shorthandManagers;

    /**
     * The CSS parser.
     */
    protected ExtendedParser parser;

    /**
     * The pseudo-element names.
     */
    protected String[] pseudoElementNames;

    /**
     * The font-size property index.
     */
    protected int fontSizeIndex = -1;

    /**
     * The line-height property index.
     */
    protected int lineHeightIndex = -1;

    /**
     * The color property index.
     */
    protected int colorIndex = -1;

    /**
     * The user-agent style-sheet.
     */
    protected StyleSheet userAgentStyleSheet;

    /**
     * The user style-sheet.
     */
    protected StyleSheet userStyleSheet;

    /**
     * The media to use to cascade properties.
     */
    protected SACMediaList media;

    /**
     * The DOM nodes which contains StyleSheets.
     */
    protected List styleSheetNodes;

    /**
     * List of StyleMap objects, one for each @font-face rule
     * encountered by this CSSEngine.
     */
    protected List fontFaces = new LinkedList();

    /**
     * The style attribute namespace URI.
     */
    protected String styleNamespaceURI;

    /**
     * The style attribute local name.
     */
    protected String styleLocalName;

    /**
     * The class attribute namespace URI.
     */
    protected String classNamespaceURI;

    /**
     * The class attribute local name.
     */
    protected String classLocalName;

    /**
     * The non CSS presentational hints.
     */
    protected Set nonCSSPresentationalHints;

    /**
     * The non CSS presentational hints namespace URI.
     */
    protected String nonCSSPresentationalHintsNamespaceURI;

    /**
     * The style declaration document handler.
     */
    protected StyleDeclarationDocumentHandler styleDeclarationDocumentHandler =
        new StyleDeclarationDocumentHandler();

    /**
     * The style declaration update handler.
     */
    protected StyleDeclarationUpdateHandler styleDeclarationUpdateHandler;

    /**
     * The style sheet document handler.
     */
    protected StyleSheetDocumentHandler styleSheetDocumentHandler =
        new StyleSheetDocumentHandler();

    /**
     * The style declaration document handler used to build a
     * StyleDeclaration object.
     */
    protected StyleDeclarationBuilder styleDeclarationBuilder =
        new StyleDeclarationBuilder();

    /**
     * The current element.
     */
    protected CSSStylableElement element;

    /**
     * The current base URI.
     */
    protected URL cssBaseURI;

    /**
     * The alternate stylesheet title.
     */
    protected String alternateStyleSheet;

    /**
     * Listener for CSSNavigableDocument events.
     */
    protected CSSNavigableDocumentHandler cssNavigableDocumentListener;

    /**
     * The DOMAttrModified event listener.
     */
    protected EventListener domAttrModifiedListener;

    /**
     * The DOMNodeInserted event listener.
     */
    protected EventListener domNodeInsertedListener;

    /**
     * The DOMNodeRemoved event listener.
     */
    protected EventListener domNodeRemovedListener;

    /**
     * The DOMSubtreeModified event listener.
     */
    protected EventListener domSubtreeModifiedListener;

    /**
     * The DOMCharacterDataModified event listener.
     */
    protected EventListener domCharacterDataModifiedListener;

    /**
     * Whether a style sheet as been removed from the document.
     */
    protected boolean styleSheetRemoved;

    /**
     * The right sibling of the last removed node.
     */
    protected Node removedStylableElementSibling;

    /**
     * The listeners.
     */
    protected List listeners = Collections.synchronizedList(new LinkedList());

    /**
     * The attributes found in stylesheets selectors.
     */
    protected Set selectorAttributes;

    /**
     * Used to fire a change event for all the properties.
     */
    protected final int[] ALL_PROPERTIES;

    /**
     * The CSS condition factory.
     */
    protected CSSConditionFactory cssConditionFactory;

    /**
     * Creates a new CSSEngine.
     * @param doc The associated document.
     * @param uri The document URI.
     * @param p The CSS parser.
     * @param vm The property value managers.
     * @param sm The shorthand properties managers.
     * @param pe The pseudo-element names supported by the associated
     *           XML dialect. Must be null if no support for pseudo-
     *           elements is required.
     * @param sns The namespace URI of the style attribute.
     * @param sln The local name of the style attribute.
     * @param cns The namespace URI of the class attribute.
     * @param cln The local name of the class attribute.
     * @param hints Whether the CSS engine should support non CSS
     *              presentational hints.
     * @param hintsNS The hints namespace URI.
     * @param ctx The CSS context.
     */
    protected CSSEngine(Document doc,
                        URL uri,
                        ExtendedParser p,
                        ValueManager[] vm,
                        ShorthandManager[] sm,
                        String[] pe,
                        String sns,
                        String sln,
                        String cns,
                        String cln,
                        boolean hints,
                        String hintsNS,
                        CSSContext ctx) {
        document = doc;
        documentURI = uri;
        parser = p;
        pseudoElementNames = pe;
        styleNamespaceURI = sns;
        styleLocalName = sln;
        classNamespaceURI = cns;
        classLocalName = cln;
        cssContext = ctx;

        isCSSNavigableDocument = doc instanceof CSSNavigableDocument;

        cssConditionFactory = new CSSConditionFactory(cns, cln, null, "id");

        int len = vm.length;
        indexes = new StringIntMap(len);
        valueManagers = vm;

        for (int i = len - 1; i >= 0; --i) {
            String pn = vm[i].getPropertyName();
            indexes.put(pn, i);
            if (fontSizeIndex == -1 &&
                pn.equals(CSSConstants.CSS_FONT_SIZE_PROPERTY)) {
                fontSizeIndex = i;
            }
            if (lineHeightIndex == -1 &&
                pn.equals(CSSConstants.CSS_LINE_HEIGHT_PROPERTY)) {
                lineHeightIndex = i;
            }
            if (colorIndex == -1 &&
                pn.equals(CSSConstants.CSS_COLOR_PROPERTY)) {
                colorIndex = i;
            }
        }

        len = sm.length;
        shorthandIndexes = new StringIntMap(len);
        shorthandManagers = sm;
        for (int i = len - 1; i >= 0; --i) {
            shorthandIndexes.put(sm[i].getPropertyName(), i);
        }

        if (hints) {
            nonCSSPresentationalHints = new HashSet(vm.length+sm.length);
            nonCSSPresentationalHintsNamespaceURI = hintsNS;
            len = vm.length;
            for (int i = 0; i < len; i++) {
                String pn = vm[i].getPropertyName();
                nonCSSPresentationalHints.add(pn);
            }
            len = sm.length;
            for (int i = 0; i < len; i++) {
                String pn = sm[i].getPropertyName();
                nonCSSPresentationalHints.add(pn);
            }
        }

        if (cssContext.isDynamic() && document instanceof EventTarget) {
            // Attach the mutation events listeners.
            addEventListeners((EventTarget) document);
            styleDeclarationUpdateHandler =
                new StyleDeclarationUpdateHandler();
        }

        ALL_PROPERTIES = new int[getNumberOfProperties()];
        for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
            ALL_PROPERTIES[i] = i;
        }
    }

    /**
     * Adds event listeners to the document to track CSS changes.
     */
    protected void addEventListeners(EventTarget doc) {
        if (isCSSNavigableDocument) {
            cssNavigableDocumentListener = new CSSNavigableDocumentHandler();
            CSSNavigableDocument cnd = (CSSNavigableDocument) doc;
            cnd.addCSSNavigableDocumentListener(cssNavigableDocumentListener);
        } else {
            domAttrModifiedListener = new DOMAttrModifiedListener();
            doc.addEventListener("DOMAttrModified",
                                 domAttrModifiedListener,
                                 false);
            domNodeInsertedListener = new DOMNodeInsertedListener();
            doc.addEventListener("DOMNodeInserted",
                                 domNodeInsertedListener,
                                 false);
            domNodeRemovedListener = new DOMNodeRemovedListener();
            doc.addEventListener("DOMNodeRemoved",
                                 domNodeRemovedListener,
                                 false);
            domSubtreeModifiedListener = new DOMSubtreeModifiedListener();
            doc.addEventListener("DOMSubtreeModified",
                                 domSubtreeModifiedListener,
                                 false);
            domCharacterDataModifiedListener =
                new DOMCharacterDataModifiedListener();
            doc.addEventListener("DOMCharacterDataModified",
                                 domCharacterDataModifiedListener,
                                 false);
        }
    }

    /**
     * Removes the event listeners from the document.
     */
    protected void removeEventListeners(EventTarget doc) {
        if (isCSSNavigableDocument) {
            CSSNavigableDocument cnd = (CSSNavigableDocument) doc;
            cnd.removeCSSNavigableDocumentListener
                (cssNavigableDocumentListener);
        } else {
            doc.removeEventListener("DOMAttrModified",
                                    domAttrModifiedListener,
                                    false);
            doc.removeEventListener("DOMNodeInserted",
                                    domNodeInsertedListener,
                                    false);
            doc.removeEventListener("DOMNodeRemoved",
                                    domNodeRemovedListener,
                                    false);
            doc.removeEventListener("DOMSubtreeModified",
                                    domSubtreeModifiedListener,
                                    false);
            doc.removeEventListener("DOMCharacterDataModified",
                                    domCharacterDataModifiedListener,
                                    false);
        }
    }

    /**
     * Disposes the CSSEngine and all the attached resources.
     */
    public void dispose() {
        setCSSEngineUserAgent(null);
        disposeStyleMaps(document.getDocumentElement());
        if (document instanceof EventTarget) {
            // Detach the mutation events listeners.
            removeEventListeners((EventTarget) document);
        }
    }

    /**
     * Removes the style maps from each CSSStylableElement in the document.
     */
    protected void disposeStyleMaps(Node node) {
        if (node instanceof CSSStylableElement) {
            ((CSSStylableElement)node).setComputedStyleMap(null, null);
        }
        for (Node n = getCSSFirstChild(node);
             n != null;
             n = getCSSNextSibling(n)) {
            if (n.getNodeType() == Node.ELEMENT_NODE) {
                disposeStyleMaps(n);
            }
        }
    }

    /**
     * Returns the CSS context.
     */
    public CSSContext getCSSContext() {
        return cssContext;
    }

    /**
     * Returns the document associated with this engine.
     */
    public Document getDocument() {
        return document;
    }

    /**
     * Returns the font-size property index.
     */
    public int getFontSizeIndex() {
        return fontSizeIndex;
    }

    /**
     * Returns the line-height property index.
     */
    public int getLineHeightIndex() {
        return lineHeightIndex;
    }

    /**
     * Returns the color property index.
     */
    public int getColorIndex() {
        return colorIndex;
    }

    /**
     * Returns the number of properties.
     */
    public int getNumberOfProperties() {
        return valueManagers.length;
    }

    /**
     * Returns the property index, or -1.
     */
    public int getPropertyIndex(String name) {
        return indexes.get(name);
    }

    /**
     * Returns the shorthand property index, or -1.
     */
    public int getShorthandIndex(String name) {
        return shorthandIndexes.get(name);
    }

    /**
     * Returns the name of the property at the given index.
     */
    public String getPropertyName(int idx) {
        return valueManagers[idx].getPropertyName();
    }

    public void setCSSEngineUserAgent(CSSEngineUserAgent userAgent) {
        this.userAgent = userAgent;
    }

    public CSSEngineUserAgent getCSSEngineUserAgent() {
        return userAgent;
    }

    /**
     * Sets the user agent style-sheet.
     */
    public void setUserAgentStyleSheet(StyleSheet ss) {
        userAgentStyleSheet = ss;
    }

    /**
     * Sets the user style-sheet.
     */
    public void setUserStyleSheet(StyleSheet ss) {
        userStyleSheet = ss;
    }

    /**
     * Returns the ValueManagers.
     */
    public ValueManager[] getValueManagers() {
        return valueManagers;
    }

    /**
     * Returns the ShorthandManagers.
     */
    public ShorthandManager[] getShorthandManagers() {
        return shorthandManagers;
    }

    /**
     * Gets the StyleMaps generated by @font-face rules
     * encountered by this CSSEngine thus far.
     */
    public List getFontFaces() {
        return fontFaces;
    }

    /**
     * Sets the media to use to compute the styles.
     */
    public void setMedia(String str) {
        try {
            media = parser.parseMedia(str);
        } catch (Exception e) {
            String m = e.getMessage();
            if (m == null) m = "";
            String s =Messages.formatMessage
                ("media.error", new Object[] { str, m });
            throw new DOMException(DOMException.SYNTAX_ERR, s);
        }
    }

    /**
     * Sets the alternate style-sheet title.
     */
    public void setAlternateStyleSheet(String str) {
        alternateStyleSheet = str;
    }

    /**
     * Recursively imports the cascaded style from a source element
     * to an element of the current document.
     */
    public void importCascadedStyleMaps(Element src,
                                        CSSEngine srceng,
                                        Element dest) {
        if (src instanceof CSSStylableElement) {
            CSSStylableElement csrc  = (CSSStylableElement)src;
            CSSStylableElement cdest = (CSSStylableElement)dest;

            StyleMap sm = srceng.getCascadedStyleMap(csrc, null);
            sm.setFixedCascadedStyle(true);
            cdest.setComputedStyleMap(null, sm);

            if (pseudoElementNames != null) {
                int len = pseudoElementNames.length;
                for (int i = 0; i < len; i++) {
                    String pe = pseudoElementNames[i];
                    sm = srceng.getCascadedStyleMap(csrc, pe);
                    cdest.setComputedStyleMap(pe, sm);
                }
            }
        }

        for (Node dn = getCSSFirstChild(dest), sn = getCSSFirstChild(src);
             dn != null;
             dn = getCSSNextSibling(dn), sn = getCSSNextSibling(sn)) {
            if (sn.getNodeType() == Node.ELEMENT_NODE) {
                importCascadedStyleMaps((Element)sn, srceng, (Element)dn);
            }
        }
    }

    /**
     * Returns the current base-url.
     */
    public URL getCSSBaseURI() {
        if (cssBaseURI == null) {
            cssBaseURI = element.getCSSBase();
        }
        return cssBaseURI;
    }

    /**
     * Returns the cascaded style of the given element/pseudo-element.
     * @param elt The stylable element.
     * @param pseudo Optional pseudo-element string (null if none).
     */
    public StyleMap getCascadedStyleMap(CSSStylableElement elt,
                                        String pseudo) {
        int props = getNumberOfProperties();
        final StyleMap result = new StyleMap(props);

        // Apply the user-agent style-sheet to the result.
        if (userAgentStyleSheet != null) {
            List rules = new ArrayList();
            addMatchingRules(rules, userAgentStyleSheet, elt, pseudo);
            addRules(elt, pseudo, result, rules, StyleMap.USER_AGENT_ORIGIN);
        }

        // Apply the user properties style-sheet to the result.
        if (userStyleSheet != null) {
            List rules = new ArrayList();
            addMatchingRules(rules, userStyleSheet, elt, pseudo);
            addRules(elt, pseudo, result, rules, StyleMap.USER_ORIGIN);
        }

        element = elt;
        try {
            // Apply the non-CSS presentational hints to the result.
            if (nonCSSPresentationalHints != null) {
                ShorthandManager.PropertyHandler ph =
                    new ShorthandManager.PropertyHandler() {
                        public void property(String pname, LexicalUnit lu,
                                             boolean important) {
                            int idx = getPropertyIndex(pname);
                            if (idx != -1) {
                                ValueManager vm = valueManagers[idx];
                                Value v = vm.createValue(lu, CSSEngine.this);
                                putAuthorProperty(result, idx, v, important,
                                                  StyleMap.NON_CSS_ORIGIN);
                                return;
                            }
                            idx = getShorthandIndex(pname);
                            if (idx == -1)
                                return; // Unknown property...
                            // Shorthand value
                            shorthandManagers[idx].setValues
                                (CSSEngine.this, this, lu, important);
                        }
                    };

                NamedNodeMap attrs = elt.getAttributes();
                int len = attrs.getLength();
                for (int i = 0; i < len; i++) {
                    Node attr = attrs.item(i);
                    String an = attr.getNodeName();
                    if (nonCSSPresentationalHints.contains(an)) {
                      String attrValue = attr.getNodeValue();          // -- dvh
                        try {
                            LexicalUnit lu;
                            lu = parser.parsePropertyValue(attr.getNodeValue());
                            ph.property(an, lu, false);
                        } catch (Exception e) {

                          System.err.println("\n***** CSSEngine: exception property.syntax.error:" + e );  // ---
                          System.err.println("\nAttrValue:" + attrValue );
                          System.err.println("\nException:" + e.getClass().getName() );
                          e.printStackTrace( System.err );                           // ---
                          System.err.println("\n***** CSSEngine: exception...." );   // ---

                            String m = e.getMessage();
                            if (m == null) m = "";
                            String u = ((documentURI == null)?"<unknown>":
                                        documentURI.toString());
                            String s = Messages.formatMessage
                                ("property.syntax.error.at",
                                 new Object[] { u, an, attr.getNodeValue(),m});
                            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
                            if (userAgent == null) throw de;
                            userAgent.displayError(de);
                        }
                    }
                }
            }

            // Apply the document style-sheets to the result.
            CSSEngine eng = cssContext.getCSSEngineForElement(elt);
            List snodes = eng.getStyleSheetNodes();
            int slen = snodes.size();
            if (slen > 0) {
                List rules = new ArrayList();
                for (int i = 0; i < slen; i++) {
                    CSSStyleSheetNode ssn = (CSSStyleSheetNode)snodes.get(i);
                    StyleSheet ss = ssn.getCSSStyleSheet();
                    if (ss != null &&
                        (!ss.isAlternate() ||
                         ss.getTitle() == null ||
                         ss.getTitle().equals(alternateStyleSheet)) &&
                        mediaMatch(ss.getMedia())) {
                        addMatchingRules(rules, ss, elt, pseudo);
                    }
                }
                addRules(elt, pseudo, result, rules, StyleMap.AUTHOR_ORIGIN);
            }

            // Apply the inline style to the result.
            if (styleLocalName != null) {
                String style = elt.getAttributeNS(styleNamespaceURI,
                                                  styleLocalName);
                if (style.length() > 0) {
                    try {
                        parser.setSelectorFactory(CSSSelectorFactory.INSTANCE);
                        parser.setConditionFactory(cssConditionFactory);
                        styleDeclarationDocumentHandler.styleMap = result;
                        parser.setDocumentHandler
                            (styleDeclarationDocumentHandler);
                        parser.parseStyleDeclaration(style);
                        styleDeclarationDocumentHandler.styleMap = null;
                    } catch (Exception e) {
                        String m = e.getMessage();
                        if (m == null) m = "";
                        String u = ((documentURI == null)?"<unknown>":
                                    documentURI.toString());
                        String s = Messages.formatMessage
                            ("style.syntax.error.at",
                             new Object[] { u, styleLocalName, style, m });
                        DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
                        if (userAgent == null) throw de;
                        userAgent.displayError(de);
                    }
                }
            }

            // Apply the override rules to the result.
            StyleDeclarationProvider p =
                elt.getOverrideStyleDeclarationProvider();
            if (p != null) {
                StyleDeclaration over = p.getStyleDeclaration();
                if (over != null) {
                    int ol = over.size();
                    for (int i = 0; i < ol; i++) {
                        int idx = over.getIndex(i);
                        Value value = over.getValue(i);
                        boolean important = over.getPriority(i);
                        if (!result.isImportant(idx) || important) {
                            result.putValue(idx, value);
                            result.putImportant(idx, important);
                            result.putOrigin(idx, StyleMap.OVERRIDE_ORIGIN);
                        }
                    }
                }
            }
        } finally {
            element = null;
            cssBaseURI = null;
        }

        return result;
    }

    /**
     * Returns the computed style of the given element/pseudo for the
     * property corresponding to the given index.
     */
    public Value getComputedStyle(CSSStylableElement elt,
                                  String pseudo,
                                  int propidx) {
        StyleMap sm = elt.getComputedStyleMap(pseudo);
        if (sm == null) {
            sm = getCascadedStyleMap(elt, pseudo);
            elt.setComputedStyleMap(pseudo, sm);
        }

        Value value = sm.getValue(propidx);
        if (sm.isComputed(propidx))
            return value;

        Value result = value;
        ValueManager vm = valueManagers[propidx];
        CSSStylableElement p = getParentCSSStylableElement(elt);
        if (value == null) {
            if ((p == null) || !vm.isInheritedProperty())
                result = vm.getDefaultValue();
        } else if ((p != null) && (value == InheritValue.INSTANCE)) {
            result = null;
        }
        if (result == null) {
            // Value is 'inherit' and p != null.
            // The pseudo class is not propagated.
            result = getComputedStyle(p, null, propidx);
            sm.putParentRelative(propidx, true);
            sm.putInherited     (propidx, true);
        } else {
            // Maybe is it a relative value.
            result = vm.computeValue(elt, pseudo, this, propidx,
                                     sm, result);
        }
        if (value == null) {
            sm.putValue(propidx, result);
            sm.putNullCascaded(propidx, true);
        } else if (result != value) {
            ComputedValue cv = new ComputedValue(value);
            cv.setComputedValue(result);
            sm.putValue(propidx, cv);
            result = cv;
        }

        sm.putComputed(propidx, true);
        return result;
    }

    /**
     * Returns the document CSSStyleSheetNodes in a list. This list is
     * updated as the document is modified.
     */
    public List getStyleSheetNodes() {
        if (styleSheetNodes == null) {
            styleSheetNodes = new ArrayList();
            selectorAttributes = new HashSet();
            // Find all the style-sheets in the document.
            findStyleSheetNodes(document);
            int len = styleSheetNodes.size();
            for (int i = 0; i < len; i++) {
                CSSStyleSheetNode ssn;
                ssn = (CSSStyleSheetNode)styleSheetNodes.get(i);
                StyleSheet ss = ssn.getCSSStyleSheet();
                if (ss != null) {
                    findSelectorAttributes(selectorAttributes, ss);
                }
            }
        }
        return styleSheetNodes;
    }

    /**
     * An auxiliary method for getStyleSheets().
     */
    protected void findStyleSheetNodes(Node n) {
        if (n instanceof CSSStyleSheetNode) {
            styleSheetNodes.add(n);
        }
        for (Node nd = getCSSFirstChild(n);
             nd != null;
             nd = getCSSNextSibling(nd)) {
            findStyleSheetNodes(nd);
        }
    }

    /**
     * Finds the selector attributes in the given stylesheet.
     */
    protected void findSelectorAttributes(Set attrs, StyleSheet ss) {
        int len = ss.getSize();
        for (int i = 0; i < len; i++) {
            Rule r = ss.getRule(i);
            switch (r.getType()) {
            case StyleRule.TYPE:
                StyleRule style = (StyleRule)r;
                SelectorList sl = style.getSelectorList();
                int slen = sl.getLength();
                for (int j = 0; j < slen; j++) {
                    ExtendedSelector s = (ExtendedSelector)sl.item(j);
                    s.fillAttributeSet(attrs);
                }
                break;

            case MediaRule.TYPE:
            case ImportRule.TYPE:
                MediaRule mr = (MediaRule)r;
                if (mediaMatch(mr.getMediaList())) {
                    findSelectorAttributes(attrs, mr);
                }
                break;
            }
        }
    }

    /**
     * Interface for people interesting in having 'primary' properties
     * set.  Shorthand properties will be expanded "automatically".
     */
    public interface MainPropertyReceiver {

        /**
         * Called with a non-shorthand property name and it's value.
         */
        public void setMainProperty(String name, Value v, boolean important);
    }

    public void setMainProperties
        (CSSStylableElement elt, final MainPropertyReceiver dst,
         String pname, String value, boolean important){
        try {
            element = elt;
            LexicalUnit lu = parser.parsePropertyValue(value);
            ShorthandManager.PropertyHandler ph =
                new ShorthandManager.PropertyHandler() {
                    public void property(String pname, LexicalUnit lu,
                                         boolean important) {
                        int idx = getPropertyIndex(pname);
                        if (idx != -1) {
                            ValueManager vm = valueManagers[idx];
                            Value v = vm.createValue(lu, CSSEngine.this);
                            dst.setMainProperty(pname, v, important);
                            return;
                        }
                        idx = getShorthandIndex(pname);
                        if (idx == -1)
                            return; // Unknown property...
                        // Shorthand value
                        shorthandManagers[idx].setValues
                            (CSSEngine.this, this, lu, important);
                    }
                };
            ph.property(pname, lu, important);
        } catch (Exception e) {
            String m = e.getMessage();
            if (m == null) m = "";                  // todo - better handling of NPE
            String u = ((documentURI == null)?"<unknown>":
                        documentURI.toString());
            String s = Messages.formatMessage
                ("property.syntax.error.at",
                 new Object[] { u, pname, value, m});
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
        } finally {
            element = null;
            cssBaseURI = null;
        }
    }

    /**
     * Parses and creates a property value from elt.
     * @param elt  The element property is from.
     * @param prop The property name.
     * @param value The property value.
     */
    public Value parsePropertyValue(CSSStylableElement elt,
                                    String prop, String value) {
        int idx = getPropertyIndex(prop);
        if (idx == -1) return null;
        ValueManager vm = valueManagers[idx];
        try {
            element = elt;
            LexicalUnit lu;
            lu = parser.parsePropertyValue(value);
            return vm.createValue(lu, this);
        } catch (Exception e) {
            String m = e.getMessage();
            if (m == null) m = "";
            String u = ((documentURI == null)?"<unknown>":
                        documentURI.toString());
            String s = Messages.formatMessage
                ("property.syntax.error.at",
                 new Object[] { u, prop, value, m });
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
        } finally {
            element = null;
            cssBaseURI = null;
        }
        return vm.getDefaultValue();
    }

    /**
     * Parses and creates a style declaration.
     * @param value The style declaration text.
     */
    public StyleDeclaration parseStyleDeclaration(CSSStylableElement elt,
                                                  String value) {
        styleDeclarationBuilder.styleDeclaration = new StyleDeclaration();
        try {
            element = elt;
            parser.setSelectorFactory(CSSSelectorFactory.INSTANCE);
            parser.setConditionFactory(cssConditionFactory);
            parser.setDocumentHandler(styleDeclarationBuilder);
            parser.parseStyleDeclaration(value);
        } catch (Exception e) {
            String m = e.getMessage();
            if (m == null) m = "";
            String u = ((documentURI == null)?"<unknown>":
                        documentURI.toString());
            String s = Messages.formatMessage
                ("syntax.error.at", new Object[] { u, m });
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
        } finally {
            element = null;
            cssBaseURI = null;
        }
        return styleDeclarationBuilder.styleDeclaration;
    }

    /**
     * Parses and creates a new style-sheet.
     * @param uri The style-sheet URI.
     * @param media The target media of the style-sheet.
     */
    public StyleSheet parseStyleSheet(URL uri, String media)
        throws DOMException {
        StyleSheet ss = new StyleSheet();
        try {
            ss.setMedia(parser.parseMedia(media));
        } catch (Exception e) {
            String m = e.getMessage();
            if (m == null) m = "";
            String u = ((documentURI == null)?"<unknown>":
                        documentURI.toString());
            String s = Messages.formatMessage
                ("syntax.error.at", new Object[] { u, m });
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
            return ss;
        }
        parseStyleSheet(ss, uri);
        return ss;
    }

    /**
     * Parses and creates a new style-sheet.
     * @param is The input source used to read the document.
     * @param uri The base URI.
     * @param media The target media of the style-sheet.
     */
    public StyleSheet parseStyleSheet(InputSource is, URL uri, String media)
        throws DOMException {
        StyleSheet ss = new StyleSheet();
        try {
            ss.setMedia(parser.parseMedia(media));
            parseStyleSheet(ss, is, uri);
        } catch (Exception e) {
            String m = e.getMessage();
            if (m == null) m = "";
            String u = ((documentURI == null)?"<unknown>":
                        documentURI.toString());
            String s = Messages.formatMessage
                ("syntax.error.at", new Object[] { u, m });
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
        }
        return ss;
    }

    /**
     * Parses and fills the given style-sheet.
     * @param ss The stylesheet to fill.
     * @param uri The base URI.
     */
    public void parseStyleSheet(StyleSheet ss, URL uri) throws DOMException {
        if (uri == null) {
            String s = Messages.formatMessage
                ("syntax.error.at",
                 new Object[] { "Null Document reference", "" });
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
            return;
        }

    try {
            // Check that access to the uri is allowed
             ParsedURL pDocURL = null;
             if (documentURI != null) {
                 pDocURL = new ParsedURL(documentURI);
             }
             ParsedURL pURL = new ParsedURL(uri);
             cssContext.checkLoadExternalResource(pURL, pDocURL);

             parseStyleSheet(ss, new InputSource(uri.toString()), uri);
    } catch (SecurityException e) {
            throw e;
        } catch (Exception e) {
            String m = e.getMessage();
            if (m == null) m = "";
            String s = Messages.formatMessage
                ("syntax.error.at", new Object[] { uri.toString(), m });
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
        }
    }

    /**
     * Parses and creates a new style-sheet.
     * @param rules The style-sheet rules to parse.
     * @param uri The style-sheet URI.
     * @param media The target media of the style-sheet.
     */
    public StyleSheet parseStyleSheet(String rules, URL uri, String media)
        throws DOMException {
        StyleSheet ss = new StyleSheet();
        try {
            ss.setMedia(parser.parseMedia(media));
        } catch (Exception e) {
            String m = e.getMessage();
            if (m == null) m = "";
            String u = ((documentURI == null)?"<unknown>":
                        documentURI.toString());
            String s = Messages.formatMessage
                ("syntax.error.at", new Object[] { u, m });
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
            return ss;
        }
        parseStyleSheet(ss, rules, uri);
        return ss;
    }

    /**
     * Parses and fills the given style-sheet.
     * @param ss The stylesheet to fill.
     * @param rules The style-sheet rules to parse.
     * @param uri The base URI.
     */
    public void parseStyleSheet(StyleSheet ss,
                                String rules,
                                URL uri) throws DOMException {
        try {
            parseStyleSheet(ss, new InputSource(new StringReader(rules)), uri);
        } catch (Exception e) {
            // e.printStackTrace();
            String m = e.getMessage();
            if (m == null) m = "";
            String s = Messages.formatMessage
                ("stylesheet.syntax.error",
                 new Object[] { uri.toString(), rules, m });
            DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
            if (userAgent == null) throw de;
            userAgent.displayError(de);
        }
    }

    /**
     * Parses and fills the given style-sheet.
     * @param ss The stylesheet to fill.
     * @param uri The base URI.
     */
    protected void parseStyleSheet(StyleSheet ss, InputSource is, URL uri)
        throws IOException {
        parser.setSelectorFactory(CSSSelectorFactory.INSTANCE);
        parser.setConditionFactory(cssConditionFactory);
        try {
            cssBaseURI = uri;
            styleSheetDocumentHandler.styleSheet = ss;
            parser.setDocumentHandler(styleSheetDocumentHandler);
            parser.parseStyleSheet(is);

            // Load the imported sheets.
            int len = ss.getSize();
            for (int i = 0; i < len; i++) {
                Rule r = ss.getRule(i);
                if (r.getType() != ImportRule.TYPE) {
                    // @import rules must be the first rules.
                    break;
                }
                ImportRule ir = (ImportRule)r;
                parseStyleSheet(ir, ir.getURI());
            }
        } finally {
            cssBaseURI = null;
        }
    }

    /**
     * Puts an author property from a style-map in another style-map,
     * if possible.
     */
    protected void putAuthorProperty(StyleMap dest,
                                     int idx,
                                     Value sval,
                                     boolean imp,
                                     short origin) {
        Value   dval = dest.getValue(idx);
        short   dorg = dest.getOrigin(idx);
        boolean dimp = dest.isImportant(idx);

        boolean cond = dval == null;
        if (!cond) {
            switch (dorg) {
            case StyleMap.USER_ORIGIN:
                cond = !dimp;
                break;
            case StyleMap.AUTHOR_ORIGIN:
                cond = !dimp || imp;
                break;
            case StyleMap.OVERRIDE_ORIGIN:
                cond = false;
                break;
            default:
                cond = true;
            }
        }

        if (cond) {
            dest.putValue(idx, sval);
            dest.putImportant(idx, imp);
            dest.putOrigin(idx, origin);
        }
    }

    /**
     * Adds the rules matching the element/pseudo-element of given style
     * sheet to the list.
     */
    protected void addMatchingRules(List rules,
                                    StyleSheet ss,
                                    Element elt,
                                    String pseudo) {
        int len = ss.getSize();
        for (int i = 0; i < len; i++) {
            Rule r = ss.getRule(i);
            switch (r.getType()) {
            case StyleRule.TYPE:
                StyleRule style = (StyleRule)r;
                SelectorList sl = style.getSelectorList();
                int slen = sl.getLength();
                for (int j = 0; j < slen; j++) {
                    ExtendedSelector s = (ExtendedSelector)sl.item(j);
                    if (s.match(elt, pseudo)) {
                        rules.add(style);
                    }
                }
                break;

            case MediaRule.TYPE:
            case ImportRule.TYPE:
                MediaRule mr = (MediaRule)r;
                if (mediaMatch(mr.getMediaList())) {
                    addMatchingRules(rules, mr, elt, pseudo);
                }
                break;
            }
        }
    }

    /**
     * Adds the rules contained in the given list to a stylemap.
     */
    protected void addRules(Element elt,
                            String pseudo,
                            StyleMap sm,
                            List rules,
                            short origin) {
        sortRules(rules, elt, pseudo);
        int rlen = rules.size();

        if (origin == StyleMap.AUTHOR_ORIGIN) {
            for (int r = 0; r < rlen; r++) {
                StyleRule sr = (StyleRule)rules.get(r);
                StyleDeclaration sd = sr.getStyleDeclaration();
                int len = sd.size();
                for (int i = 0; i < len; i++) {
                    putAuthorProperty(sm,
                                      sd.getIndex(i),
                                      sd.getValue(i),
                                      sd.getPriority(i),
                                      origin);
                }
            }
        } else {
            for (int r = 0; r < rlen; r++) {
                StyleRule sr = (StyleRule)rules.get(r);
                StyleDeclaration sd = sr.getStyleDeclaration();
                int len = sd.size();
                for (int i = 0; i < len; i++) {
                    int idx = sd.getIndex(i);
                    sm.putValue(idx, sd.getValue(i));
                    sm.putImportant(idx, sd.getPriority(i));
                    sm.putOrigin(idx, origin);
                }
            }
        }
    }

    /**
     * Sorts the rules matching the element/pseudo-element of given style
     * sheet to the list.
     */
    protected void sortRules(List rules, Element elt, String pseudo) {
        int len = rules.size();
        for (int i = 0; i < len - 1; i++) {
            int idx = i;
            int min = Integer.MAX_VALUE;
            for (int j = i; j < len; j++) {
                StyleRule r = (StyleRule)rules.get(j);
                SelectorList sl = r.getSelectorList();
                int spec = 0;
                int slen = sl.getLength();
                for (int k = 0; k < slen; k++) {
                    ExtendedSelector s = (ExtendedSelector)sl.item(k);
                    if (s.match(elt, pseudo)) {
                        int sp = s.getSpecificity();
                        if (sp > spec) {
                            spec = sp;
                        }
                    }
                }
                if (spec < min) {
                    min = spec;
                    idx = j;
                }
            }
            if (i != idx) {
                Object tmp = rules.get(i);
                rules.set(i, rules.get(idx));
                rules.set(idx, tmp);
            }
        }
    }

    /**
     * Whether the given media list matches the media list of this
     * CSSEngine object.
     */
    protected boolean mediaMatch(SACMediaList ml) {
    if (media == null ||
            ml == null ||
            media.getLength() == 0 ||
            ml.getLength() == 0) {
        return true;
    }
    for (int i = 0; i < ml.getLength(); i++) {
            if (ml.item(i).equalsIgnoreCase("all"))
                return true;
        for (int j = 0; j < media.getLength(); j++) {
        if (media.item(j).equalsIgnoreCase("all") ||
                    ml.item(i).equalsIgnoreCase(media.item(j))) {
            return true;
        }
        }
    }
    return false;
    }

    /**
     * To parse a style declaration.
     */
    protected class StyleDeclarationDocumentHandler
        extends DocumentAdapter
        implements ShorthandManager.PropertyHandler {
        public StyleMap styleMap;

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#property(String,LexicalUnit,boolean)}.
         */
        public void property(String name, LexicalUnit value, boolean important)
            throws CSSException {
            int i = getPropertyIndex(name);
            if (i == -1) {
                i = getShorthandIndex(name);
                if (i == -1) {
                    // Unknown property
                    return;
                }
                shorthandManagers[i].setValues(CSSEngine.this,
                                               this,
                                               value,
                                               important);
            } else {
                Value v = valueManagers[i].createValue(value, CSSEngine.this);
                putAuthorProperty(styleMap, i, v, important,
                                  StyleMap.INLINE_AUTHOR_ORIGIN);
            }
        }
    }

    /**
     * To build a StyleDeclaration object.
     */
    protected class StyleDeclarationBuilder
        extends DocumentAdapter
        implements ShorthandManager.PropertyHandler {
        public StyleDeclaration styleDeclaration;

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#property(String,LexicalUnit,boolean)}.
         */
        public void property(String name, LexicalUnit value, boolean important)
            throws CSSException {
            int i = getPropertyIndex(name);
            if (i == -1) {
                i = getShorthandIndex(name);
                if (i == -1) {
                    // Unknown property
                    return;
                }
                shorthandManagers[i].setValues(CSSEngine.this,
                                               this,
                                               value,
                                               important);
            } else {
                Value v = valueManagers[i].createValue(value, CSSEngine.this);
                styleDeclaration.append(v, i, important);
            }
        }
    }

    /**
     * To parse a style sheet.
     */
    protected class StyleSheetDocumentHandler
        extends DocumentAdapter
        implements ShorthandManager.PropertyHandler {
        public StyleSheet styleSheet;
        protected StyleRule styleRule;
        protected StyleDeclaration styleDeclaration;

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#startDocument(InputSource)}.
         */
        public void startDocument(InputSource source)
            throws CSSException {
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#endDocument(InputSource)}.
         */
        public void endDocument(InputSource source) throws CSSException {
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#ignorableAtRule(String)}.
         */
        public void ignorableAtRule(String atRule) throws CSSException {
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#importStyle(String,SACMediaList,String)}.
         */
        public void importStyle(String       uri,
                                SACMediaList media,
                                String       defaultNamespaceURI)
            throws CSSException {
            ImportRule ir = new ImportRule();
            ir.setMediaList(media);
            ir.setParent(styleSheet);
            try {
                URL base = getCSSBaseURI();
                URL url;
                if (base == null) url = new URL(uri);
                else              url = new URL(base, uri);
                ir.setURI(url);
            } catch (MalformedURLException e) {
            }
            styleSheet.append(ir);
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#startMedia(SACMediaList)}.
         */
        public void startMedia(SACMediaList media) throws CSSException {
            MediaRule mr = new MediaRule();
            mr.setMediaList(media);
            mr.setParent(styleSheet);
            styleSheet.append(mr);
            styleSheet = mr;
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#endMedia(SACMediaList)}.
         */
        public void endMedia(SACMediaList media) throws CSSException {
            styleSheet = styleSheet.getParent();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#startPage(String,String)}.
         */
        public void startPage(String name, String pseudo_page)
            throws CSSException {
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#endPage(String,String)}.
         */
        public void endPage(String name, String pseudo_page)
            throws CSSException {
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#startFontFace()}.
         */
        public void startFontFace() throws CSSException {
            styleDeclaration = new StyleDeclaration();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#endFontFace()}.
         */
        public void endFontFace() throws CSSException {
            StyleMap sm = new StyleMap(getNumberOfProperties());
            int len = styleDeclaration.size();
            for (int i=0; i<len; i++) {
                int idx = styleDeclaration.getIndex(i);
                sm.putValue(idx, styleDeclaration.getValue(i));
                sm.putImportant(idx, styleDeclaration.getPriority(i));
                // Not sure on this..
                sm.putOrigin(idx, StyleMap.AUTHOR_ORIGIN);
            }
            styleDeclaration = null;

            int pidx = getPropertyIndex(CSSConstants.CSS_FONT_FAMILY_PROPERTY);
            Value fontFamily = sm.getValue(pidx);
            if (fontFamily == null) return;

            URL base = getCSSBaseURI();
            ParsedURL purl = null;
            if (base != null) purl = new ParsedURL(base);
            fontFaces.add(new FontFaceRule(sm, purl));
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#startSelector(SelectorList)}.
         */
        public void startSelector(SelectorList selectors) throws CSSException {
            styleRule = new StyleRule();
            styleRule.setSelectorList(selectors);
            styleDeclaration = new StyleDeclaration();
            styleRule.setStyleDeclaration(styleDeclaration);
            styleSheet.append(styleRule);
        }

        /**
         * <b>SAC</b>: Implements {@link
         * org.w3c.css.sac.DocumentHandler#endSelector(SelectorList)}.
         */
        public void endSelector(SelectorList selectors) throws CSSException {
            styleRule = null;
            styleDeclaration = null;
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#property(String,LexicalUnit,boolean)}.
         */
        public void property(String name, LexicalUnit value, boolean important)
            throws CSSException {
            int i = getPropertyIndex(name);
            if (i == -1) {
                i = getShorthandIndex(name);
                if (i == -1) {
                    // Unknown property
                    return;
                }
                shorthandManagers[i].setValues(CSSEngine.this,
                                               this,
                                               value,
                                               important);
            } else {
                Value v = valueManagers[i].createValue(value, CSSEngine.this);
                styleDeclaration.append(v, i, important);
            }
        }
    }

    /**
     * Provides an (empty) adapter for the DocumentHandler interface.
     * Most methods just throw an UnsupportedOperationException, so
     * the subclasses <i>must</i> override them with 'real' methods.
     */
    protected static class DocumentAdapter implements DocumentHandler {

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#startDocument(InputSource)}.
         */
        public void startDocument(InputSource source){
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#endDocument(InputSource)}.
         */
        public void endDocument(InputSource source) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#comment(String)}.
         */
        public void comment(String text) {
            // We always ignore the comments.
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#ignorableAtRule(String)}.
         */
        public void ignorableAtRule(String atRule) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#namespaceDeclaration(String,String)}.
         */
        public void namespaceDeclaration(String prefix, String uri) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#importStyle(String,SACMediaList,String)}.
         */
        public void importStyle(String       uri,
                                SACMediaList media,
                                String       defaultNamespaceURI) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#startMedia(SACMediaList)}.
         */
        public void startMedia(SACMediaList media) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#endMedia(SACMediaList)}.
         */
        public void endMedia(SACMediaList media) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#startPage(String,String)}.
         */
        public void startPage(String name, String pseudo_page) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#endPage(String,String)}.
         */
        public void endPage(String name, String pseudo_page) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link DocumentHandler#startFontFace()}.
         */
        public void startFontFace() {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link DocumentHandler#endFontFace()}.
         */
        public void endFontFace() {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#startSelector(SelectorList)}.
         */
        public void startSelector(SelectorList selectors) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#endSelector(SelectorList)}.
         */
        public void endSelector(SelectorList selectors) {
            throwUnsupportedEx();
        }

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#property(String,LexicalUnit,boolean)}.
         */
        public void property(String name, LexicalUnit value, boolean important) {
            throwUnsupportedEx();
        }


        private void throwUnsupportedEx(){
            throw new UnsupportedOperationException("you try to use an empty method in Adapter-class" );
        }
    }

    // CSS events /////////////////////////////////////////////////////////

    protected final static CSSEngineListener[] LISTENER_ARRAY =
        new CSSEngineListener[0];

    /**
     * Adds a CSS engine listener.
     */
    public void addCSSEngineListener(CSSEngineListener l) {
        listeners.add(l);
    }

    /**
     * Removes a CSS engine listener.
     */
    public void removeCSSEngineListener(CSSEngineListener l) {
        listeners.remove(l);
    }

    /**
     * Fires a CSSEngineEvent, given a list of modified properties.
     */
    protected void firePropertiesChangedEvent(Element target, int[] props) {
        CSSEngineListener[] ll =
            (CSSEngineListener[])listeners.toArray(LISTENER_ARRAY);

        int len = ll.length;
        if (len > 0) {
            CSSEngineEvent evt = new CSSEngineEvent(this, target, props);
            for (int i = 0; i < len; i++) {
                ll[i].propertiesChanged(evt);
            }
        }
    }

    // Dynamic updates ////////////////////////////////////////////////////

    /**
     * Called when the inline style of the given element has been updated.
     */
    protected void inlineStyleAttributeUpdated(CSSStylableElement elt,
                                               StyleMap style,
                                               short attrChange,
                                               String prevValue,
                                               String newValue) {
        boolean[] updated = styleDeclarationUpdateHandler.updatedProperties;
        for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
            updated[i] = false;
        }

        switch (attrChange) {
        case MutationEvent.ADDITION:            // intentional fall-through
        case MutationEvent.MODIFICATION:
            if (newValue.length() > 0) {
                element = elt;
                try {
                    parser.setSelectorFactory(CSSSelectorFactory.INSTANCE);
                    parser.setConditionFactory(cssConditionFactory);
                    styleDeclarationUpdateHandler.styleMap = style;
                    parser.setDocumentHandler(styleDeclarationUpdateHandler);
                    parser.parseStyleDeclaration(newValue);
                    styleDeclarationUpdateHandler.styleMap = null;
                } catch (Exception e) {
                    String m = e.getMessage();
                    if (m == null) m = "";
                    String u = ((documentURI == null)?"<unknown>":
                                documentURI.toString());
                    String s = Messages.formatMessage
                        ("style.syntax.error.at",
                         new Object[] { u, styleLocalName, newValue, m });
                    DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
                    if (userAgent == null) throw de;
                    userAgent.displayError(de);
                } finally {
                    element = null;
                    cssBaseURI = null;
                }
            }

            // Fall through
        case MutationEvent.REMOVAL:
            boolean removed = false;

            if (prevValue != null && prevValue.length() > 0) {
                // Check if the style map has cascaded styles which
                // come from the inline style attribute or override style.
                for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
                    if (style.isComputed(i) && !updated[i]) {
                        short origin = style.getOrigin(i);
                        if (origin >= StyleMap.INLINE_AUTHOR_ORIGIN) {
                            removed = true;
                            updated[i] = true;
                        }
                    }
                }
            }

            if (removed) {
                invalidateProperties(elt, null, updated, true);
            } else {
                int count = 0;
                // Invalidate the relative values
                boolean fs = (fontSizeIndex == -1)
                    ? false
                    : updated[fontSizeIndex];
                boolean lh = (lineHeightIndex == -1)
                    ? false
                    : updated[lineHeightIndex];
                boolean cl = (colorIndex == -1)
                    ? false
                    : updated[colorIndex];

                for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
                    if (updated[i]) {
                        count++;
                    }
                    else if ((fs && style.isFontSizeRelative(i)) ||
                             (lh && style.isLineHeightRelative(i)) ||
                             (cl && style.isColorRelative(i))) {
                        updated[i] = true;
                        clearComputedValue(style, i);
                        count++;
                    }
                }

                if (count > 0) {
                    int[] props = new int[count];
                    count = 0;
                    for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
                        if (updated[i]) {
                            props[count++] = i;
                        }
                    }
                    invalidateProperties(elt, props, null, true);
                }
            }
            break;

        default:
            // Must not happen
            throw new IllegalStateException("Invalid attrChangeType");
        }
    }

    private static void clearComputedValue(StyleMap style, int n) {
        if (style.isNullCascaded(n)) {
            style.putValue(n, null);
        } else {
            Value v = style.getValue(n);
            if (v instanceof ComputedValue) {
                ComputedValue cv = (ComputedValue)v;
                v = cv.getCascadedValue();
                style.putValue(n, v);
            }
        }
        style.putComputed(n, false);
    }

    /**
     * Invalidates all the properties of the given node.
     */
    protected void invalidateProperties(Node node,
                                        int [] properties,
                                        boolean [] updated,
                                        boolean recascade) {

        if (!(node instanceof CSSStylableElement))
            return;  // Not Stylable sub tree

        CSSStylableElement elt = (CSSStylableElement)node;
        StyleMap style = elt.getComputedStyleMap(null);
        if (style == null)
            return;  // Nothing to invalidate.

        boolean [] diffs = new boolean[getNumberOfProperties()];
        if (updated != null) {
            System.arraycopy( updated, 0, diffs, 0, updated.length );
        }
        if (properties != null) {
            for (int i=0; i<properties.length; i++) {
                diffs[properties[i]] = true;
            }
        }
        int count =0;
        if (!recascade) {
            for (int i=0; i<diffs.length; i++) {
                if (diffs[i]) {
                    count++;
                }
            }
        } else {
            StyleMap newStyle = getCascadedStyleMap(elt, null);
            elt.setComputedStyleMap(null, newStyle);
            for (int i=0; i<diffs.length; i++) {
                if (diffs[i]) {
                    count++;
                    continue; // Already marked changed.
                }

                // Value nv = getComputedStyle(elt, null, i);
                Value nv = newStyle.getValue(i);
                Value ov = null;
                if (!style.isNullCascaded(i)) {
                    ov = style.getValue(i);
                    if (ov instanceof ComputedValue) {
                        ov = ((ComputedValue)ov).getCascadedValue();
                    }
                }

                if (nv == ov) continue;
                if ((nv != null) && (ov != null)) {
                    if (nv.equals(ov)) continue;
                    String ovCssText = ov.getCssText();
                    String nvCssText = nv.getCssText();
                    if ((nvCssText == ovCssText) ||
                        ((nvCssText != null) && nvCssText.equals(ovCssText)))
                        continue;
                }
                count++;
                diffs[i] = true;
            }
        }
        int []props = null;
        if (count != 0) {
            props = new int[count];
            count = 0;
            for (int i=0; i<diffs.length; i++) {
                if (diffs[i])
                    props[count++] = i;
            }
        }
        propagateChanges(elt, props, recascade);
    }

    /**
     * Propagates the changes that occurs on the parent of the given node.
     * Props is a list of known 'changed' properties.
     * If recascade is true then the stylesheets will be applied
     * again to see if the any new rules apply (or old rules don't
     * apply).
     */
    protected void propagateChanges(Node node, int[] props,
                                    boolean recascade) {
        if (!(node instanceof CSSStylableElement))
            return;
        CSSStylableElement elt = (CSSStylableElement)node;
        StyleMap style = elt.getComputedStyleMap(null);
        if (style != null) {
            boolean[] updated =
                styleDeclarationUpdateHandler.updatedProperties;
            for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
                updated[i] = false;
            }
            if (props != null) {
                for (int i = props.length - 1; i >= 0; --i) {
                    int idx = props[i];
                    updated[idx] = true;
                }
            }

            // Invalidate the relative values
            boolean fs = (fontSizeIndex == -1)
                ? false
                : updated[fontSizeIndex];
            boolean lh = (lineHeightIndex == -1)
                ? false
                : updated[lineHeightIndex];
            boolean cl = (colorIndex == -1)
                ? false
                : updated[colorIndex];

            int count = 0;
            for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
                if (updated[i]) {
                    count++;
                }
                else if ((fs && style.isFontSizeRelative(i)) ||
                         (lh && style.isLineHeightRelative(i)) ||
                         (cl && style.isColorRelative(i))) {
                    updated[i] = true;
                    clearComputedValue(style, i);
                    count++;
                }
            }

            if (count == 0) {
                props = null;
            } else {
                props = new int[count];
                count = 0;
                for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
                    if (updated[i]) {
                        props[count++] = i;
                    }
                }
                firePropertiesChangedEvent(elt, props);
            }
        }

        int [] inherited = props;
        if (props != null) {
            // Filter out uninheritable properties when we
            // propogate to children.
            int count = 0;
            for (int i=0; i<props.length; i++) {
                ValueManager vm = valueManagers[props[i]];
                if (vm.isInheritedProperty()) count++;
                else props[i] = -1;
            }

            if (count == 0) {
                // nothing to propogate for sure
                inherited = null;
            } else {
                inherited = new int[count];
                count=0;
                for (int i=0; i<props.length; i++)
                    if (props[i] != -1)
                        inherited[count++] = props[i];
            }
        }

        for (Node n = getCSSFirstChild(node);
             n != null;
             n = getCSSNextSibling(n)) {
            if (n.getNodeType() == Node.ELEMENT_NODE) {
                // XXX Should this invalidateProperties be called on eng?
                // In r216064 with CSSImportedElementRoot, the imported
                // element's CSSEngine was indeed used.
                // CSSEngine eng = cssContext.getCSSEngineForElement((Element) n);
                invalidateProperties(n, inherited, null, recascade);
            }
        }
    }

    /**
     * To parse a style declaration and update a StyleMap.
     */
    protected class StyleDeclarationUpdateHandler
        extends DocumentAdapter
        implements ShorthandManager.PropertyHandler {
        public StyleMap styleMap;
        public boolean[] updatedProperties =
            new boolean[getNumberOfProperties()];

        /**
         * <b>SAC</b>: Implements {@link
         * DocumentHandler#property(String,LexicalUnit,boolean)}.
         */
        public void property(String name, LexicalUnit value, boolean important)
            throws CSSException {
            int i = getPropertyIndex(name);
            if (i == -1) {
                i = getShorthandIndex(name);
                if (i == -1) {
                    // Unknown property
                    return;
                }
                shorthandManagers[i].setValues(CSSEngine.this,
                                               this,
                                               value,
                                               important);
            } else {
                if (styleMap.isImportant(i)) {
                    // The previous value is important, and a value
                    // from a style attribute cannot be important...
                    return;
                }

                updatedProperties[i] = true;

                Value v = valueManagers[i].createValue(value, CSSEngine.this);
                styleMap.putMask(i, (short)0);
                styleMap.putValue(i, v);
                styleMap.putOrigin(i, StyleMap.INLINE_AUTHOR_ORIGIN);
            }
        }
    }

    /**
     * Called when a non-CSS presentational hint has been updated.
     */
    protected void nonCSSPresentationalHintUpdated(CSSStylableElement elt,
                                                   StyleMap style,
                                                   String property,
                                                   short attrChange,
                                                   String newValue) {
        int idx = getPropertyIndex(property);

        if (style.isImportant(idx)) {
            // The current value is important, and a value
            // from an XML attribute cannot be important...
            return;
        }

        if (style.getOrigin(idx) >= StyleMap.AUTHOR_ORIGIN) {
            // The current value has a greater priority
            return;
        }

        switch (attrChange) {
        case MutationEvent.ADDITION:   // intentional fall-through
        case MutationEvent.MODIFICATION:
            element = elt;
            try {
                LexicalUnit lu;
                lu = parser.parsePropertyValue(newValue);
                ValueManager vm = valueManagers[idx];
                Value v = vm.createValue(lu, CSSEngine.this);
                style.putMask(idx, (short)0);
                style.putValue(idx, v);
                style.putOrigin(idx, StyleMap.NON_CSS_ORIGIN);
            } catch (Exception e) {
                String m = e.getMessage();
                if (m == null) m = "";
                String u = ((documentURI == null)?"<unknown>":
                            documentURI.toString());
                String s = Messages.formatMessage
                    ("property.syntax.error.at",
                     new Object[] { u, property, newValue, m });
                DOMException de = new DOMException(DOMException.SYNTAX_ERR, s);
                if (userAgent == null) throw de;
                userAgent.displayError(de);
            } finally {
                element = null;
                cssBaseURI = null;
            }
            break;

        case MutationEvent.REMOVAL:
            {
                int [] invalid = { idx };
                invalidateProperties(elt, invalid, null, true);
                return;
            }
        }

        boolean[] updated = styleDeclarationUpdateHandler.updatedProperties;
        for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
            updated[i] = false;
        }
        updated[idx] = true;

        // Invalidate the relative values
        boolean fs = idx == fontSizeIndex;
        boolean lh = idx == lineHeightIndex;
        boolean cl = idx == colorIndex;
        int count = 0;

        for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
            if (updated[i]) {
                count++;
            }
            else if ((fs && style.isFontSizeRelative(i)) ||
                     (lh && style.isLineHeightRelative(i)) ||
                     (cl && style.isColorRelative(i))) {
                updated[i] = true;
                clearComputedValue(style, i);
                count++;
            }
        }

        int[] props = new int[count];
        count = 0;
        for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
            if (updated[i]) {
                props[count++] = i;
            }
        }

        invalidateProperties(elt, props, null, true);
    }

    /**
     * Returns whether the DOM subtree rooted at the specified node
     * contains a {@link CSSStyleSheetNode}.
     */
    protected boolean hasStyleSheetNode(Node n) {
        if (n instanceof CSSStyleSheetNode) {
            return true;
        }
        n = getCSSFirstChild(n);
        while (n != null) {
            if (hasStyleSheetNode(n)) {
                return true;
            }
            n = getCSSNextSibling(n);
        }
        return false;
    }

    /**
     * Handles an attribute change in the document.
     */
    protected void handleAttrModified(Element e,
                                      Attr attr,
                                      short attrChange,
                                      String prevValue,
                                      String newValue) {
        if (!(e instanceof CSSStylableElement)) {
            // Not a stylable element.
            return;
        }

        if (newValue.equals(prevValue)) {
            return;  // no change really...
        }

        String attrNS = attr.getNamespaceURI();
        String name = attrNS == null ? attr.getNodeName() : attr.getLocalName();

        CSSStylableElement elt = (CSSStylableElement) e;
        StyleMap style = elt.getComputedStyleMap(null);
        if (style != null) {
            if (attrNS == styleNamespaceURI
                    || attrNS != null && attrNS.equals(styleNamespaceURI)) {
                if (name.equals(styleLocalName)) {
                    // The style declaration attribute has been modified.
                    inlineStyleAttributeUpdated
                        (elt, style, attrChange, prevValue, newValue);
                    return;
                }
            }

            if (nonCSSPresentationalHints != null) {
                if (attrNS == nonCSSPresentationalHintsNamespaceURI ||
                        attrNS != null &&
                        attrNS.equals(nonCSSPresentationalHintsNamespaceURI)) {
                    if (nonCSSPresentationalHints.contains(name)) {
                        // The 'name' attribute which represents a non CSS
                        // presentational hint has been modified.
                        nonCSSPresentationalHintUpdated
                            (elt, style, name, attrChange, newValue);
                        return;
                    }
                }
            }
        }

        if (selectorAttributes != null &&
            selectorAttributes.contains(name)) {
            // An attribute has been modified, invalidate all the
            // properties to correctly match attribute selectors.
            invalidateProperties(elt, null, null, true);
            for (Node n = getCSSNextSibling(elt);
                 n != null;
                 n = getCSSNextSibling(n)) {
                invalidateProperties(n, null, null, true);
            }
        }
    }

    /**
     * Handles a node insertion in the document.
     */
    protected void handleNodeInserted(Node n) {
        if (hasStyleSheetNode(n)) {
            // Invalidate all the CSSStylableElements in the document.
            styleSheetNodes = null;
            invalidateProperties(document.getDocumentElement(),
                                 null, null, true);
        } else if (n instanceof CSSStylableElement) {
            // Invalidate the CSSStylableElement siblings, to correctly
            // match the adjacent selectors and first-child pseudo-class.
            n = getCSSNextSibling(n);
            while (n != null) {
                invalidateProperties(n, null, null, true);
                n = getCSSNextSibling(n);
            }
        }
    }

    /**
     * Handles a node removal from the document.
     */
    protected void handleNodeRemoved(Node n) {
        if (hasStyleSheetNode(n)) {
            // Wait for the DOMSubtreeModified to do the invalidations
            // because at this time the node is in the tree.
            styleSheetRemoved = true;
        } else if (n instanceof CSSStylableElement) {
            // Wait for the DOMSubtreeModified to do the invalidations
            // because at this time the node is in the tree.
            removedStylableElementSibling = getCSSNextSibling(n);
        }
        // Clears the computed styles in the removed tree.
        disposeStyleMaps(n);
    }

    /**
     * Handles a subtree modification in the document.
     */
    protected void handleSubtreeModified(Node n) {
        if (styleSheetRemoved) {
            // Invalidate all the CSSStylableElements in the document.
            styleSheetRemoved = false;
            styleSheetNodes = null;
            invalidateProperties(document.getDocumentElement(),
                                 null, null, true);
        } else if (removedStylableElementSibling != null) {
            // Invalidate the CSSStylableElement siblings, to
            // correctly match the adjacent selectors and
            // first-child pseudo-class.
            n = removedStylableElementSibling;
            while (n != null) {
                invalidateProperties(n, null, null, true);
                n = getCSSNextSibling(n);
            }
            removedStylableElementSibling = null;
        }
    }

    /**
     * Handles a character data modification in the document.
     */
    protected void handleCharacterDataModified(Node n) {
        if (getCSSParentNode(n) instanceof CSSStyleSheetNode) {
            // Invalidate all the CSSStylableElements in the document.
            styleSheetNodes = null;
            invalidateProperties(document.getDocumentElement(),
                                 null, null, true);
        }
    }

    /**
     * To handle mutations of a CSSNavigableDocument.
     */
    protected class CSSNavigableDocumentHandler
            implements CSSNavigableDocumentListener,
                       MainPropertyReceiver {

        /**
         * Array to hold which properties have been changed by a call to
         * setMainProperties.
         */
        protected boolean[] mainPropertiesChanged;

        /**
         * The StyleDeclaration to use from the MainPropertyReceiver.
         */
        protected StyleDeclaration declaration;

        /**
         * A node has been inserted into the CSSNavigableDocument tree.
         */
        public void nodeInserted(Node newNode) {
            handleNodeInserted(newNode);
        }

        /**
         * A node is about to be removed from the CSSNavigableDocument tree.
         */
        public void nodeToBeRemoved(Node oldNode) {
            handleNodeRemoved(oldNode);
        }

        /**
         * A subtree of the CSSNavigableDocument tree has been modified
         * in some way.
         */
        public void subtreeModified(Node rootOfModifications) {
            handleSubtreeModified(rootOfModifications);
        }

        /**
         * Character data in the CSSNavigableDocument tree has been modified.
         */
        public void characterDataModified(Node text) {
            handleCharacterDataModified(text);
        }

        /**
         * An attribute has changed in the CSSNavigableDocument.
         */
        public void attrModified(Element e,
                                 Attr attr,
                                 short attrChange,
                                 String prevValue,
                                 String newValue) {
            handleAttrModified(e, attr, attrChange, prevValue, newValue);
        }

        /**
         * The text of the override style declaration for this element has been
         * modified.
         */
        public void overrideStyleTextChanged(CSSStylableElement elt,
                                             String text) {
            StyleDeclarationProvider p =
                elt.getOverrideStyleDeclarationProvider();
            StyleDeclaration declaration = p.getStyleDeclaration();
            int ds = declaration.size();
            boolean[] updated = new boolean[getNumberOfProperties()];
            for (int i = 0; i < ds; i++) {
                updated[declaration.getIndex(i)] = true;
            }
            declaration = parseStyleDeclaration(elt, text);
            p.setStyleDeclaration(declaration);
            ds = declaration.size();
            for (int i = 0; i < ds; i++) {
                updated[declaration.getIndex(i)] = true;
            }
            invalidateProperties(elt, null, updated, true);
        }

        /**
         * A property in the override style declaration has been removed.
         */
        public void overrideStylePropertyRemoved(CSSStylableElement elt,
                                                 String name) {
            StyleDeclarationProvider p =
                elt.getOverrideStyleDeclarationProvider();
            StyleDeclaration declaration = p.getStyleDeclaration();
            int idx = getPropertyIndex(name);
            int ds = declaration.size();
            for (int i = 0; i < ds; i++) {
                if (idx == declaration.getIndex(i)) {
                    declaration.remove(i);
                    StyleMap style = elt.getComputedStyleMap(null);
                    if (style.getOrigin(idx) == StyleMap.OVERRIDE_ORIGIN
                            && style.isComputed(idx)) {
                        invalidateProperties
                            (elt, new int[] { idx }, null, true);
                    }
                    break;
                }
            }
        }

        /**
         * A property in the override style declaration has been changed.
         */
        public void overrideStylePropertyChanged(CSSStylableElement elt,
                                                 String name, String val,
                                                 String prio) {
            boolean important = prio != null && prio.length() != 0;
            StyleDeclarationProvider p =
                elt.getOverrideStyleDeclarationProvider();
            declaration = p.getStyleDeclaration();
            setMainProperties(elt, this, name, val, important);
            declaration = null;
            invalidateProperties(elt, null, mainPropertiesChanged, true);
        }

        // MainPropertyReceiver //////////////////////////////////////////////

        /**
         * Sets a main property value in response to a shorthand property
         * being set.
         */
        public void setMainProperty(String name, Value v, boolean important) {
            int idx = getPropertyIndex(name);
            if (idx == -1) {
                return;   // unknown property
            }

            int i;
            for (i = 0; i < declaration.size(); i++) {
                if (idx == declaration.getIndex(i)) {
                    break;
                }
            }
            if (i < declaration.size()) {
                declaration.put(i, v, idx, important);
            } else {
                declaration.append(v, idx, important);
            }
        }
    }

    /**
     * To handle the insertion of a CSSStyleSheetNode in the
     * associated document.
     */
    protected class DOMNodeInsertedListener implements EventListener {
        public void handleEvent(Event evt) {
            handleNodeInserted((Node) evt.getTarget());
        }
    }

    /**
     * To handle the removal of a CSSStyleSheetNode from the
     * associated document.
     */
    protected class DOMNodeRemovedListener implements EventListener {
        public void handleEvent(Event evt) {
            handleNodeRemoved((Node) evt.getTarget());
        }
    }

    /**
     * To handle the removal of a CSSStyleSheetNode from the
     * associated document.
     */
    protected class DOMSubtreeModifiedListener implements EventListener {
        public void handleEvent(Event evt) {
            handleSubtreeModified((Node) evt.getTarget());
        }
    }

    /**
     * To handle the modification of a CSSStyleSheetNode.
     */
    protected class DOMCharacterDataModifiedListener implements EventListener {
        public void handleEvent(Event evt) {
            handleCharacterDataModified((Node) evt.getTarget());
        }
    }

    /**
     * To handle the element attributes modification in the associated
     * document.
     */
    protected class DOMAttrModifiedListener implements EventListener {
        public void handleEvent(Event evt) {
            MutationEvent mevt = (MutationEvent) evt;
            handleAttrModified((Element) evt.getTarget(),
                               (Attr) mevt.getRelatedNode(),
                               mevt.getAttrChange(),
                               mevt.getPrevValue(),
                               mevt.getNewValue());
        }
    }
}
