/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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.swing.svg;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JOptionPane;

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.BridgeException;
import org.apache.batik.bridge.BridgeExtension;
import org.apache.batik.bridge.DefaultScriptSecurity;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.ErrorConstants;
import org.apache.batik.bridge.ExternalResourceSecurity;
import org.apache.batik.bridge.RelaxedExternalResourceSecurity;
import org.apache.batik.bridge.ScriptSecurity;
import org.apache.batik.bridge.UpdateManager;
import org.apache.batik.bridge.UpdateManagerEvent;
import org.apache.batik.bridge.UpdateManagerListener;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.ViewBox;
import org.apache.batik.bridge.svg12.SVG12BridgeContext;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.batik.dom.util.DOMUtilities;
import org.apache.batik.dom.util.XLinkSupport;
import org.apache.batik.ext.awt.image.spi.ImageTagRegistry;
import org.apache.batik.gvt.CanvasGraphicsNode;
import org.apache.batik.gvt.CompositeGraphicsNode;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.event.EventDispatcher;
import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.batik.gvt.renderer.ImageRenderer;
import org.apache.batik.gvt.text.Mark;
import org.apache.batik.script.Interpreter;
import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
import org.apache.batik.swing.gvt.JGVTComponent;
import org.apache.batik.swing.gvt.JGVTComponentListener;
import org.apache.batik.util.ParsedURL;
import org.apache.batik.util.RunnableQueue;
import org.apache.batik.util.SVGConstants;
import org.apache.batik.util.SVGFeatureStrings;
import org.apache.batik.util.XMLResourceDescriptor;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGAElement;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;

/**
 * This class represents a swing component that can display SVG documents. This
 * component also lets you translate, zoom and rotate the document being
 * displayed. This is the fundamental class for rendering SVG documents in a
 * swing application.
 *
 * <h2>Rendering Process</h2>
 *
 * <p>The rendering process can be broken down into five phases. Not all of
 * those steps are required - depending on the method used to specify the SVG
 * document to display, but basically the steps in the rendering process
 * are:</p>
 *
 * <ol>
 *
 * <li><b>Building a DOM tree</b>
 *
 * <blockquote>If the <code>{@link #loadSVGDocument(String)}</code> method is used,
 * the SVG file is parsed and an SVG DOM Tree is built.</blockquote></li>
 *
 * <li><b>Building a GVT tree</b>
 *
 * <blockquote>Once an SVGDocument is created (using the step 1 or if the
 * <code>{@link #setSVGDocument(SVGDocument)}</code> method has been used) - a GVT
 * tree is constructed. The GVT tree is the data structure used internally to
 * render an SVG document. see the <code>{@link org.apache.batik.gvt}
 * package.</code></blockquote></li>
 *
 * <li><b>Executing the SVGLoad event handlers</b>
 *
 * <blockquote>
 *    If the document is dynamic, the scripts are initialized and the
 *    SVGLoad event is dispatched before the initial rendering.
 * </blockquote></li>
 *
 * <li><b>Rendering the GVT tree</b>
 *
 * <blockquote>Then the GVT tree is rendered. see the <code>{@link
 * org.apache.batik.gvt.renderer}</code> package.</blockquote></li>
 *
 * <li><b>Running the document</b>
 *
 * <blockquote>
 *    If the document is dynamic, the update threads are started.
 * </blockquote></li>
 *
 * </ol>
 *
 * <p>Those steps are performed in a separate thread. To be notified to what
 * happens and eventually perform some operations - such as resizing the window
 * to the size of the document or get the SVGDocument built via a URI, five
 * different listeners are provided (one per step):
 * <code>{@link SVGDocumentLoaderListener}</code>,
 * <code>{@link GVTTreeBuilderListener}</code>,
 * <code>{@link SVGLoadEventDispatcherListener}</code>,
 * <code>{@link org.apache.batik.swing.gvt.GVTTreeRendererListener}</code>,
 * <code>{@link org.apache.batik.bridge.UpdateManagerListener}</code>.</p>
 *
 * <p>Each listener has methods to be notified of the start of a phase,
 *    and methods to be notified of the end of a phase.
 *    A phase cannot start before the preceding has finished.</p>
 *
 * <p>The following example shows how you can get the size of an SVG
 * document. Note that due to how SVG is designed (units, percentages...), the
 * size of an SVG document can be known only once the SVGDocument has been
 * analyzed (ie. the GVT tree has been constructed).</p>
 *
 * <pre>
 * final JSVGComponent svgComp = new JSVGComponent();
 * svgComp.loadSVGDocument("foo.svg");
 * svgComp.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter() {
 *     public void gvtBuildCompleted(GVTTreeBuilderEvent evt) {
 *         Dimension2D size = svgComp.getSVGDocumentSize();
 *         // ...
 *     }
 * });
 * </pre>
 *
 * <p>The second example shows how you can access to the DOM tree when a URI has
 * been used to display an SVG document.
 *
 * <pre>
 * final JSVGComponent svgComp = new JSVGComponent();
 * svgComp.loadSVGDocument("foo.svg");
 * svgComp.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter() {
 *     public void documentLoadingCompleted(SVGDocumentLoaderEvent evt) {
 *         SVGDocument svgDoc = svgComp.getSVGDocument();
 *         //...
 *     }
 * });
 * </pre>
 *
 * <p>Conformed to the <a href=
 * "http://java.sun.com/docs/books/tutorial/uiswing/overview/threads.html">
 * single thread rule of swing</a>, the listeners are executed in the swing
 * thread. The sequence of the method calls for a particular listener and
 * the order of the listeners themselves are <em>guaranteed</em>.</p>
 *
 * <h2>User Agent</h2>
 *
 * <p>The <code>JSVGComponent</code> can pick up some informations to a user
 * agent. The <code>{@link SVGUserAgent}</code> provides a way to control the
 * resolution used to display an SVG document (controling the pixel to
 * millimeter conversion factor), perform an operation in respond to a click on
 * an hyperlink, control the default language to use, or specify a user
 * stylesheet, or how to display errors when an error occured while
 * building/rendering a document (invalid XML file, missing attributes...).</p>
 *
 * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
 * @version $Id$
 */
public class JSVGComponent extends JGVTComponent {

    /**
     * Means that the component must auto detect whether
     * the current document is static or dynamic.
     */
    public static final int AUTODETECT = 0;

    /**
     * Means that all document must be considered as dynamic.
     *
     * Indicates that all DOM listeners should be registered. This supports
     * 'interactivity' (anchors and cursors), as well as DOM modifications
     * listeners to update the GVT rendering tree.
     */
    public static final int ALWAYS_DYNAMIC = 1;

    /**
     * Means that all document must be considered as static.
     *
     * Indicates that no DOM listeners should be registered.
     * In this case the generated GVT tree should be totally
     * independent of the DOM tree (in practice text holds
     * references to the source text elements for font resolution).
     */
    public static final int ALWAYS_STATIC = 2;

    /**
     * Means that all document must be considered as interactive.
     *
     * Indicates that DOM listeners should be registered to support,
     * 'interactivity' this includes anchors and cursors, but does not
     * include support for DOM modifications.
     */
    public static final int ALWAYS_INTERACTIVE = 3;

    /**
     * String constant for the resource with the text for a script alert
     * dialog. Must have a substitution for one string.
     */
    public static final String SCRIPT_ALERT = "script.alert";

    /**
     * String constant for the resource with the text for a script
     * prompt dialog. Must have a substitution for one string.
     */
    public static final String SCRIPT_PROMPT = "script.prompt";

    /**
     * String constant for the resource with the text for a script
     * confim dialog. Must have a substitution for one string.
     */
    public static final String SCRIPT_CONFIRM = "script.confirm";

    /**
     * String constant for the resource with the text for the title
     * of the info tooltip for brokin link images.
     * No string substitution.
     */
    public static final String BROKEN_LINK_TITLE = "broken.link.title";

    /**
     * The document loader.
     */
    protected SVGDocumentLoader documentLoader;

    /**
     * The next document loader to run.
     */
    protected SVGDocumentLoader nextDocumentLoader;

    /**
     * The concrete bridge document loader.
     */
    protected DocumentLoader loader;

    /**
     * The GVT tree builder.
     */
    protected GVTTreeBuilder gvtTreeBuilder;

    /**
     * The next GVT tree builder to run.
     */
    protected GVTTreeBuilder nextGVTTreeBuilder;

    /**
     * The SVGLoadEventDispatcher.
     */
    protected SVGLoadEventDispatcher svgLoadEventDispatcher;

    /**
     * The update manager.
     */
    protected UpdateManager updateManager;

    /**
     * The next update manager.
     */
    protected UpdateManager nextUpdateManager;

    /**
     * The current SVG document.
     */
    protected SVGDocument svgDocument;

    /**
     * The document loader listeners.
     */
    protected List svgDocumentLoaderListeners = new LinkedList();

    /**
     * The GVT tree builder listeners.
     */
    protected List gvtTreeBuilderListeners = new LinkedList();

    /**
     * The SVG onload dispatcher listeners.
     */
    protected List svgLoadEventDispatcherListeners = new LinkedList();

    /**
     * The link activation listeners.
     */
    protected List linkActivationListeners = new LinkedList();

    /**
     * The update manager listeners.
     */
    protected List updateManagerListeners = new LinkedList();

    /**
     * The user agent.
     */
    protected UserAgent userAgent;

    /**
     * The SVG user agent.
     */
    protected SVGUserAgent svgUserAgent;

    /**
     * The current bridge context.
     */
    protected BridgeContext bridgeContext;

    /**
     * The current document fragment identifier.
     */
    protected String fragmentIdentifier;

    /**
     * Whether the current document has dynamic features.
     */
    protected boolean isDynamicDocument;

    /**
     * Whether the current document has dynamic features.
     */
    protected boolean isInteractiveDocument;

    /**
     * Set to true before component calls setDisableInteractors
     * so it knows that the users isn't the one calling it.
     */
    protected boolean selfCallingDisableInteractions = false;

    /**
     * Set to true if the user ever calls setDisableInteractions
     */
    protected boolean userSetDisableInteractions = false;

    /**
     * The document state.
     */
    protected int documentState;

    protected Dimension prevComponentSize;

    protected Runnable afterStopRunnable = null;

    protected SVGUpdateOverlay updateOverlay; // = new SVGUpdateOverlay(20, 4);

    protected boolean recenterOnResize = true;

    protected AffineTransform viewingTransform = null;

    /**
     * The animation limiting mode.
     */
    protected int animationLimitingMode;

    /**
     * The amount of animation limiting.
     */
    protected float animationLimitingAmount;

    /**
     * Creates a new JSVGComponent.
     */
    public JSVGComponent() {
        this(null, false, false);
    }

    /**
     * Creates a new JSVGComponent.
     * @param ua a SVGUserAgent instance or null.
     * @param eventsEnabled Whether the GVT tree should be reactive
     *        to mouse and key events.
     * @param selectableText Whether the text should be selectable.
     */
    public JSVGComponent(SVGUserAgent ua, boolean eventsEnabled,
                         boolean selectableText) {
        super(eventsEnabled, selectableText);

        svgUserAgent = ua;

        userAgent = new BridgeUserAgentWrapper(createUserAgent());

        addSVGDocumentLoaderListener((SVGListener)listener);
        addGVTTreeBuilderListener((SVGListener)listener);
        addSVGLoadEventDispatcherListener((SVGListener)listener);
        if (updateOverlay != null)
            getOverlays().add(updateOverlay);
    }

    public void dispose() {
        setSVGDocument(null);
    }

    public void setDisableInteractions(boolean b) {
        super.setDisableInteractions(b);
        if (!selfCallingDisableInteractions)
            userSetDisableInteractions = true;
    }

    /**
     * Clears the boolean that indicates the 'user'
     * has set disable interactions so that the canvas
     * uses the value from documents.
     */
    public void clearUserSetDisableInteractions() {
        userSetDisableInteractions = false;
        updateZoomAndPanEnable(svgDocument);
    }

    /**
     * Enables/Disables Zoom And Pan based on the zoom and
     * pan attribute of the currently installed document,
     * Unless the user has set the Interactions State.
     */
    public void updateZoomAndPanEnable(Document doc) {
        if (userSetDisableInteractions) return;
        if (doc == null) return;
        try {
            Element root = doc.getDocumentElement();
            String znp = root.getAttributeNS
                (null, SVGConstants.SVG_ZOOM_AND_PAN_ATTRIBUTE);
            boolean enable = SVGConstants.SVG_MAGNIFY_VALUE.equals(znp);
            selfCallingDisableInteractions = true;
            setDisableInteractions(!enable);
        } finally {
            selfCallingDisableInteractions = false;
        }
    }

    /**
     * Indicates if the canvas should recenter the content after
     * the canvas is resized.  If true it will try and keep the
     * point that was at the center at the center after resize.
     * Otherwise the upper left corner will be kept at the same point.
     */
    public boolean getRecenterOnResize() {
        return recenterOnResize;
    }
    /**
     * Returns sate of the recenter on resize flag.
     */
    public void setRecenterOnResize(boolean recenterOnResize) {
        this.recenterOnResize = recenterOnResize;
    }

    /**
     * Tells whether the component use dynamic features to
     * process the current document.
     */
    public boolean isDynamic() {
        return isDynamicDocument;
    }

    /**
     * Tells whether the component use dynamic features to
     * process the current document.
     */
    public boolean isInteractive() {
        return isInteractiveDocument;
    }

    /**
     * Sets the document state. The given value must be one of
     * AUTODETECT, ALWAYS_DYNAMIC or ALWAYS_STATIC.  This only
     * effects the loading of subsequent documents, it has no
     * effect on the currently loaded document.
     */
    public void setDocumentState(int state) {
        documentState = state;
    }

    /**
     * Returns the current update manager.  The update manager becomes
     * available after the first rendering completes.  You can be
     * notifed when the rendering completes by registering a
     * GVTTreeRendererListener with the component and waiting for the
     * <code>gvtRenderingCompleted</code> event.
     *
     * An UpdateManager is only created for Dynamic documents.  By
     * default the Canvas attempts to autodetect dynamic documents by
     * looking for script elements and/or event attributes in the
     * document, if it does not find these it assumes the document is
     * static.  Callers of this method will almost certainly want to
     * call setDocumentState(ALWAYS_DYNAMIC) before loading the document
     * (with setURI, setDocument, setSVGDocument etc.) so that an
     * UpdateManager is always created (even for apparently static documents).
     */
    public UpdateManager getUpdateManager() {
        if (svgLoadEventDispatcher != null) {
            return svgLoadEventDispatcher.getUpdateManager();
        }
        if (nextUpdateManager != null) {
            return nextUpdateManager;
        }
        return updateManager;
    }

    /**
     * Resumes the processing of the current document.
     */
    public void resumeProcessing() {
        if (updateManager != null) {
            updateManager.resume();
        }
    }

    /**
     * Suspend the processing of the current document.
     */
    public void suspendProcessing() {
        if (updateManager != null) {
            updateManager.suspend();
        }
    }

    /**
     * Stops the processing of the current document.
     */
    public void stopProcessing() {
        nextDocumentLoader = null;
        nextGVTTreeBuilder = null;

        if (documentLoader != null) {
            documentLoader.halt();
        }
        if (gvtTreeBuilder != null) {
            gvtTreeBuilder.halt();
        }
        if (svgLoadEventDispatcher != null) {
            svgLoadEventDispatcher.halt();
        }
        if (nextUpdateManager != null) {
            nextUpdateManager.interrupt();
            nextUpdateManager = null;
        }
        if (updateManager != null) {
            updateManager.interrupt();
        }
        super.stopProcessing();
    }

    /**
     * Loads a SVG document from the given URL.
     * <em>Note: Because the loading is multi-threaded, the current
     * SVG document is not guaranteed to be updated after this method
     * returns. The only way to be notified a document has been loaded
     * is to listen to the <code>SVGDocumentLoaderEvent</code>s.</em>
     */
    public void loadSVGDocument(String url) {
        String oldURI = null;
        if (svgDocument != null) {
            oldURI = svgDocument.getURL();
        }
        final ParsedURL newURI = new ParsedURL(oldURI, url);

        stopThenRun(new Runnable() {
                public void run() {
                    String url = newURI.toString();
                    fragmentIdentifier = newURI.getRef();

                    loader = new DocumentLoader(userAgent);
                    nextDocumentLoader = new SVGDocumentLoader(url, loader);
                    nextDocumentLoader.setPriority(Thread.MIN_PRIORITY);

                    Iterator it = svgDocumentLoaderListeners.iterator();
                    while (it.hasNext()) {
                        nextDocumentLoader.addSVGDocumentLoaderListener
                            ((SVGDocumentLoaderListener)it.next());
                    }
                    startDocumentLoader();
                }
            });
    }

    /**
     * Starts a loading thread.
     */
    private void startDocumentLoader() {
        documentLoader = nextDocumentLoader;
        nextDocumentLoader = null;
        documentLoader.start();
    }

    /**
     * Sets the Document to display.  If the document does not use
     * Batik's SVG DOM Implemenation it will be cloned into that
     * implementation.  In this case you should use 'getSVGDocument()'
     * to get the actual DOM that is attached to the rendering interface.
     *
     * Note that the preparation for rendering and the rendering itself
     * occur asynchronously so you need to register event handlers
     * if you want to know when the document is truly displayed.
     *
     * Notes for documents that you want to change in Java:
     * From this point on you may only modify the
     * the document in the UpdateManager thread @see #getUpdateManager.
     * In many cases you also need to tell Batik to treat the document
     * as a dynamic document by calling setDocumentState(ALWAYS_DYNAMIC).
     */
    public void setDocument(Document doc) {
        if ((doc != null) &&
            !(doc.getImplementation() instanceof SVGDOMImplementation)) {
            DOMImplementation impl;
            impl = SVGDOMImplementation.getDOMImplementation();
            Document d = DOMUtilities.deepCloneDocument(doc, impl);
            doc = d;
        }
        setSVGDocument((SVGDocument)doc);
    }

    /**
     * Sets the SVGDocument to display.  If the document does not use
     * Batik's SVG DOM Implemenation it will be cloned into that
     * implementation.  In this case you should use 'getSVGDocument()'
     * to get the actual DOM that is attached to the rendering
     * interface.
     *
     * Note that the preparation for rendering and the rendering itself
     * occur asynchronously so you need to register event handlers
     * if you want to know when the document is truly displayed.
     *
     * Notes for documents that you want to change in Java.
     * From this point on you may only modify the
     * the document in the UpdateManager thread @see #getUpdateManager.
     * In many cases you also need to tell Batik to treat the document
     * as a dynamic document by calling setDocumentState(ALWAYS_DYNAMIC).
     */
    public void setSVGDocument(SVGDocument doc) {
        if ((doc != null) &&
            !(doc.getImplementation() instanceof SVGDOMImplementation)) {
            DOMImplementation impl;
            impl = SVGDOMImplementation.getDOMImplementation();
            Document d = DOMUtilities.deepCloneDocument(doc, impl);
            doc = (SVGDocument)d;
        }

        final SVGDocument svgdoc = doc;
        stopThenRun(new Runnable() {
                public void run() {
                    installSVGDocument(svgdoc);
                }
            });
    }

    /**
     * This method calls stop processing waits for all
     * threads to die then runs the Runnable in the event
     * queue thread.  It returns immediately.
     */
    protected void stopThenRun(final Runnable r) {
        if (afterStopRunnable != null) {
            // Have it run our new runnable, and not
                // run the 'old' runnable.
            afterStopRunnable = r;
            return;
        }
        afterStopRunnable = r;

        stopProcessing();

        if ((documentLoader         == null) &&
            (gvtTreeBuilder         == null) &&
            (gvtTreeRenderer        == null) &&
            (svgLoadEventDispatcher == null) &&
            (nextUpdateManager      == null) &&
            (updateManager          == null)) {
            Runnable asr = afterStopRunnable;
            afterStopRunnable = null;
            asr.run();
        }
    }

    /**
     * This does the real work of installing the SVG Document after
     * the update manager from the previous document (if any) has been
     * properly 'shut down'.
     */
    protected void installSVGDocument(SVGDocument doc) {
        svgDocument = doc;

        if (bridgeContext != null) {
            bridgeContext.dispose();
            bridgeContext = null;
        }

        releaseRenderingReferences();

        if (doc == null) {
            isDynamicDocument = false;
            isInteractiveDocument = false;
            disableInteractions = true;
            initialTransform = new AffineTransform();
            setRenderingTransform(initialTransform, false);
            Rectangle vRect = getRenderRect();
            repaint(vRect.x,     vRect.y,
                    vRect.width, vRect.height);
            return;
        }

        bridgeContext = createBridgeContext((SVGOMDocument) doc);

        switch (documentState) {
        case ALWAYS_STATIC:
            isDynamicDocument = false;
            isInteractiveDocument = false;
            break;
        case ALWAYS_INTERACTIVE:
            isDynamicDocument = false;
            isInteractiveDocument = true;
            break;
        case ALWAYS_DYNAMIC:
            isDynamicDocument = true;
            isInteractiveDocument = true;
            break;
        case AUTODETECT:
            isDynamicDocument = bridgeContext.isDynamicDocument(doc);
            isInteractiveDocument =
                isDynamicDocument || bridgeContext.isInteractiveDocument(doc);
        }

        if (isInteractiveDocument) {
            if (isDynamicDocument)
                bridgeContext.setDynamicState(BridgeContext.DYNAMIC);
            else
                bridgeContext.setDynamicState(BridgeContext.INTERACTIVE);
        }

        setBridgeContextAnimationLimitingMode();

        updateZoomAndPanEnable(doc);

        nextGVTTreeBuilder = new GVTTreeBuilder(doc, bridgeContext);
        nextGVTTreeBuilder.setPriority(Thread.MIN_PRIORITY);

        Iterator it = gvtTreeBuilderListeners.iterator();
        while (it.hasNext()) {
            nextGVTTreeBuilder.addGVTTreeBuilderListener
                ((GVTTreeBuilderListener)it.next());
        }

        initializeEventHandling();

        if (gvtTreeBuilder == null &&
            documentLoader == null &&
            gvtTreeRenderer == null &&
            svgLoadEventDispatcher == null &&
            updateManager == null) {
            startGVTTreeBuilder();
        }
    }

    /**
     * Starts a tree builder.
     */
    protected void startGVTTreeBuilder() {
        gvtTreeBuilder = nextGVTTreeBuilder;
        nextGVTTreeBuilder = null;
        gvtTreeBuilder.start();
    }

    /**
     * Returns the current SVG document.
     */
    public SVGDocument getSVGDocument() {
        return svgDocument;
    }

    /**
     * Returns the size of the SVG document.
     */
    public Dimension2D getSVGDocumentSize() {
        return bridgeContext.getDocumentSize();
    }

    /**
     * Returns the current's document fragment identifier.
     */
    public String getFragmentIdentifier() {
        return fragmentIdentifier;
    }

    /**
     * Sets the current fragment identifier.
     */
    public void setFragmentIdentifier(String fi) {
        fragmentIdentifier = fi;
        if (computeRenderingTransform())
            scheduleGVTRendering();
    }

    /**
     * Removes all images from the image cache.
     */
    public void flushImageCache() {
        ImageTagRegistry reg = ImageTagRegistry.getRegistry();
        reg.flushCache();
    }

    public void setGraphicsNode(GraphicsNode gn, boolean createDispatcher) {
        Dimension2D dim = bridgeContext.getDocumentSize();
        Dimension   mySz = new Dimension((int)dim.getWidth(),
                                         (int)dim.getHeight());
        JSVGComponent.this.setMySize(mySz);
        SVGSVGElement elt = svgDocument.getRootElement();
        prevComponentSize = getSize();
        AffineTransform at = calculateViewingTransform
            (fragmentIdentifier, elt);
        CanvasGraphicsNode cgn = getCanvasGraphicsNode(gn);
        if (cgn != null) {
            cgn.setViewingTransform(at);
        }
        viewingTransform = null;
        initialTransform = new AffineTransform();
        setRenderingTransform(initialTransform, false);
        jsvgComponentListener.updateMatrix(initialTransform);
        addJGVTComponentListener(jsvgComponentListener);
        addComponentListener(jsvgComponentListener);
        super.setGraphicsNode(gn, createDispatcher);
    }

    /**
     * Creates a new bridge context.
     */
    protected BridgeContext createBridgeContext(SVGOMDocument doc) {
        if (loader == null) {
            loader = new DocumentLoader(userAgent);
        }
        BridgeContext result;
        if (doc.isSVG12()) {
            result = new SVG12BridgeContext(userAgent, loader);
        } else {
            result = new BridgeContext(userAgent, loader);
        }
        return result;
    }

    /**
     * Starts a SVGLoadEventDispatcher thread.
     */
    protected void startSVGLoadEventDispatcher(GraphicsNode root) {
        UpdateManager um = new UpdateManager(bridgeContext,
                                             root,
                                             svgDocument);
        svgLoadEventDispatcher =
            new SVGLoadEventDispatcher(root,
                                       svgDocument,
                                       bridgeContext,
                                       um);
        Iterator it = svgLoadEventDispatcherListeners.iterator();
        while (it.hasNext()) {
            svgLoadEventDispatcher.addSVGLoadEventDispatcherListener
                ((SVGLoadEventDispatcherListener)it.next());
        }

        svgLoadEventDispatcher.start();
    }

    /**
     * Creates a new renderer.
     */
    protected ImageRenderer createImageRenderer() {
        if (isDynamicDocument) {
            return rendererFactory.createDynamicImageRenderer();
        } else {
            return rendererFactory.createStaticImageRenderer();
        }
    }

    public CanvasGraphicsNode getCanvasGraphicsNode() {
        return getCanvasGraphicsNode(gvtRoot);

    }

    protected CanvasGraphicsNode getCanvasGraphicsNode(GraphicsNode gn) {
        if (!(gn instanceof CompositeGraphicsNode))
            return null;
        CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn;
        List children = cgn.getChildren();
        if (children.size() == 0)
            return null;
        gn = (GraphicsNode)children.get(0);
        if (!(gn instanceof CanvasGraphicsNode))
            return null;
        return (CanvasGraphicsNode)gn;
    }

    public AffineTransform getViewingTransform() {
        AffineTransform vt;
        synchronized (this) {
            vt = viewingTransform;
            if (vt == null) {
                CanvasGraphicsNode cgn = getCanvasGraphicsNode();
                if (cgn != null)
                    vt = cgn.getViewingTransform();
            }
        }
        return vt;
    }

    /**
     * Returns the transform from viewBox coords to screen coords
     */
    public AffineTransform getViewBoxTransform() {
        AffineTransform at = getRenderingTransform();
        if (at == null) at = new AffineTransform();
        else            at = new AffineTransform(at);
        AffineTransform vt = getViewingTransform();
        if (vt != null) {
            at.concatenate(vt);
        }
        return at;
    }

    /**
     * Computes the transform used for rendering.
     * Returns true if the component needs to be repainted.
     */
    protected boolean computeRenderingTransform() {
        if ((svgDocument == null) || (gvtRoot == null))
            return false;

        boolean ret = updateRenderingTransform();
        initialTransform = new AffineTransform();
        if (!initialTransform.equals(getRenderingTransform())) {
            setRenderingTransform(initialTransform, false);
            ret = true;
        }
        return ret;
    }

    protected AffineTransform calculateViewingTransform
        (String fragIdent, SVGSVGElement svgElt) {
        Dimension d = getSize();
        if (d.width  < 1) d.width  = 1;
        if (d.height < 1) d.height = 1;
        return ViewBox.getViewTransform
            (fragIdent, svgElt, d.width, d.height, bridgeContext);
    }

    /**
     * Updates the value of the transform used for rendering.
     * Return true if a repaint is required, otherwise false.
     */
    protected boolean updateRenderingTransform() {
        if ((svgDocument == null) || (gvtRoot == null))
            return false;

        try {
            SVGSVGElement elt = svgDocument.getRootElement();
            Dimension d = getSize();
            Dimension oldD = prevComponentSize;
            if (oldD == null) oldD = d;
            prevComponentSize = d;
            if (d.width  < 1) d.width  = 1;
            if (d.height < 1) d.height = 1;
            final AffineTransform at = calculateViewingTransform
                (fragmentIdentifier, elt);
            AffineTransform vt = getViewingTransform();
            if (at.equals(vt)) {
                // No new transform
                // Only repaint if size really changed.
                return ((oldD.width != d.width) || (oldD.height != d.height));
            }

            if (recenterOnResize) {
                // Here we map the old center of the component down to
                // the user coodinate system with the old viewing
                // transform and then back to the screen with the
                // new viewing transform.  We then adjust the rendering
                // transform so it lands in the same place.
                Point2D pt = new Point2D.Float(oldD.width/2.0f,
                                               oldD.height/2.0f);
                AffineTransform rendAT = getRenderingTransform();
                if (rendAT != null) {
                    try {
                        AffineTransform invRendAT = rendAT.createInverse();
                        pt = invRendAT.transform(pt, null);
                    } catch (NoninvertibleTransformException e) { }
                }
                if (vt != null) {
                    try {
                        AffineTransform invVT = vt.createInverse();
                        pt = invVT.transform(pt, null);
                    } catch (NoninvertibleTransformException e) { }
                }
                if (at != null)
                    pt = at.transform(pt, null);
                if (rendAT != null)
                    pt = rendAT.transform(pt, null);
                
                // Now figure out how far we need to shift things
                // to get the center point to line up again.
                float dx = (float)((d.width/2.0f) -pt.getX());
                float dy = (float)((d.height/2.0f)-pt.getY());
                // Round the values to nearest integer.
                dx = (int)((dx < 0)?(dx - .5):(dx + .5));
                dy = (int)((dy < 0)?(dy - .5):(dy + .5));
                if ((dx != 0) || (dy != 0)) {
                    rendAT.preConcatenate
                        (AffineTransform.getTranslateInstance(dx, dy));
                    setRenderingTransform(rendAT, false);
                }
            }

            synchronized (this) {
                viewingTransform = at;
            }
            Runnable r = new Runnable() {
                    AffineTransform myAT = at;
                    CanvasGraphicsNode myCGN = getCanvasGraphicsNode();
                    public void run() {
                        synchronized (JSVGComponent.this) {
                            if (myCGN != null) {
                                myCGN.setViewingTransform(myAT);
                            }
                            if (viewingTransform == myAT)
                                viewingTransform = null;
                        }
                    }
                };
            UpdateManager um = getUpdateManager();
            if (um != null) um.getUpdateRunnableQueue().invokeLater(r);
            else             r.run();
        } catch (BridgeException e) {
            userAgent.displayError(e);
        }
        return true;
    }

    /**
     * Renders the GVT tree.
     */
    protected void renderGVTTree() {
        if (!isInteractiveDocument ||
            updateManager == null ||
            !updateManager.isRunning()) {
            super.renderGVTTree();
            return;
        }

        final Rectangle visRect = getRenderRect();
        if ((gvtRoot == null)    ||
            (visRect.width <= 0) ||
            (visRect.height <= 0)) {
            return;
        }

        // Area of interest computation.
        AffineTransform inv = null;
        try {
            inv = renderingTransform.createInverse();
        } catch (NoninvertibleTransformException e) {
        }
        final Shape s;
        if (inv == null) s = visRect;
        else             s = inv.createTransformedShape(visRect);

        class UpdateRenderingRunnable implements Runnable {
            AffineTransform at;
            boolean         doubleBuf;
            boolean         clearPaintTrans;
            Shape           aoi;
            int             width;
            int             height;

            boolean active;

            public UpdateRenderingRunnable(AffineTransform at,
                                           boolean doubleBuf,
                                           boolean clearPaintTrans,
                                           Shape aoi,
                                           int width, int height) {
                updateInfo(at, doubleBuf, clearPaintTrans, aoi, width, height);
                active = true;
            }

            public void updateInfo(AffineTransform at,
                                   boolean doubleBuf,
                                   boolean clearPaintTrans,
                                   Shape aoi,
                                   int width, int height) {
                this.at              = at;
                this.doubleBuf       = doubleBuf;
                this.clearPaintTrans = clearPaintTrans;
                this.aoi             = aoi;
                this.width           = width;
                this.height          = height;
                active = true;
            }

            public void deactivate() {
                active = false;
            }
            public void run() {
                if (!active) return;

                updateManager.updateRendering
                    (at, doubleBuf, clearPaintTrans, aoi, width, height);
            }
        }
        RunnableQueue rq = updateManager.getUpdateRunnableQueue();

        // Events compression.
        synchronized (rq.getIteratorLock()) {
            Iterator it = rq.iterator();
            while (it.hasNext()) {
                Object next = it.next();
                if (next instanceof UpdateRenderingRunnable) {
                    ((UpdateRenderingRunnable)next).deactivate();
                }
            }
        }

        rq.invokeLater(new UpdateRenderingRunnable
                       (renderingTransform,
                        doubleBufferedRendering, true, s,
                        visRect.width, visRect.height));
    }

    /**
     * Handles an exception.
     */
    protected void handleException(Exception e) {
        userAgent.displayError(e);
    }

    /**
     * Adds a SVGDocumentLoaderListener to this component.
     */
    public void addSVGDocumentLoaderListener(SVGDocumentLoaderListener l) {
        svgDocumentLoaderListeners.add(l);
    }

    /**
     * Removes a SVGDocumentLoaderListener from this component.
     */
    public void removeSVGDocumentLoaderListener(SVGDocumentLoaderListener l) {
        svgDocumentLoaderListeners.remove(l);
    }

    /**
     * Adds a GVTTreeBuilderListener to this component.
     */
    public void addGVTTreeBuilderListener(GVTTreeBuilderListener l) {
        gvtTreeBuilderListeners.add(l);
    }

    /**
     * Removes a GVTTreeBuilderListener from this component.
     */
    public void removeGVTTreeBuilderListener(GVTTreeBuilderListener l) {
        gvtTreeBuilderListeners.remove(l);
    }

    /**
     * Adds a SVGLoadEventDispatcherListener to this component.
     */
    public void addSVGLoadEventDispatcherListener
        (SVGLoadEventDispatcherListener l) {
        svgLoadEventDispatcherListeners.add(l);
    }

    /**
     * Removes a SVGLoadEventDispatcherListener from this component.
     */
    public void removeSVGLoadEventDispatcherListener
        (SVGLoadEventDispatcherListener l) {
        svgLoadEventDispatcherListeners.remove(l);
    }

    /**
     * Adds a LinkActivationListener to this component.
     */
    public void addLinkActivationListener(LinkActivationListener l) {
        linkActivationListeners.add(l);
    }

    /**
     * Removes a LinkActivationListener from this component.
     */
    public void removeLinkActivationListener(LinkActivationListener l) {
        linkActivationListeners.remove(l);
    }

    /**
     * Adds a UpdateManagerListener to this component.
     */
    public void addUpdateManagerListener(UpdateManagerListener l) {
        updateManagerListeners.add(l);
    }

    /**
     * Removes a UpdateManagerListener from this component.
     */
    public void removeUpdateManagerListener(UpdateManagerListener l) {
        updateManagerListeners.remove(l);
    }

    /**
     * Shows an alert dialog box.
     */
    public void showAlert(String message) {
        JOptionPane.showMessageDialog
            (this, Messages.formatMessage(SCRIPT_ALERT,
                                          new Object[] { message }));
    }

    /**
     * Shows a prompt dialog box.
     */
    public String showPrompt(String message) {
        return JOptionPane.showInputDialog
            (this, Messages.formatMessage(SCRIPT_PROMPT,
                                          new Object[] { message }));
    }

    /**
     * Shows a prompt dialog box.
     */
    public String showPrompt(String message, String defaultValue) {
        return (String)JOptionPane.showInputDialog
            (this,
             Messages.formatMessage(SCRIPT_PROMPT,
                                    new Object[] { message }),
             null,
             JOptionPane.PLAIN_MESSAGE,
             null, null, defaultValue);
    }

    /**
     * Shows a confirm dialog box.
     */
    public boolean showConfirm(String message) {
        return JOptionPane.showConfirmDialog
            (this, Messages.formatMessage(SCRIPT_CONFIRM,
                                          new Object[] { message }),
             "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
    }


    /**
     * This method is called when the component knows the desired
     * size of the window (based on width/height of outermost SVG
     * element).
     * The default implementation simply calls setPreferredSize,
     * and invalidate.
     * However it is often useful to pack the window containing
     * this component.
     */
    public void setMySize(Dimension d) {
        setPreferredSize(d);
        invalidate();
    }

    /**
     * Sets the animation limiting mode to "none".
     */
    public void setAnimationLimitingNone() {
        animationLimitingMode = 0;
        if (bridgeContext != null) {
            setBridgeContextAnimationLimitingMode();
        }
    }

    /**
     * Sets the animation limiting mode to a percentage of CPU.
     * @param pc the maximum percentage of CPU to use (0 &lt; pc ≤ 1)
     */
    public void setAnimationLimitingCPU(float pc) {
        animationLimitingMode = 1;
        animationLimitingAmount = pc;
        if (bridgeContext != null) {
            setBridgeContextAnimationLimitingMode();
        }
    }

    /**
     * Sets the animation limiting mode to a number of frames per second.
     * @param fps the maximum number of frames per second (fps &gt; 0)
     */
    public void setAnimationLimitingFPS(float fps) {
        animationLimitingMode = 2;
        animationLimitingAmount = fps;
        if (bridgeContext != null) {
            setBridgeContextAnimationLimitingMode();
        }
    }

    /**
     * Returns the {@link Interpreter} being used for script of the given
     * MIME type.
     *
     * @param type The MIME type the returned <code>Interpreter</code> handles.
     */
    public Interpreter getInterpreter(String type) {
        if (bridgeContext != null) {
            return bridgeContext.getInterpreter(type);
        }
        return null;
    }

    /**
     * Sets the animation limiting mode on the current bridge context.
     */
    protected void setBridgeContextAnimationLimitingMode() {
        switch (animationLimitingMode) {
            case 0: // unlimited
                bridgeContext.setAnimationLimitingNone();
                break;
            case 1: // %cpu
                bridgeContext.setAnimationLimitingCPU(animationLimitingAmount);
                break;
            case 2: // fps
                bridgeContext.setAnimationLimitingFPS(animationLimitingAmount);
                break;
        }
    }

    /**
     * The JGVTComponentListener.
     */
    protected JSVGComponentListener jsvgComponentListener =
        new JSVGComponentListener();

    protected class JSVGComponentListener extends ComponentAdapter
        implements JGVTComponentListener {
        float prevScale = 0;
        float prevTransX = 0;
        float prevTransY = 0;

        public void componentResized(ComponentEvent ce) {
            if (isDynamicDocument &&
                (updateManager != null) && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            try {
                                updateManager.dispatchSVGResizeEvent();
                            } catch (InterruptedException ie) {
                            }
                        }});
            }
        }

        public void componentTransformChanged(ComponentEvent event) {
            AffineTransform at = getRenderingTransform();

            float currScale  = (float)Math.sqrt(at.getDeterminant());
            float currTransX = (float)at.getTranslateX();
            float currTransY = (float)at.getTranslateY();

            final boolean dispatchZoom    = (currScale != prevScale);
            final boolean dispatchScroll  = ((currTransX != prevTransX) ||
                                             (currTransY != prevTransY));
            if (isDynamicDocument &&
                (updateManager != null) && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            try {
                                if (dispatchZoom)
                                    updateManager.dispatchSVGZoomEvent();
                                if (dispatchScroll)
                                    updateManager.dispatchSVGScrollEvent();
                            } catch (InterruptedException ie) {
                            }
                        }});
            }
            prevScale = currScale;
            prevTransX = currTransX;
            prevTransY = currTransY;
        }

        public void updateMatrix(AffineTransform at) {
            prevScale  = (float)Math.sqrt(at.getDeterminant());
            prevTransX = (float)at.getTranslateX();
            prevTransY = (float)at.getTranslateY();
        }
    }


    /**
     * Creates an instance of Listener.
     */
    protected Listener createListener() {
        return new SVGListener();
    }

    /**
     * To hide the listener methods.
     */
    protected class SVGListener
        extends Listener
        implements SVGDocumentLoaderListener,
                   GVTTreeBuilderListener,
                   SVGLoadEventDispatcherListener,
                   UpdateManagerListener {

        /**
         * Creates a new SVGListener.
         */
        protected SVGListener() {
        }

        // SVGDocumentLoaderListener /////////////////////////////////////////

        /**
         * Called when the loading of a document was started.
         */
        public void documentLoadingStarted(SVGDocumentLoaderEvent e) {
        }

        /**
         * Called when the loading of a document was completed.
         */
        public void documentLoadingCompleted(SVGDocumentLoaderEvent e) {
            if (nextDocumentLoader != null) {
                startDocumentLoader();
                return;
            }

            documentLoader = null;
            if (afterStopRunnable != null) {
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            setSVGDocument(e.getSVGDocument());
        }

        /**
         * Called when the loading of a document was cancelled.
         */
        public void documentLoadingCancelled(SVGDocumentLoaderEvent e) {
            if (nextDocumentLoader != null) {
                startDocumentLoader();
                return;
            }

            documentLoader = null;
            if (afterStopRunnable != null) {
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextGVTTreeBuilder != null) {
                startGVTTreeBuilder();
                return;
            }
        }

        /**
         * Called when the loading of a document has failed.
         */
        public void documentLoadingFailed(SVGDocumentLoaderEvent e) {
            if (nextDocumentLoader != null) {
                startDocumentLoader();
                return;
            }

            documentLoader = null;
            userAgent.displayError(((SVGDocumentLoader)e.getSource()).
                                   getException());

            if (afterStopRunnable != null) {
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }
            if (nextGVTTreeBuilder != null) {
                startGVTTreeBuilder();
                return;
            }
        }

        // GVTTreeBuilderListener ////////////////////////////////////////////

        /**
         * Called when a build started.
         * The data of the event is initialized to the old document.
         */
        public void gvtBuildStarted(GVTTreeBuilderEvent e) {
            removeJGVTComponentListener(jsvgComponentListener);
            removeComponentListener(jsvgComponentListener);
        }

        /**
         * Called when a build was completed.
         */
        public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
            if (nextGVTTreeBuilder != null) {
                startGVTTreeBuilder();
                return;
            }

            loader = null;
            gvtTreeBuilder = null;

            if (afterStopRunnable != null) {
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextDocumentLoader != null) {
                startDocumentLoader();
                return;
            }

            gvtRoot = null;

            if (isDynamicDocument && JSVGComponent.this.eventsEnabled) {
                startSVGLoadEventDispatcher(e.getGVTRoot());
            } else {
                if (isInteractiveDocument) {
                    nextUpdateManager = new UpdateManager(bridgeContext,
                                                          e.getGVTRoot(),
                                                          svgDocument);
                }

                JSVGComponent.this.setGraphicsNode(e.getGVTRoot(), false);
                scheduleGVTRendering();
            }
        }

        /**
         * Called when a build was cancelled.
         */
        public void gvtBuildCancelled(GVTTreeBuilderEvent e) {
            if (nextGVTTreeBuilder != null) {
                startGVTTreeBuilder();
                return;
            }

            loader = null;
            gvtTreeBuilder = null;

            if (afterStopRunnable != null) {
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextDocumentLoader != null) {
                startDocumentLoader();
                return;
            }
            JSVGComponent.this.image = null;
            repaint();
        }

        /**
         * Called when a build failed.
         */
        public void gvtBuildFailed(GVTTreeBuilderEvent e) {
            if (nextGVTTreeBuilder != null) {
                startGVTTreeBuilder();
                return;
            }

            loader = null;
            gvtTreeBuilder = null;

            if (afterStopRunnable != null) {
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextDocumentLoader != null) {
                startDocumentLoader();
                return;
            }

            GraphicsNode gn = e.getGVTRoot();
            if (gn == null) {
                JSVGComponent.this.image = null;
                repaint();
            } else {
                JSVGComponent.this.setGraphicsNode(gn, false);
                computeRenderingTransform();
            }
            userAgent.displayError(((GVTTreeBuilder)e.getSource())
                                   .getException());
        }

        // SVGLoadEventDispatcherListener ////////////////////////////////////

        /**
         * Called when a onload event dispatch started.
         */
        public void svgLoadEventDispatchStarted
            (SVGLoadEventDispatcherEvent e) {
        }

        /**
         * Called when a onload event dispatch was completed.
         */
        public void svgLoadEventDispatchCompleted
            (SVGLoadEventDispatcherEvent e) {
            nextUpdateManager = svgLoadEventDispatcher.getUpdateManager();
            svgLoadEventDispatcher = null;

            if (afterStopRunnable != null) {
                nextUpdateManager.interrupt();
                nextUpdateManager = null;

                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextGVTTreeBuilder != null) {
                nextUpdateManager.interrupt();
                nextUpdateManager = null;

                startGVTTreeBuilder();
                return;
            }
            if (nextDocumentLoader != null) {
                nextUpdateManager.interrupt();
                nextUpdateManager = null;

                startDocumentLoader();
                return;
            }

            JSVGComponent.this.setGraphicsNode(e.getGVTRoot(), false);
            scheduleGVTRendering();
        }

        /**
         * Called when a onload event dispatch was cancelled.
         */
        public void svgLoadEventDispatchCancelled
            (SVGLoadEventDispatcherEvent e) {
            nextUpdateManager = svgLoadEventDispatcher.getUpdateManager();
            svgLoadEventDispatcher = null;

            nextUpdateManager.interrupt();
            nextUpdateManager = null;

            if (afterStopRunnable != null) {
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextGVTTreeBuilder != null) {
                startGVTTreeBuilder();
                return;
            }
            if (nextDocumentLoader != null) {
                startDocumentLoader();
                return;
            }
        }

        /**
         * Called when a onload event dispatch failed.
         */
        public void svgLoadEventDispatchFailed
            (SVGLoadEventDispatcherEvent e) {
            nextUpdateManager = svgLoadEventDispatcher.getUpdateManager();
            svgLoadEventDispatcher = null;

            nextUpdateManager.interrupt();
            nextUpdateManager = null;

            if (afterStopRunnable != null) {
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextGVTTreeBuilder != null) {
                startGVTTreeBuilder();
                return;
            }
            if (nextDocumentLoader != null) {
                startDocumentLoader();
                return;
            }

            GraphicsNode gn = e.getGVTRoot();
            if (gn == null) {
                JSVGComponent.this.image = null;
                repaint();
            } else {
                JSVGComponent.this.setGraphicsNode(gn, false);
                computeRenderingTransform();
            }
            userAgent.displayError(((SVGLoadEventDispatcher)e.getSource())
                                   .getException());
        }

        // GVTTreeRendererListener ///////////////////////////////////////////

        /**
         * Called when a rendering was completed.
         */
        public void gvtRenderingCompleted(GVTTreeRendererEvent e) {
            super.gvtRenderingCompleted(e);

            if (afterStopRunnable != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }
                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextGVTTreeBuilder != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }
                startGVTTreeBuilder();
                return;
            }
            if (nextDocumentLoader != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }
                startDocumentLoader();
                return;
            }

            if (nextUpdateManager != null) {
                updateManager = nextUpdateManager;
                nextUpdateManager = null;
                updateManager.addUpdateManagerListener(this);
                updateManager.manageUpdates(renderer);
            }
        }

        /**
         * Called when a rendering was cancelled.
         */
        public void gvtRenderingCancelled(GVTTreeRendererEvent e) {
            super.gvtRenderingCancelled(e);

            if (afterStopRunnable != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }

                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextGVTTreeBuilder != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }

                startGVTTreeBuilder();
                return;
            }
            if (nextDocumentLoader != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }
                startDocumentLoader();
                return;
            }
        }

        /**
         * Called when a rendering failed.
         */
        public void gvtRenderingFailed(GVTTreeRendererEvent e) {
            super.gvtRenderingFailed(e);

            if (afterStopRunnable != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }

                EventQueue.invokeLater(afterStopRunnable);
                afterStopRunnable = null;
                return;
            }

            if (nextGVTTreeBuilder != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }

                startGVTTreeBuilder();
                return;
            }
            if (nextDocumentLoader != null) {
                if (nextUpdateManager != null) {
                    nextUpdateManager.interrupt();
                    nextUpdateManager = null;
                }

                startDocumentLoader();
                return;
            }
        }

        // UpdateManagerListener //////////////////////////////////////////

        /**
         * Called when the manager was started.
         */
        public void managerStarted(final UpdateManagerEvent e) {
            EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        suspendInteractions = false;

                        Object[] dll = updateManagerListeners.toArray();

                        if (dll.length > 0) {
                            for (int i = 0; i < dll.length; i++) {
                                ((UpdateManagerListener)dll[i]).
                                    managerStarted(e);
                            }
                        }
                    }
                });
        }

        /**
         * Called when the manager was suspended.
         */
        public void managerSuspended(final UpdateManagerEvent e) {
            EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        Object[] dll = updateManagerListeners.toArray();

                        if (dll.length > 0) {
                            for (int i = 0; i < dll.length; i++) {
                                ((UpdateManagerListener)dll[i]).
                                    managerSuspended(e);
                            }
                        }
                    }
                });
        }

        /**
         * Called when the manager was resumed.
         */
        public void managerResumed(final UpdateManagerEvent e) {
            EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        Object[] dll = updateManagerListeners.toArray();

                        if (dll.length > 0) {
                            for (int i = 0; i < dll.length; i++) {
                                ((UpdateManagerListener)dll[i]).
                                    managerResumed(e);
                            }
                        }
                    }
                });
        }

        /**
         * Called when the manager was stopped.
         */
        public void managerStopped(final UpdateManagerEvent e) {
            EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        updateManager = null;


                        Object[] dll = updateManagerListeners.toArray();

                        if (dll.length > 0) {
                            for (int i = 0; i < dll.length; i++) {
                                ((UpdateManagerListener)dll[i]).
                                    managerStopped(e);
                            }
                        }

                        if (afterStopRunnable != null) {
                            EventQueue.invokeLater(afterStopRunnable);
                            afterStopRunnable = null;
                            return;
                        }

                        if (nextGVTTreeBuilder != null) {
                            startGVTTreeBuilder();
                            return;
                        }
                        if (nextDocumentLoader != null) {
                            startDocumentLoader();
                            return;
                        }
                    }
                });
        }

        /**
         * Called when an update started.
         */
        public void updateStarted(final UpdateManagerEvent e) {
            EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        if (!doubleBufferedRendering) {
                            image = e.getImage();
                        }

                        Object[] dll = updateManagerListeners.toArray();

                        if (dll.length > 0) {
                            for (int i = 0; i < dll.length; i++) {
                                ((UpdateManagerListener)dll[i]).
                                    updateStarted(e);
                            }
                        }
                    }
                });
        }

        /**
         * Called when an update was completed.
         */
        public void updateCompleted(final UpdateManagerEvent e) {
            // IMPORTANT:
            // ==========
            //
            // The following call is 'invokeAndWait' and not
            // 'invokeLater' because it is essential that the
            // UpdateManager thread (which invokes this
            // 'updateCompleted' method, blocks until the repaint
            // has completed. Otherwise, there is a possibility
            // that internal buffers would get updated in the
            // middle of a swing repaint.
            //
            try {
                EventQueue.invokeAndWait(new Runnable() {
                        public void run() {
                            image = e.getImage();
                            if (e.getClearPaintingTransform())
                                paintingTransform = null;

                            List l = e.getDirtyAreas();
                            if (l != null) {
                                Iterator i = l.iterator();
                                while (i.hasNext()) {
                                    Rectangle r = (Rectangle)i.next();
                                    if (updateOverlay != null) {
                                        updateOverlay.addRect(r);
                                        r = getRenderRect();
                                    }

                                    if (doubleBufferedRendering)
                                        repaint(r);
                                    else
                                        paintImmediately(r);
                                }
                                if (updateOverlay != null)
                                    updateOverlay.endUpdate();
                            }
                            suspendInteractions = false;
                        }
                    });
            } catch (Exception ex) {
            }


            EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        Object[] dll = updateManagerListeners.toArray();

                        if (dll.length > 0) {
                            for (int i = 0; i < dll.length; i++) {
                                ((UpdateManagerListener)dll[i]).
                                    updateCompleted(e);
                            }
                        }
                    }
                });
        }

        /**
         * Called when an update failed.
         */
        public void updateFailed(final UpdateManagerEvent e) {
            EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        Object[] dll = updateManagerListeners.toArray();

                        if (dll.length > 0) {
                            for (int i = 0; i < dll.length; i++) {
                                ((UpdateManagerListener)dll[i]).
                                    updateFailed(e);
                            }
                        }
                    }
                });
        }

        // Event propagation to GVT ///////////////////////////////////////

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchKeyTyped(final KeyEvent e) {
            if (!isDynamicDocument) {
                super.dispatchKeyTyped(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.keyTyped(e);
                        }
                    });
            }

        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchKeyPressed(final KeyEvent e) {
            if (!isDynamicDocument) {
                super.dispatchKeyPressed(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.keyPressed(e);
                        }
                    });
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchKeyReleased(final KeyEvent e) {
            if (!isDynamicDocument) {
                super.dispatchKeyReleased(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.keyReleased(e);
                        }
                    });
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchMouseClicked(final MouseEvent e) {
            if (!isInteractiveDocument) {
                super.dispatchMouseClicked(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.mouseClicked(e);

                        }
                    });
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchMousePressed(final MouseEvent e) {
            if (!isDynamicDocument) {
                super.dispatchMousePressed(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.mousePressed(e);
                        }
                    });
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchMouseReleased(final MouseEvent e) {
            if (!isDynamicDocument) {
                super.dispatchMouseReleased(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.mouseReleased(e);
                        }
                    });
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchMouseEntered(final MouseEvent e) {
            if (!isInteractiveDocument) {
                super.dispatchMouseEntered(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.mouseEntered(e);
                        }
                    });
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchMouseExited(final MouseEvent e) {
            if (!isInteractiveDocument) {
                super.dispatchMouseExited(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.mouseExited(e);
                        }
                    });
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchMouseDragged(MouseEvent e) {
            if (!isDynamicDocument) {
                super.dispatchMouseDragged(e);
                return;
            }

            class MouseDraggedRunnable implements Runnable {
                MouseEvent event;
                MouseDraggedRunnable(MouseEvent evt) {
                    event = evt;
                }
                public void run() {
                    eventDispatcher.mouseDragged(event);
                }
            }

            if (updateManager != null && updateManager.isRunning()) {
                RunnableQueue rq = updateManager.getUpdateRunnableQueue();

                // Events compression.
                synchronized (rq.getIteratorLock()) {
                    Iterator it = rq.iterator();
                    while (it.hasNext()) {
                        Object next = it.next();
                        if (next instanceof MouseDraggedRunnable) {
                            MouseDraggedRunnable mdr;
                            mdr = (MouseDraggedRunnable)next;
                            MouseEvent mev = mdr.event;
                            if (mev.getModifiers() == e.getModifiers()) {
                                mdr.event = e;
                            }
                            return;
                        }
                    }
                }

                rq.invokeLater(new MouseDraggedRunnable(e));
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchMouseMoved(MouseEvent e) {
            if (!isInteractiveDocument) {
                super.dispatchMouseMoved(e);
                return;
            }

            class MouseMovedRunnable implements Runnable {
                MouseEvent event;
                MouseMovedRunnable(MouseEvent evt) {
                    event = evt;
                }
                public void run() {
                    eventDispatcher.mouseMoved(event);
                }
            }

            if (updateManager != null && updateManager.isRunning()) {
                RunnableQueue rq = updateManager.getUpdateRunnableQueue();

                // Events compression.
                int i = 0;
                synchronized (rq.getIteratorLock()) {
                    Iterator it = rq.iterator();
                    while (it.hasNext()) {
                        Object next = it.next();
                        if (next instanceof MouseMovedRunnable) {
                            MouseMovedRunnable mmr;
                            mmr = (MouseMovedRunnable)next;
                            MouseEvent mev = mmr.event;
                            if (mev.getModifiers() == e.getModifiers()) {
                                mmr.event = e;
                            }
                            return;
                        }
                        i++;
                    }

                }

                rq.invokeLater(new MouseMovedRunnable(e));
            }
        }

        /**
         * Dispatches the event to the GVT tree.
         */
        protected void dispatchMouseWheelMoved(final MouseWheelEvent e) {
            if (!isInteractiveDocument) {
                super.dispatchMouseWheelMoved(e);
                return;
            }

            if (updateManager != null && updateManager.isRunning()) {
                updateManager.getUpdateRunnableQueue().invokeLater
                    (new Runnable() {
                        public void run() {
                            eventDispatcher.mouseWheelMoved(e);
                        }
                    });
            }
        }
    }

    /**
     * Creates a UserAgent.
     */
    protected UserAgent createUserAgent() {
        return new BridgeUserAgent();
    }

    /**
     * The user-agent wrapper, which call the methods in the event thread.
     */
    protected static class BridgeUserAgentWrapper implements UserAgent {

        /**
         * The wrapped user agent.
         */
        protected UserAgent userAgent;

        /**
         * Creates a new BridgeUserAgentWrapper.
         */
        public BridgeUserAgentWrapper(UserAgent ua) {
            userAgent = ua;
        }

        /**
         * Returns the event dispatcher to use.
         */
        public EventDispatcher getEventDispatcher() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getEventDispatcher();
            } else {
                class Query implements Runnable {
                    EventDispatcher result;
                    public void run() {
                        result = userAgent.getEventDispatcher();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns the default size of the viewport.
         */
        public Dimension2D getViewportSize() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getViewportSize();
            } else {
                class Query implements Runnable {
                    Dimension2D result;
                    public void run() {
                        result = userAgent.getViewportSize();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Displays an error resulting from the specified Exception.
         */
        public void displayError(final Exception ex) {
            if (EventQueue.isDispatchThread()) {
                userAgent.displayError(ex);
            } else {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            userAgent.displayError(ex);
                        }
                    });
            }
        }

        /**
         * Displays a message in the User Agent interface.
         */
        public void displayMessage(final String message) {
            if (EventQueue.isDispatchThread()) {
                userAgent.displayMessage(message);
            } else {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            userAgent.displayMessage(message);
                        }
                    });
            }
        }

        /**
         * Shows an alert dialog box.
         */
        public void showAlert(final String message) {
            if (EventQueue.isDispatchThread()) {
                userAgent.showAlert(message);
            } else {
                invokeAndWait(new Runnable() {
                        public void run() {
                            userAgent.showAlert(message);
                        }
                    });
            }
        }

        /**
         * Shows a prompt dialog box.
         */
        public String showPrompt(final String message) {
            if (EventQueue.isDispatchThread()) {
                return userAgent.showPrompt(message);
            } else {
                class Query implements Runnable {
                    String result;
                    public void run() {
                        result = userAgent.showPrompt(message);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Shows a prompt dialog box.
         */
        public String showPrompt(final String message,
                                 final String defaultValue) {
            if (EventQueue.isDispatchThread()) {
                return userAgent.showPrompt(message, defaultValue);
            } else {
                class Query implements Runnable {
                    String result;
                    public void run() {
                        result = userAgent.showPrompt(message, defaultValue);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Shows a confirm dialog box.
         */
        public boolean showConfirm(final String message) {
            if (EventQueue.isDispatchThread()) {
                return userAgent.showConfirm(message);
            } else {
                class Query implements Runnable {
                    boolean result;
                    public void run() {
                        result = userAgent.showConfirm(message);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns the size of a px CSS unit in millimeters.
         */
        public float getPixelUnitToMillimeter() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getPixelUnitToMillimeter();
            } else {
                class Query implements Runnable {
                    float result;
                    public void run() {
                        result = userAgent.getPixelUnitToMillimeter();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns the size of a px CSS unit in millimeters.
         * This will be removed after next release.
         * @see #getPixelUnitToMillimeter()
         */
        public float getPixelToMM() { return getPixelUnitToMillimeter(); }


        /**
         * Returns the default font family.
         */
        public String getDefaultFontFamily() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getDefaultFontFamily();
            } else {
                class Query implements Runnable {
                    String result;
                    public void run() {
                        result = userAgent.getDefaultFontFamily();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        public float getMediumFontSize() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getMediumFontSize();
            } else {
                class Query implements Runnable {
                    float result;
                    public void run() {
                        result = userAgent.getMediumFontSize();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        public float getLighterFontWeight(float f) {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getLighterFontWeight(f);
            } else {
                final float ff = f;
                class Query implements Runnable {
                    float result;
                    public void run() {
                        result = userAgent.getLighterFontWeight(ff);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        public float getBolderFontWeight(float f) {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getBolderFontWeight(f);
            } else {
                final float ff = f;
                class Query implements Runnable {
                    float result;
                    public void run() {
                        result = userAgent.getBolderFontWeight(ff);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns the language settings.
         */
        public String getLanguages() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getLanguages();
            } else {
                class Query implements Runnable {
                    String result;
                    public void run() {
                        result = userAgent.getLanguages();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns the user stylesheet uri.
         * @return null if no user style sheet was specified.
         */
        public String getUserStyleSheetURI() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getUserStyleSheetURI();
            } else {
                class Query implements Runnable {
                    String result;
                    public void run() {
                        result = userAgent.getUserStyleSheetURI();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Opens a link.
         * @param elt The activated link element.
         */
        public void openLink(final SVGAElement elt) {
            if (EventQueue.isDispatchThread()) {
                userAgent.openLink(elt);
            } else {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            userAgent.openLink(elt);
                        }
                    });
            }
        }

        /**
         * Informs the user agent to change the cursor.
         * @param cursor the new cursor
         */
        public void setSVGCursor(final Cursor cursor) {
            if (EventQueue.isDispatchThread()) {
                userAgent.setSVGCursor(cursor);
            } else {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            userAgent.setSVGCursor(cursor);
                        }
                    });
            }
        }

        /**
         * Informs the user agent that the text selection should be changed.
         * @param start The Mark for the start of the selection.
         * @param end   The Mark for the end of the selection.
         */
        public void setTextSelection(final Mark start, final Mark end) {
            if (EventQueue.isDispatchThread()) {
                userAgent.setTextSelection(start, end);
            } else {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            userAgent.setTextSelection(start, end);
                        }
                    });
            }
        }

        /**
         * Informs the user agent that the text should be deselected.
         */
        public void deselectAll() {
            if (EventQueue.isDispatchThread()) {
                userAgent.deselectAll();
            } else {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            userAgent.deselectAll();
                        }
                    });
            }
        }

        /**
         * Returns the class name of the XML parser.
         */
        public String getXMLParserClassName() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getXMLParserClassName();
            } else {
                class Query implements Runnable {
                    String result;
                    public void run() {
                        result = userAgent.getXMLParserClassName();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns true if the XML parser must be in validation mode, false
         * otherwise.
         */
        public boolean isXMLParserValidating() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.isXMLParserValidating();
            } else {
                class Query implements Runnable {
                    boolean result;
                    public void run() {
                        result = userAgent.isXMLParserValidating();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns the <code>AffineTransform</code> currently
         * applied to the drawing by the UserAgent.
         */
        public AffineTransform getTransform() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getTransform();
            } else {
                class Query implements Runnable {
                    AffineTransform result;
                    public void run() {
                        result = userAgent.getTransform();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Sets the <code>AffineTransform</code> to be
         * applied to the drawing by the UserAgent.
         */
        public void setTransform(AffineTransform at) {
            if (EventQueue.isDispatchThread()) {
                userAgent.setTransform(at);
            } else {
                final AffineTransform affine = at;
                class Query implements Runnable {
                    public void run() {
                        userAgent.setTransform(affine);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
            }
        }

        /**
         * Returns this user agent's CSS media.
         */
        public String getMedia() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getMedia();
            } else {
                class Query implements Runnable {
                    String result;
                    public void run() {
                        result = userAgent.getMedia();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns this user agent's alternate style-sheet title.
         */
        public String getAlternateStyleSheet() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getAlternateStyleSheet();
            } else {
                class Query implements Runnable {
                    String result;
                    public void run() {
                        result = userAgent.getAlternateStyleSheet();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Returns the location on the screen of the
         * client area in the UserAgent.
         */
        public Point getClientAreaLocationOnScreen() {
            if (EventQueue.isDispatchThread()) {
                return userAgent.getClientAreaLocationOnScreen();
            } else {
                class Query implements Runnable {
                    Point result;
                    public void run() {
                        result = userAgent.getClientAreaLocationOnScreen();
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Tells whether the given feature is supported by this
         * user agent.
         */
        public boolean hasFeature(final String s) {
            if (EventQueue.isDispatchThread()) {
                return userAgent.hasFeature(s);
            } else {
                class Query implements Runnable {
                    boolean result;
                    public void run() {
                        result = userAgent.hasFeature(s);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Tells whether the given extension is supported by this
         * user agent.
         */
        public boolean supportExtension(final String s) {
            if (EventQueue.isDispatchThread()) {
                return userAgent.supportExtension(s);
            } else {
                class Query implements Runnable {
                    boolean result;
                    public void run() {
                        result = userAgent.supportExtension(s);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * Lets the bridge tell the user agent that the following
         * extension is supported by the bridge.
         */
        public void registerExtension(final BridgeExtension ext) {
            if (EventQueue.isDispatchThread()) {
                userAgent.registerExtension(ext);
            } else {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            userAgent.registerExtension(ext);
                        }
                    });
            }
        }

        /**
         * Notifies the UserAgent that the input element
         * has been found in the document. This is sometimes
         * called, for example, to handle &lt;a&gt; or
         * &lt;title&gt; elements in a UserAgent-dependant
         * way.
         */
        public void handleElement(final Element elt, final Object data) {
            if (EventQueue.isDispatchThread()) {
                userAgent.handleElement(elt, data);
            } else {
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            userAgent.handleElement(elt, data);
                        }
                    });
            }
        }

        /**
         * Returns the security settings for the given script
         * type, script url and document url
         *
         * @param scriptType type of script, as found in the
         *        type attribute of the &lt;script&gt; element.
         * @param scriptPURL url for the script, as defined in
         *        the script's xlink:href attribute. If that
         *        attribute was empty, then this parameter should
         *        be null
         * @param docPURL url for the document into which the
         *        script was found.
         */
        public ScriptSecurity getScriptSecurity(String scriptType,
                                                ParsedURL scriptPURL,
                                                ParsedURL docPURL){
            if (EventQueue.isDispatchThread()) {
                return userAgent.getScriptSecurity(scriptType,
                                                   scriptPURL,
                                                   docPURL);
            } else {
                final String st = scriptType;
                final ParsedURL sPURL= scriptPURL;
                final ParsedURL dPURL= docPURL;
                class Query implements Runnable {
                    ScriptSecurity result;
                    public void run() {
                        result = userAgent.getScriptSecurity(st, sPURL, dPURL);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * This method throws a SecurityException if the script
         * of given type, found at url and referenced from docURL
         * should not be loaded.
         *
         * This is a convenience method to call checkLoadScript
         * on the ScriptSecurity strategy returned by
         * getScriptSecurity.
         *
         * @param scriptType type of script, as found in the
         *        type attribute of the &lt;script&gt; element.
         * @param scriptPURL url for the script, as defined in
         *        the script's xlink:href attribute. If that
         *        attribute was empty, then this parameter should
         *        be null
         * @param docPURL url for the document into which the
         *        script was found.
         */
        public void checkLoadScript(String scriptType,
                                    ParsedURL scriptPURL,
                                    ParsedURL docPURL) throws SecurityException {
            if (EventQueue.isDispatchThread()) {
                userAgent.checkLoadScript(scriptType,
                                          scriptPURL,
                                          docPURL);
            } else {
                final String st = scriptType;
                final ParsedURL sPURL= scriptPURL;
                final ParsedURL dPURL= docPURL;
                class Query implements Runnable {
                    SecurityException se = null;
                    public void run() {
                        try {
                            userAgent.checkLoadScript(st, sPURL, dPURL);
                        } catch (SecurityException se) {
                            this.se = se;
                        }
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                if (q.se != null) {
                    q.se.fillInStackTrace();
                    throw q.se;
                }
            }
        }


        /**
         * Returns the security settings for the given resource
         * url and document url
         *
         * @param resourcePURL url for the resource, as defined in
         *        the resource's xlink:href attribute. If that
         *        attribute was empty, then this parameter should
         *        be null
         * @param docPURL url for the document into which the
         *        resource was found.
         */
        public ExternalResourceSecurity
            getExternalResourceSecurity(ParsedURL resourcePURL,
                                        ParsedURL docPURL){
            if (EventQueue.isDispatchThread()) {
                return userAgent.getExternalResourceSecurity(resourcePURL,
                                                             docPURL);
            } else {
                final ParsedURL rPURL= resourcePURL;
                final ParsedURL dPURL= docPURL;
                class Query implements Runnable {
                    ExternalResourceSecurity result;
                    public void run() {
                        result = userAgent.getExternalResourceSecurity(rPURL, dPURL);
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                return q.result;
            }
        }

        /**
         * This method throws a SecurityException if the resource
         * found at url and referenced from docURL
         * should not be loaded.
         *
         * This is a convenience method to call checkLoadExternalResource
         * on the ExternalResourceSecurity strategy returned by
         * getExternalResourceSecurity.
         *
         * @param resourceURL url for the resource, as defined in
         *        the resource's xlink:href attribute. If that
         *        attribute was empty, then this parameter should
         *        be null
         * @param docURL url for the document into which the
         *        resource was found.
         */
        public void
            checkLoadExternalResource(ParsedURL resourceURL,
                                      ParsedURL docURL) throws SecurityException {
            if (EventQueue.isDispatchThread()) {
                userAgent.checkLoadExternalResource(resourceURL,
                                                    docURL);
            } else {
                final ParsedURL rPURL= resourceURL;
                final ParsedURL dPURL= docURL;
                class Query implements Runnable {
                    SecurityException se;
                    public void run() {
                        try {
                            userAgent.checkLoadExternalResource(rPURL, dPURL);
                        } catch (SecurityException se) {
                            this.se = se;
                        }
                    }
                }
                Query q = new Query();
                invokeAndWait(q);
                if (q.se != null) {
                    q.se.fillInStackTrace();
                    throw q.se;
                }
            }
        }


        /**
         * This Implementation simply forwards the request to the AWT thread.
         *
         * @param e   The <image> element that can't be loaded.
         * @param url The resolved url that can't be loaded.
         * @param msg As best as can be determined the reason it can't be
         *            loaded (not available, corrupt, unknown format,...).
         */
        public SVGDocument getBrokenLinkDocument(final Element e,
                                                 final String url,
                                                 final String msg) {
            if (EventQueue.isDispatchThread())
                return userAgent.getBrokenLinkDocument(e, url, msg);

            class Query implements Runnable {
                SVGDocument doc;
                RuntimeException rex = null;
                public void run() {
                    try {
                        doc = userAgent.getBrokenLinkDocument(e, url, msg);
                    } catch (RuntimeException re) { rex = re; }
                }
            }
            Query q = new Query();
            invokeAndWait(q);
            if (q.rex != null) throw q.rex;
            return q.doc;
        }


        /**
         * Invokes the given runnable from the event thread, and wait
         * for the run method to terminate.
         */
        protected void invokeAndWait(Runnable r) {
            try {
                EventQueue.invokeAndWait(r);
            } catch (Exception e) {
            }
        }

        /**
         * This method should load a new document described by the supplied URL.
         *
         * @param url The url to be loaded as a string.
         */
        public void loadDocument(String url) {
            userAgent.loadDocument(url);
        }

        public FontFamilyResolver getFontFamilyResolver() {
            return userAgent.getFontFamilyResolver();
        }
    }

    /**
     * To hide the user-agent methods.
     */
    protected class BridgeUserAgent implements UserAgent {

        /**
         * Creates a new user agent.
         */
        protected BridgeUserAgent() {
        }

        /**
         * Returns the default size of the viewport of this user agent (0, 0).
         */
        public Dimension2D getViewportSize() {
            return getSize();
        }

        /**
         * Returns the <code>EventDispatcher</code> used by the
         * <code>UserAgent</code> to dispatch events on GVT.
         */
        public EventDispatcher getEventDispatcher() {
            return JSVGComponent.this.eventDispatcher;
        }

        /**
         * Displays an error message in the User Agent interface.
         */
        public void displayError(String message) {
            if (svgUserAgent != null) {
                svgUserAgent.displayError(message);
            }
        }

        /**
         * Displays an error resulting from the specified Exception.
         */
        public void displayError(Exception ex) {
            if (svgUserAgent != null) {
                svgUserAgent.displayError(ex);
            }
        }

        /**
         * Displays a message in the User Agent interface.
         */
        public void displayMessage(String message) {
            if (svgUserAgent != null) {
                svgUserAgent.displayMessage(message);
            }
        }

        /**
         * Shows an alert dialog box.
         */
        public void showAlert(String message) {
            if (svgUserAgent != null) {
                svgUserAgent.showAlert(message);
                return;
            }
            JSVGComponent.this.showAlert(message);
        }

        /**
         * Shows a prompt dialog box.
         */
        public String showPrompt(String message) {
            if (svgUserAgent != null) {
                return svgUserAgent.showPrompt(message);
            }
            return JSVGComponent.this.showPrompt(message);
        }

        /**
         * Shows a prompt dialog box.
         */
        public String showPrompt(String message, String defaultValue) {
            if (svgUserAgent != null) {
                return svgUserAgent.showPrompt(message, defaultValue);
            }
            return JSVGComponent.this.showPrompt
                (message, defaultValue);
        }

        /**
         * Shows a confirm dialog box.
         */
        public boolean showConfirm(String message) {
            if (svgUserAgent != null) {
                return svgUserAgent.showConfirm(message);
            }
            return JSVGComponent.this.showConfirm(message);
        }

        /**
         * Returns the size of a px CSS unit in millimeters.
         */
        public float getPixelUnitToMillimeter() {
            if (svgUserAgent != null) {
                return svgUserAgent.getPixelUnitToMillimeter();
            }
            return 0.264583333333333333333f; // 96 dpi
        }

        /**
         * Returns the size of a px CSS unit in millimeters.
         * This will be removed after next release.
         * @see #getPixelUnitToMillimeter()
         */
        public float getPixelToMM() { return getPixelUnitToMillimeter(); }

        /**
         * Returns the default font family.
         */
        public String getDefaultFontFamily() {
            if (svgUserAgent != null) {
                return svgUserAgent.getDefaultFontFamily();
            }
            return "Arial, Helvetica, sans-serif";
        }

        /**
         * Returns the  medium font size.
         */
        public float getMediumFontSize() {
            if (svgUserAgent != null) {
                return svgUserAgent.getMediumFontSize();
            }
            // 9pt (72pt = 1in)
            return 9f * 25.4f / (72f * getPixelUnitToMillimeter());
        }

        /**
         * Returns a lighter font-weight.
         */
        public float getLighterFontWeight(float f) {
            if (svgUserAgent != null) {
                return svgUserAgent.getLighterFontWeight(f);
            }
            // Round f to nearest 100...
            int weight = ((int)((f+50)/100))*100;
            switch (weight) {
            case 100: return 100;
            case 200: return 100;
            case 300: return 200;
            case 400: return 300;
            case 500: return 400;
            case 600: return 400;
            case 700: return 400;
            case 800: return 400;
            case 900: return 400;
            default:
                throw new IllegalArgumentException("Bad Font Weight: " + f);
            }
        }

        /**
         * Returns a bolder font-weight.
         */
        public float getBolderFontWeight(float f) {
            if (svgUserAgent != null) {
                return svgUserAgent.getBolderFontWeight(f);
            }
            // Round f to nearest 100...
            int weight = ((int)((f+50)/100))*100;
            switch (weight) {
            case 100: return 600;
            case 200: return 600;
            case 300: return 600;
            case 400: return 600;
            case 500: return 600;
            case 600: return 700;
            case 700: return 800;
            case 800: return 900;
            case 900: return 900;
            default:
                throw new IllegalArgumentException("Bad Font Weight: " + f);
            }
        }

        /**
         * Returns the language settings.
         */
        public String getLanguages() {
            if (svgUserAgent != null) {
                return svgUserAgent.getLanguages();
            }
            return "en";
        }

        /**
         * Returns the user stylesheet uri.
         * @return null if no user style sheet was specified.
         */
        public String getUserStyleSheetURI() {
            if (svgUserAgent != null) {
                return svgUserAgent.getUserStyleSheetURI();
            }
            return null;
        }

        /**
         * Opens a link.
         * @param elt The activated link element.
         */
        public void openLink(SVGAElement elt) {
            String show = XLinkSupport.getXLinkShow(elt);
            String href = elt.getHref().getAnimVal();
            if (show.equals("new")) {
                fireLinkActivatedEvent(elt, href);
                if (svgUserAgent != null) {
                    String oldURI = svgDocument.getURL();
                    ParsedURL newURI = null;
                    // if the anchor element is in an external resource
                    if (elt.getOwnerDocument() != svgDocument) {
                        SVGDocument doc = (SVGDocument)elt.getOwnerDocument();
                        href = new ParsedURL(doc.getURL(), href).toString();
                    }
                    newURI = new ParsedURL(oldURI, href);
                    href = newURI.toString();
                    svgUserAgent.openLink(href, true);
                } else {
                    JSVGComponent.this.loadSVGDocument(href);
                }
                return;
            }

            // Always use anchor element's document for base URI,
            // for when it comes from an external resource.
            ParsedURL newURI = new ParsedURL
                (((SVGDocument)elt.getOwnerDocument()).getURL(), href);

            // replace href with a fully resolved URI.
            href = newURI.toString();

            // Avoid reloading if possible.
            if (svgDocument != null) {

                ParsedURL oldURI = new ParsedURL(svgDocument.getURL());
                // Check if they reference the same file.
                if (newURI.sameFile(oldURI)) {
                    // They do, see if it's a new Fragment Ident.
                    String s = newURI.getRef();
                    if ((fragmentIdentifier != s) &&
                        ((s == null) || (!s.equals(fragmentIdentifier)))) {
                        // It is, so update rendering transform.
                        fragmentIdentifier = s;
                        if (computeRenderingTransform())
                            scheduleGVTRendering();
                    }
                    // Let every one know the link fired (but don't
                    // load doc, it's already loaded.).
                    fireLinkActivatedEvent(elt, href);
                    return;
                }
            }

            fireLinkActivatedEvent(elt, href);
            if (svgUserAgent != null) {
                svgUserAgent.openLink(href, false);
            } else {
                JSVGComponent.this.loadSVGDocument(href);
            }
        }

        /**
         * Fires a LinkActivatedEvent.
         */
        protected void fireLinkActivatedEvent(SVGAElement elt, String href) {
            Object[] ll = linkActivationListeners.toArray();

            if (ll.length > 0) {
                LinkActivationEvent ev;
                ev = new LinkActivationEvent(JSVGComponent.this, elt, href);

                for (int i = 0; i < ll.length; i++) {
                    LinkActivationListener l = (LinkActivationListener)ll[i];
                    l.linkActivated(ev);
                }
            }
        }

        /**
         * Informs the user agent to change the cursor.
         * @param cursor the new cursor
         */
        public void setSVGCursor(Cursor cursor) {
            if (cursor != JSVGComponent.this.getCursor())
                JSVGComponent.this.setCursor(cursor);
        }

        /**
         * Informs the user agent that the text selection has changed.
         * @param start The Mark for the start of the selection.
         * @param end   The Mark for the end of the selection.
         */
        public void setTextSelection(Mark start, Mark end) {
            JSVGComponent.this.select(start, end);
        }

        /**
         * Informs the user agent that the text selection should be
         * cleared.
         */
        public void deselectAll() {
            JSVGComponent.this.deselectAll();
        }

        /**
         * Returns the class name of the XML parser.
         */
        public String getXMLParserClassName() {
            if (svgUserAgent != null) {
                return svgUserAgent.getXMLParserClassName();
            }
            return XMLResourceDescriptor.getXMLParserClassName();
        }

        /**
         * Returns true if the XML parser must be in validation mode, false
         * otherwise depending on the SVGUserAgent.
         */
        public boolean isXMLParserValidating() {
            if (svgUserAgent != null) {
                return svgUserAgent.isXMLParserValidating();
            }
            return false;
        }

        /**
         * Returns the <code>AffineTransform</code> currently
         * applied to the drawing by the UserAgent.
         */
        public AffineTransform getTransform() {
            return JSVGComponent.this.renderingTransform;
        }

        /**
         * Sets the <code>AffineTransform</code> to be
         * applied to the drawing by the UserAgent.
         */
        public void setTransform(AffineTransform at) {
            JSVGComponent.this.setRenderingTransform(at);
        }

        /**
         * Returns this user agent's CSS media.
         */
        public String getMedia() {
            if (svgUserAgent != null) {
                return svgUserAgent.getMedia();
            }
            return "screen";
        }

        /**
         * Returns this user agent's alternate style-sheet title.
         */
        public String getAlternateStyleSheet() {
            if (svgUserAgent != null) {
                return svgUserAgent.getAlternateStyleSheet();
            }
            return null;
        }

        /**
         * Returns the location on the screen of the
         * client area in the UserAgent.
         */
        public Point getClientAreaLocationOnScreen() {
            return getLocationOnScreen();
        }

        /**
         * Tells whether the given feature is supported by this
         * user agent.
         */
        public boolean hasFeature(String s) {
            return FEATURES.contains(s);
        }

        protected Map extensions = new HashMap();

        /**
         * Tells whether the given extension is supported by this
         * user agent.
         */
        public boolean supportExtension(String s) {
            if ((svgUserAgent != null) &&
                (svgUserAgent.supportExtension(s)))
                return true;

            return extensions.containsKey(s);
        }

        /**
         * Lets the bridge tell the user agent that the following
         * extension is supported by the bridge.
         */
        public void registerExtension(BridgeExtension ext) {
            Iterator i = ext.getImplementedExtensions();
            while (i.hasNext())
                extensions.put(i.next(), ext);
        }


        /**
         * Notifies the UserAgent that the input element
         * has been found in the document. This is sometimes
         * called, for example, to handle &lt;a&gt; or
         * &lt;title&gt; elements in a UserAgent-dependant
         * way.
         */
        public void handleElement(Element elt, Object data) {
            if (svgUserAgent != null) {
                svgUserAgent.handleElement(elt, data);
            }
        }

        /**
         * Returns the security settings for the given script
         * type, script url and document url
         *
         * @param scriptType type of script, as found in the
         *        type attribute of the &lt;script&gt; element.
         * @param scriptURL url for the script, as defined in
         *        the script's xlink:href attribute. If that
         *        attribute was empty, then this parameter should
         *        be null
         * @param docURL url for the document into which the
         *        script was found.
         */
        public ScriptSecurity getScriptSecurity(String scriptType,
                                                ParsedURL scriptURL,
                                                ParsedURL docURL){
            if (svgUserAgent != null){
                return svgUserAgent.getScriptSecurity(scriptType,
                                                      scriptURL,
                                                      docURL);
            } else {
                return new DefaultScriptSecurity(scriptType,
                                                 scriptURL,
                                                 docURL);
            }
        }

        /**
         * This method throws a SecurityException if the script
         * of given type, found at url and referenced from docURL
         * should not be loaded.
         *
         * This is a convenience method to call checkLoadScript
         * on the ScriptSecurity strategy returned by
         * getScriptSecurity.
         *
         * @param scriptType type of script, as found in the
         *        type attribute of the &lt;script&gt; element.
         * @param scriptURL url for the script, as defined in
         *        the script's xlink:href attribute. If that
         *        attribute was empty, then this parameter should
         *        be null
         * @param docURL url for the document into which the
         *        script was found.
         */
        public void checkLoadScript(String scriptType,
                                    ParsedURL scriptURL,
                                    ParsedURL docURL) throws SecurityException {
            if (svgUserAgent != null) {
                svgUserAgent.checkLoadScript(scriptType,
                                             scriptURL,
                                             docURL);
            } else {
                ScriptSecurity s = getScriptSecurity(scriptType,
                                                     scriptURL,
                                                     docURL);
                if (s != null) {
                    s.checkLoadScript();
                }
            }
        }

        /**
         * Returns the security settings for the given
         * resource url and document url
         *
         * @param resourceURL url for the script, as defined in
         *        the resource's xlink:href attribute. If that
         *        attribute was empty, then this parameter should
         *        be null
         * @param docURL url for the document into which the
         *        script was found.
         */
        public ExternalResourceSecurity
            getExternalResourceSecurity(ParsedURL resourceURL,
                                        ParsedURL docURL){
            if (svgUserAgent != null){
                return svgUserAgent.getExternalResourceSecurity(resourceURL,
                                                                docURL);
            } else {
                return new RelaxedExternalResourceSecurity(resourceURL,
                                                           docURL);
            }
        }

        /**
         * This method throws a SecurityException if the resource
         * found at url and referenced from docURL
         * should not be loaded.
         *
         * This is a convenience method to call checkLoadExternalResource
         * on the ExternalResourceSecurity strategy returned by
         * getExternalResourceSecurity.
         *
         * @param resourceURL url for the resource, as defined in
         *        the resource's xlink:href attribute. If that
         *        attribute was empty, then this parameter should
         *        be null
         * @param docURL url for the document into which the
         *        resource was found.
         */
        public void
            checkLoadExternalResource(ParsedURL resourceURL,
                                      ParsedURL docURL) throws SecurityException {
            if (svgUserAgent != null) {
                svgUserAgent.checkLoadExternalResource(resourceURL,
                                                       docURL);
            } else {
                ExternalResourceSecurity s
                    =  getExternalResourceSecurity(resourceURL, docURL);

                if (s != null) {
                    s.checkLoadExternalResource();
                }
            }
        }

        /**
         * This implementation provides a true SVG Document that it
         * annotates with some information about why the real document
         * can't be loaded (unfortunately right now tool tips are broken
         * for content referenced by images so you can't actually see
         * the info).
         *
         * @param e   The &lt;image> element that can't be loaded.
         * @param url The resolved url that can't be loaded.
         * @param message As best as can be determined the reason it can't be
         *                loaded (not available, corrupt, unknown format,...).
         */
        public SVGDocument getBrokenLinkDocument(Element e,
                                                 String url,
                                                 String message) {
            Class cls = JSVGComponent.class;
            URL blURL = cls.getResource("resources/BrokenLink.svg");
            if (blURL == null)
                throw new BridgeException
                    (bridgeContext, e, ErrorConstants.ERR_URI_IMAGE_BROKEN,
                     new Object[] { url, message });

            DocumentLoader loader  = bridgeContext.getDocumentLoader();
            SVGDocument    doc = null;

            try {
                doc  = (SVGDocument)loader.loadDocument(blURL.toString());
                if (doc == null) return doc;

                DOMImplementation impl;
                impl = SVGDOMImplementation.getDOMImplementation();
                doc  = (SVGDocument)DOMUtilities.deepCloneDocument(doc, impl);

                String title;
                Element infoE, titleE, descE;
                infoE = doc.getElementById("__More_About");
                if (infoE == null) return doc;

                titleE = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
                                            SVGConstants.SVG_TITLE_TAG);
                title = Messages.formatMessage(BROKEN_LINK_TITLE, null);
                titleE.appendChild(doc.createTextNode(title));

                descE = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
                                           SVGConstants.SVG_DESC_TAG);
                descE.appendChild(doc.createTextNode(message));

                infoE.insertBefore(descE, infoE.getFirstChild());
                infoE.insertBefore(titleE, descE);
            } catch (Exception ex) {
                throw new BridgeException
                    (bridgeContext, e, ex, ErrorConstants.ERR_URI_IMAGE_BROKEN,
                     new Object[] {url, message });
            }
            return doc;
        }

        /**
         * This method should load a new document described by the supplied URL.
         *
         * @param url The url to be loaded as a string.
         */
        public void loadDocument(String url) {
            JSVGComponent.this.loadSVGDocument(url);
        }

        public FontFamilyResolver getFontFamilyResolver() {
            return DefaultFontFamilyResolver.SINGLETON;
        }
    }

    protected static final Set FEATURES = new HashSet();
    static {
        SVGFeatureStrings.addSupportedFeatureStrings(FEATURES);
    }
}
