You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by jm...@apache.org on 2013/10/08 16:03:20 UTC

[05/62] [abbrv] [partial] Merged Apache Flex 4.9.0 release branch

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeContext.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeContext.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeContext.java
new file mode 100644
index 0000000..3d618d7
--- /dev/null
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeContext.java
@@ -0,0 +1,553 @@
+/*
+
+   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.flex.forks.batik.bridge.svg12;
+
+import java.util.Iterator;
+
+import org.apache.flex.forks.batik.bridge.BridgeContext;
+import org.apache.flex.forks.batik.bridge.BridgeUpdateHandler;
+import org.apache.flex.forks.batik.bridge.DocumentLoader;
+import org.apache.flex.forks.batik.bridge.ScriptingEnvironment;
+import org.apache.flex.forks.batik.bridge.URIResolver;
+import org.apache.flex.forks.batik.bridge.UserAgent;
+import org.apache.flex.forks.batik.css.engine.CSSEngine;
+import org.apache.flex.forks.batik.dom.AbstractDocument;
+import org.apache.flex.forks.batik.dom.AbstractNode;
+import org.apache.flex.forks.batik.dom.events.EventSupport;
+import org.apache.flex.forks.batik.dom.events.NodeEventTarget;
+import org.apache.flex.forks.batik.dom.svg.SVGOMDocument;
+import org.apache.flex.forks.batik.dom.svg12.XBLEventSupport;
+import org.apache.flex.forks.batik.dom.svg12.XBLOMShadowTreeElement;
+import org.apache.flex.forks.batik.dom.xbl.NodeXBL;
+import org.apache.flex.forks.batik.dom.xbl.XBLManager;
+import org.apache.flex.forks.batik.script.Interpreter;
+import org.apache.flex.forks.batik.script.InterpreterPool;
+import org.apache.flex.forks.batik.util.SVGConstants;
+import org.apache.flex.forks.batik.util.XMLConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.events.Event;
+import org.w3c.dom.events.EventListener;
+import org.w3c.dom.events.EventTarget;
+import org.w3c.dom.svg.SVGDocument;
+
+/**
+ * Bridge context for SVG 1.2 documents.  This is primarily for dispatching
+ * XBL events to bridges and for handling resource documents.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id: SVG12BridgeContext.java 502489 2007-02-02 04:57:56Z cam $
+ */
+public class SVG12BridgeContext extends BridgeContext {
+
+    /**
+     * The BindingListener for XBL binding events.
+     */
+    protected XBLBindingListener bindingListener;
+
+    /**
+     * The ContentSelectionChangedListener for xbl:content element events.
+     */
+    protected XBLContentListener contentListener;
+
+    /**
+     * The EventTarget that has the mouse capture.
+     */
+    protected EventTarget mouseCaptureTarget;
+
+    /**
+     * Whether the mouse capture event target will receive events
+     * that do not intersect with its geometry.
+     */
+    protected boolean mouseCaptureSendAll;
+
+    /**
+     * Whether the mouse capture will be released on mouse up.
+     */
+    protected boolean mouseCaptureAutoRelease;
+
+    /**
+     * Constructs a new bridge context.
+     * @param userAgent the user agent
+     */
+    public SVG12BridgeContext(UserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Constructs a new bridge context.
+     * @param userAgent the user agent
+     * @param loader document loader
+     */
+    public SVG12BridgeContext(UserAgent userAgent,
+                              DocumentLoader loader) {
+        super(userAgent, loader);
+    }
+
+    /**
+     * Constructs a new bridge context.
+     * @param userAgent the user agent
+     * @param interpreterPool the interpreter pool
+     * @param documentLoader document loader
+     */
+    public SVG12BridgeContext(UserAgent userAgent,
+                              InterpreterPool interpreterPool,
+                              DocumentLoader documentLoader) {
+        super(userAgent, interpreterPool, documentLoader);
+    }
+
+    /**
+     * Returns a new URIResolver object.
+     */
+    public URIResolver createURIResolver(SVGDocument doc, DocumentLoader dl) {
+        return new SVG12URIResolver(doc, dl);
+    }
+
+    /**
+     * Adds the GVT listener for AWT event support.
+     */
+    public void addGVTListener(Document doc) {
+        SVG12BridgeEventSupport.addGVTListener(this, doc);
+    }
+
+    /**
+     * Disposes this BridgeContext.
+     */
+    public void dispose() {
+        clearChildContexts();
+
+        synchronized (eventListenerSet) {
+            // remove all listeners added by Bridges
+            Iterator iter = eventListenerSet.iterator();
+            while (iter.hasNext()) {
+                EventListenerMememto m = (EventListenerMememto)iter.next();
+                NodeEventTarget et = m.getTarget();
+                EventListener   el = m.getListener();
+                boolean         uc = m.getUseCapture();
+                String          t  = m.getEventType();
+                boolean         in = m.getNamespaced();
+                if (et == null || el == null || t == null) {
+                    continue;
+                }
+                if (m instanceof ImplementationEventListenerMememto) {
+                    String ns = m.getNamespaceURI();
+                    Node nde = (Node)et;
+                    AbstractNode n = (AbstractNode)nde.getOwnerDocument();
+                    if (n != null) {
+                        XBLEventSupport es;
+                        es = (XBLEventSupport) n.initializeEventSupport();
+                        es.removeImplementationEventListenerNS(ns, t, el, uc);
+                    }
+                } else if (in) {
+                    String ns = m.getNamespaceURI();
+                    et.removeEventListenerNS(ns, t, el, uc);
+                } else {
+                    et.removeEventListener(t, el, uc);
+                }
+            }
+        }
+
+        if (document != null) {
+            removeDOMListeners();
+            removeBindingListener();
+        }
+
+        if (animationEngine != null) {
+            animationEngine.dispose();
+            animationEngine = null;
+        }
+
+        Iterator iter = interpreterMap.values().iterator();
+        while (iter.hasNext()) {
+            Interpreter interpreter = (Interpreter)iter.next();
+            if (interpreter != null)
+                interpreter.dispose();
+        }
+        interpreterMap.clear();
+
+        if (focusManager != null) {
+            focusManager.dispose();
+        }
+    }
+
+    /**
+     * Adds a BindingListener to the XBLManager for the document, so that
+     * XBL binding events can be passed on to the BridgeUpdateHandlers.
+     */
+    public void addBindingListener() {
+        AbstractDocument doc = (AbstractDocument) document;
+        DefaultXBLManager xm = (DefaultXBLManager) doc.getXBLManager();
+        if (xm != null) {
+            bindingListener = new XBLBindingListener();
+            xm.addBindingListener(bindingListener);
+            contentListener = new XBLContentListener();
+            xm.addContentSelectionChangedListener(contentListener);
+        }
+    }
+
+    /**
+     * Removes the BindingListener from the XBLManager.
+     */
+    public void removeBindingListener() {
+        AbstractDocument doc = (AbstractDocument) document;
+        XBLManager xm = doc.getXBLManager();
+        if (xm instanceof DefaultXBLManager) {
+            DefaultXBLManager dxm = (DefaultXBLManager) xm;
+            dxm.removeBindingListener(bindingListener);
+            dxm.removeContentSelectionChangedListener(contentListener);
+        }
+    }
+
+    /**
+     * Adds EventListeners to the DOM and CSSEngineListener to the
+     * CSSEngine to handle any modifications on the DOM tree or style
+     * properties and update the GVT tree in response.  This overriden
+     * method adds implementation event listeners, so that mutations in
+     * shadow trees can be caught.
+     */
+    public void addDOMListeners() {
+        SVGOMDocument doc = (SVGOMDocument)document;
+        XBLEventSupport evtSupport
+            = (XBLEventSupport) doc.initializeEventSupport();
+
+        domAttrModifiedEventListener
+            = new EventListenerWrapper(new DOMAttrModifiedEventListener());
+        evtSupport.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMAttrModified",
+             domAttrModifiedEventListener, true);
+
+        domNodeInsertedEventListener
+            = new EventListenerWrapper(new DOMNodeInsertedEventListener());
+        evtSupport.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMNodeInserted",
+             domNodeInsertedEventListener, true);
+
+        domNodeRemovedEventListener
+            = new EventListenerWrapper(new DOMNodeRemovedEventListener());
+        evtSupport.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMNodeRemoved",
+             domNodeRemovedEventListener, true);
+
+        domCharacterDataModifiedEventListener = 
+            new EventListenerWrapper(new DOMCharacterDataModifiedEventListener());
+        evtSupport.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMCharacterDataModified",
+             domCharacterDataModifiedEventListener, true);
+
+        animatedAttributeListener = new AnimatedAttrListener();
+        doc.addAnimatedAttributeListener(animatedAttributeListener);
+        
+        focusManager = new SVG12FocusManager(document);
+
+        CSSEngine cssEngine = doc.getCSSEngine();
+        cssPropertiesChangedListener = new CSSPropertiesChangedListener();
+        cssEngine.addCSSEngineListener(cssPropertiesChangedListener);
+    }
+
+    /**
+     * Adds EventListeners to the input document to handle the cursor 
+     * property.
+     * This is not done in the addDOMListeners method because 
+     * addDOMListeners is only used for dynamic content whereas 
+     * cursor support is provided for all content.
+     * Also note that it is very important that the listeners be
+     * registered for the capture phase as the 'default' behavior
+     * for cursors is handled by the BridgeContext during the 
+     * capture phase and the 'custom' behavior (handling of 'auto'
+     * on anchors, for example), is handled during the bubbling phase.
+     */
+    public void addUIEventListeners(Document doc) {
+        EventTarget evtTarget = (EventTarget)doc.getDocumentElement();
+        AbstractNode n = (AbstractNode) evtTarget;
+        XBLEventSupport evtSupport
+            = (XBLEventSupport) n.initializeEventSupport();
+
+        EventListener domMouseOverListener
+            = new EventListenerWrapper(new DOMMouseOverEventListener());
+        evtSupport.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             SVGConstants.SVG_EVENT_MOUSEOVER,
+             domMouseOverListener, true);
+        storeImplementationEventListenerNS
+            (evtTarget,
+             XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             SVGConstants.SVG_EVENT_MOUSEOVER,
+             domMouseOverListener, true);
+
+        EventListener domMouseOutListener
+            = new EventListenerWrapper(new DOMMouseOutEventListener());
+        evtSupport.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             SVGConstants.SVG_EVENT_MOUSEOUT,
+             domMouseOutListener, true);
+        storeImplementationEventListenerNS
+            (evtTarget,
+             XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             SVGConstants.SVG_EVENT_MOUSEOUT,
+             domMouseOutListener, true);
+    }
+
+    public void removeUIEventListeners(Document doc) {
+        EventTarget evtTarget = (EventTarget)doc.getDocumentElement();
+        AbstractNode n = (AbstractNode) evtTarget;
+        XBLEventSupport es = (XBLEventSupport) n.initializeEventSupport();
+
+        synchronized (eventListenerSet) {
+            Iterator i = eventListenerSet.iterator();
+            while (i.hasNext()) {
+                EventListenerMememto elm = (EventListenerMememto)i.next();
+                NodeEventTarget et = elm.getTarget();
+                if (et == evtTarget) {
+                    EventListener el = elm.getListener();
+                    boolean       uc = elm.getUseCapture();
+                    String        t  = elm.getEventType();
+                    boolean       in = elm.getNamespaced();
+                    if (et == null || el == null || t == null) {
+                        continue;
+                    }
+                    if (elm instanceof ImplementationEventListenerMememto) {
+                        String ns = elm.getNamespaceURI();
+                        es.removeImplementationEventListenerNS(ns, t, el, uc);
+                    } else if (in) {
+                        String ns = elm.getNamespaceURI();
+                        et.removeEventListenerNS(ns, t, el, uc);
+                    } else {
+                        et.removeEventListener(t, el, uc);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes event listeners from the DOM and CSS engine.
+     */
+    protected void removeDOMListeners() {
+        SVGOMDocument doc = (SVGOMDocument)document;
+
+        doc.removeEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMAttrModified",
+             domAttrModifiedEventListener, true);
+        doc.removeEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMNodeInserted",
+             domNodeInsertedEventListener, true);
+        doc.removeEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMNodeRemoved",
+             domNodeRemovedEventListener, true);
+        doc.removeEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMCharacterDataModified",
+             domCharacterDataModifiedEventListener, true);
+        
+        doc.removeAnimatedAttributeListener(animatedAttributeListener);
+
+        CSSEngine cssEngine = doc.getCSSEngine();
+        if (cssEngine != null) {
+            cssEngine.removeCSSEngineListener
+                (cssPropertiesChangedListener);
+            cssEngine.dispose();
+            doc.setCSSEngine(null);
+        }
+    }
+
+    /**
+     * Adds to the eventListenerSet the specified implementation event
+     * listener registration.
+     */
+    protected void storeImplementationEventListenerNS(EventTarget t,
+                                                      String ns,
+                                                      String s,
+                                                      EventListener l,
+                                                      boolean b) {
+        synchronized (eventListenerSet) {
+            ImplementationEventListenerMememto m
+                = new ImplementationEventListenerMememto(t, ns, s, l, b, this);
+            eventListenerSet.add(m);
+        }
+    }
+
+    public BridgeContext createSubBridgeContext(SVGOMDocument newDoc) {
+        CSSEngine eng = newDoc.getCSSEngine();
+        if (eng != null) {
+            return (BridgeContext)newDoc.getCSSEngine().getCSSContext();
+        }
+
+        BridgeContext subCtx = super.createSubBridgeContext(newDoc);
+        if (isDynamic() && subCtx.isDynamic()) {
+            setUpdateManager(subCtx, updateManager);
+            if (updateManager != null) {
+                ScriptingEnvironment se;
+                if (newDoc.isSVG12()) {
+                    se = new SVG12ScriptingEnvironment(subCtx);
+                } else {
+                    se = new ScriptingEnvironment(subCtx);
+                }
+                se.loadScripts();
+                se.dispatchSVGLoadEvent();
+                if (newDoc.isSVG12()) {
+                    DefaultXBLManager xm =
+                        new DefaultXBLManager(newDoc, subCtx);
+                    setXBLManager(subCtx, xm);
+                    newDoc.setXBLManager(xm);
+                    xm.startProcessing();
+                }
+            }
+        }
+        return subCtx;
+    }
+
+    /**
+     * Starts mouse capture.
+     */
+    public void startMouseCapture(EventTarget target, boolean sendAll,
+                                  boolean autoRelease) {
+        mouseCaptureTarget = target;
+        mouseCaptureSendAll = sendAll;
+        mouseCaptureAutoRelease = autoRelease;
+    }
+
+    /**
+     * Stops mouse capture.
+     */
+    public void stopMouseCapture() {
+        mouseCaptureTarget = null;
+    }
+
+    /**
+     * A class used to store an implementation EventListener added to the DOM.
+     */
+    protected static class ImplementationEventListenerMememto
+            extends EventListenerMememto {
+
+        /**
+         * Creates a new ImplementationEventListenerMememto.
+         */
+        public ImplementationEventListenerMememto(EventTarget t,
+                                                  String s,
+                                                  EventListener l,
+                                                  boolean b,
+                                                  BridgeContext c) {
+            super(t, s, l, b, c);
+        }
+
+        /**
+         * Creates a new ImplementationEventListenerMememto.
+         */
+        public ImplementationEventListenerMememto(EventTarget t,
+                                                  String n,
+                                                  String s,
+                                                  EventListener l,
+                                                  boolean b,
+                                                  BridgeContext c) {
+            super(t, n, s, l, b, c);
+        }
+    }
+
+    /**
+     * Wrapper for DOM event listeners so that they will see only
+     * original events (i.e., not retargetted).
+     */
+    protected class EventListenerWrapper implements EventListener {
+
+        /**
+         * The wrapped listener.
+         */
+        protected EventListener listener;
+
+        /**
+         * Creates a new EventListenerWrapper.
+         */
+        public EventListenerWrapper(EventListener l) {
+            listener = l;
+        }
+
+        /**
+         * Handles the event.
+         */
+        public void handleEvent(Event evt) {
+            listener.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+
+        /**
+         * String representation of this listener wrapper.
+         */
+        public String toString() {
+            return super.toString() + " [wrapping " + listener.toString() + "]";
+        }
+    }
+
+    /**
+     * The BindingListener.
+     */
+    protected class XBLBindingListener implements BindingListener {
+        
+        /**
+         * Invoked when the specified bindable element's binding has changed.
+         */
+        public void bindingChanged(Element bindableElement,
+                                   Element shadowTree) {
+            BridgeUpdateHandler h = getBridgeUpdateHandler(bindableElement);
+            if (h instanceof SVG12BridgeUpdateHandler) {
+                SVG12BridgeUpdateHandler h12 = (SVG12BridgeUpdateHandler) h;
+                try {
+                    h12.handleBindingEvent(bindableElement, shadowTree);
+                } catch (Exception e) {
+                    userAgent.displayError(e);
+                }
+            }
+        }
+    }
+
+    /**
+     * The ContentSelectionChangedListener.
+     */
+    protected class XBLContentListener
+            implements ContentSelectionChangedListener {
+        
+        /**
+         * Invoked after an xbl:content element has updated its selected
+         * nodes list.
+         * @param csce the ContentSelectionChangedEvent object
+         */
+        public void contentSelectionChanged(ContentSelectionChangedEvent csce) {
+            Element e = (Element) csce.getContentElement().getParentNode();
+            if (e instanceof XBLOMShadowTreeElement) {
+                e = ((NodeXBL) e).getXblBoundElement();
+            }
+            BridgeUpdateHandler h = getBridgeUpdateHandler(e);
+            if (h instanceof SVG12BridgeUpdateHandler) {
+                SVG12BridgeUpdateHandler h12 = (SVG12BridgeUpdateHandler) h;
+                try {
+                    h12.handleContentSelectionChangedEvent(csce);
+                } catch (Exception ex) {
+                    userAgent.displayError(ex);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeEventSupport.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeEventSupport.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeEventSupport.java
new file mode 100644
index 0000000..bbbc94b
--- /dev/null
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeEventSupport.java
@@ -0,0 +1,833 @@
+/*
+
+   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.flex.forks.batik.bridge.svg12;
+
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+import java.awt.geom.Point2D;
+
+import org.apache.flex.forks.batik.bridge.BridgeContext;
+import org.apache.flex.forks.batik.bridge.BridgeEventSupport;
+import org.apache.flex.forks.batik.bridge.FocusManager;
+import org.apache.flex.forks.batik.bridge.UserAgent;
+import org.apache.flex.forks.batik.dom.events.AbstractEvent;
+import org.apache.flex.forks.batik.dom.events.DOMKeyboardEvent;
+import org.apache.flex.forks.batik.dom.events.DOMMouseEvent;
+import org.apache.flex.forks.batik.dom.events.DOMTextEvent;
+import org.apache.flex.forks.batik.dom.events.NodeEventTarget;
+import org.apache.flex.forks.batik.dom.svg12.SVGOMWheelEvent;
+import org.apache.flex.forks.batik.dom.util.DOMUtilities;
+import org.apache.flex.forks.batik.gvt.GraphicsNode;
+import org.apache.flex.forks.batik.gvt.event.EventDispatcher;
+import org.apache.flex.forks.batik.gvt.event.GraphicsNodeKeyEvent;
+import org.apache.flex.forks.batik.gvt.event.GraphicsNodeMouseEvent;
+import org.apache.flex.forks.batik.gvt.event.GraphicsNodeMouseWheelEvent;
+import org.apache.flex.forks.batik.gvt.event.GraphicsNodeMouseWheelListener;
+import org.apache.flex.forks.batik.util.XMLConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.events.DocumentEvent;
+import org.w3c.dom.events.EventListener;
+import org.w3c.dom.events.EventTarget;
+
+/**
+ * This class is responsible for tracking GraphicsNodeMouseEvents and
+ * forwarding them to the DOM as regular DOM MouseEvents.  This SVG 1.2
+ * specific class handles DOM Level 3 keyboard events and also ensures
+ * that mouse events under sXBL have appropriate bubble limits.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id: SVG12BridgeEventSupport.java 575202 2007-09-13 07:45:18Z cam $
+ */
+public abstract class SVG12BridgeEventSupport extends BridgeEventSupport {
+
+    protected SVG12BridgeEventSupport() {}
+
+    /**
+     * Is called only for the root element in order to dispatch GVT
+     * events to the DOM.
+     */
+    public static void addGVTListener(BridgeContext ctx, Document doc) {
+        UserAgent ua = ctx.getUserAgent();
+        if (ua != null) {
+            EventDispatcher dispatcher = ua.getEventDispatcher();
+            if (dispatcher != null) {
+                final Listener listener = new Listener(ctx, ua);
+                dispatcher.addGraphicsNodeMouseListener(listener);
+                dispatcher.addGraphicsNodeMouseWheelListener(listener);
+                dispatcher.addGraphicsNodeKeyListener(listener);
+                // add an unload listener on the SVGDocument to remove
+                // that listener for dispatching events
+                EventListener l = new GVTUnloadListener(dispatcher, listener);
+                NodeEventTarget target = (NodeEventTarget) doc;
+                target.addEventListenerNS
+                    (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                     "SVGUnload",
+                     l, false, null);
+                storeEventListenerNS
+                    (ctx, target,
+                     XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                     "SVGUnload",
+                     l, false);
+            }
+        }
+    }
+
+    /**
+     * A GraphicsNodeMouseListener that dispatch DOM events accordingly.
+     */
+    protected static class Listener
+            extends BridgeEventSupport.Listener 
+            implements GraphicsNodeMouseWheelListener {
+
+        /**
+         * The BridgeContext downcasted to an SVG12BridgeContext.
+         */
+        protected SVG12BridgeContext ctx12;
+
+        public Listener(BridgeContext ctx, UserAgent u) {
+            super(ctx, u);
+            ctx12 = (SVG12BridgeContext) ctx;
+        }
+
+        // Key -------------------------------------------------------------
+
+        /**
+         * Invoked when a key has been pressed.
+         * @param evt the graphics node key event
+         */
+        public void keyPressed(GraphicsNodeKeyEvent evt) {
+            // XXX isDown is not preventing key repeats
+            if (!isDown) {
+                isDown = true;
+                dispatchKeyboardEvent("keydown", evt);
+            }
+            if (evt.getKeyChar() == KeyEvent.CHAR_UNDEFINED) {
+                // We will not get a KEY_TYPED event for this char
+                // so generate a keypress event here.
+                dispatchTextEvent(evt);
+            }
+        }
+
+        /**
+         * Invoked when a key has been released.
+         * @param evt the graphics node key event
+         */
+        public void keyReleased(GraphicsNodeKeyEvent evt) {
+            dispatchKeyboardEvent("keyup", evt);
+            isDown = false;
+        }
+
+        /**
+         * Invoked when a key has been typed.
+         * @param evt the graphics node key event
+         */
+        public void keyTyped(GraphicsNodeKeyEvent evt) {
+            dispatchTextEvent(evt);
+        }
+
+        /**
+         * Dispatch a DOM 3 Keyboard event.
+         */
+        protected void dispatchKeyboardEvent(String eventType,
+                                             GraphicsNodeKeyEvent evt) {
+            FocusManager fmgr = context.getFocusManager();
+            if (fmgr == null) {
+                return;
+            }
+
+            Element targetElement = (Element) fmgr.getCurrentEventTarget();
+            if (targetElement == null) {
+                targetElement = context.getDocument().getDocumentElement();
+            }
+            DocumentEvent d = (DocumentEvent) targetElement.getOwnerDocument();
+            DOMKeyboardEvent keyEvt
+                = (DOMKeyboardEvent) d.createEvent("KeyboardEvent");
+            String modifiers
+                = DOMUtilities.getModifiersList(evt.getLockState(),
+                                                evt.getModifiers());
+            keyEvt.initKeyboardEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                                       eventType, 
+                                       true,
+                                       true,
+                                       null,
+                                       mapKeyCodeToIdentifier(evt.getKeyCode()),
+                                       mapKeyLocation(evt.getKeyLocation()),
+                                       modifiers);
+
+            try {
+                ((EventTarget)targetElement).dispatchEvent(keyEvt);
+            } catch (RuntimeException e) {
+                ua.displayError(e);
+            }
+        }
+
+        /**
+         * Dispatch a DOM 3 Text event.
+         */
+        protected void dispatchTextEvent(GraphicsNodeKeyEvent evt) {
+            FocusManager fmgr = context.getFocusManager();
+            if (fmgr == null) {
+                return;
+            }
+
+            Element targetElement = (Element) fmgr.getCurrentEventTarget();
+            if (targetElement == null) {
+                targetElement = context.getDocument().getDocumentElement();
+            }
+            DocumentEvent d = (DocumentEvent) targetElement.getOwnerDocument();
+            DOMTextEvent textEvt = (DOMTextEvent) d.createEvent("TextEvent");
+            textEvt.initTextEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                                    "textInput", 
+                                    true,
+                                    true,
+                                    null,
+                                    String.valueOf(evt.getKeyChar()));
+
+            try {
+                ((EventTarget) targetElement).dispatchEvent(textEvt);
+            } catch (RuntimeException e) {
+                ua.displayError(e);
+            }
+        }
+
+        /**
+         * Maps Java KeyEvent location numbers to DOM 3 location numbers.
+         */
+        protected int mapKeyLocation(int location) {
+            return location - 1;
+        }
+
+        /**
+         * Array to hold the map of Java keycodes to DOM 3 key strings.
+         */
+        protected static String[][] IDENTIFIER_KEY_CODES = new String[256][];
+        static {
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_0,
+                                 KeyEvent.VK_0);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_1,
+                                 KeyEvent.VK_1);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_2,
+                                 KeyEvent.VK_2);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_3,
+                                 KeyEvent.VK_3);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_4,
+                                 KeyEvent.VK_4);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_5,
+                                 KeyEvent.VK_5);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_6,
+                                 KeyEvent.VK_6);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_7,
+                                 KeyEvent.VK_7);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_8,
+                                 KeyEvent.VK_8);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_9,
+                                 KeyEvent.VK_9);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ACCEPT,
+                                 KeyEvent.VK_ACCEPT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_AGAIN,
+                                 KeyEvent.VK_AGAIN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_A,
+                                 KeyEvent.VK_A);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ALL_CANDIDATES,
+                                 KeyEvent.VK_ALL_CANDIDATES);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ALPHANUMERIC,
+                                 KeyEvent.VK_ALPHANUMERIC);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ALT_GRAPH,
+                                 KeyEvent.VK_ALT_GRAPH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ALT,
+                                 KeyEvent.VK_ALT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_AMPERSAND,
+                                 KeyEvent.VK_AMPERSAND);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_APOSTROPHE,
+                                 KeyEvent.VK_QUOTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ASTERISK,
+                                 KeyEvent.VK_ASTERISK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_AT,
+                                 KeyEvent.VK_AT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_BACKSLASH,
+                                 KeyEvent.VK_BACK_SLASH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_BACKSPACE,
+                                 KeyEvent.VK_BACK_SPACE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_B,
+                                 KeyEvent.VK_B);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CANCEL,
+                                 KeyEvent.VK_CANCEL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CAPS_LOCK,
+                                 KeyEvent.VK_CAPS_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CIRCUMFLEX,
+                                 KeyEvent.VK_CIRCUMFLEX);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_C,
+                                 KeyEvent.VK_C);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CLEAR,
+                                 KeyEvent.VK_CLEAR);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CODE_INPUT,
+                                 KeyEvent.VK_CODE_INPUT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COLON,
+                                 KeyEvent.VK_COLON);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_ACUTE,
+                                 KeyEvent.VK_DEAD_ACUTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_BREVE,
+                                 KeyEvent.VK_DEAD_BREVE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_CARON,
+                                 KeyEvent.VK_DEAD_CARON);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_CEDILLA,
+                                 KeyEvent.VK_DEAD_CEDILLA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_CIRCUMFLEX,
+                                 KeyEvent.VK_DEAD_CIRCUMFLEX);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_DIERESIS,
+                                 KeyEvent.VK_DEAD_DIAERESIS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_DOT_ABOVE,
+                                 KeyEvent.VK_DEAD_ABOVEDOT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_DOUBLE_ACUTE,
+                                 KeyEvent.VK_DEAD_DOUBLEACUTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_GRAVE,
+                                 KeyEvent.VK_DEAD_GRAVE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_IOTA,
+                                 KeyEvent.VK_DEAD_IOTA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_MACRON,
+                                 KeyEvent.VK_DEAD_MACRON);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_OGONEK,
+                                 KeyEvent.VK_DEAD_OGONEK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_RING_ABOVE,
+                                 KeyEvent.VK_DEAD_ABOVERING);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_TILDE,
+                                 KeyEvent.VK_DEAD_TILDE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMMA,
+                                 KeyEvent.VK_COMMA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMPOSE,
+                                 KeyEvent.VK_COMPOSE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CONTROL,
+                                 KeyEvent.VK_CONTROL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CONVERT,
+                                 KeyEvent.VK_CONVERT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COPY,
+                                 KeyEvent.VK_COPY);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CUT,
+                                 KeyEvent.VK_CUT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_DELETE,
+                                 KeyEvent.VK_DELETE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_D,
+                                 KeyEvent.VK_D);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_DOLLAR,
+                                 KeyEvent.VK_DOLLAR);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_DOWN,
+                                 KeyEvent.VK_DOWN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_E,
+                                 KeyEvent.VK_E);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_END,
+                                 KeyEvent.VK_END);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ENTER,
+                                 KeyEvent.VK_ENTER);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_EQUALS,
+                                 KeyEvent.VK_EQUALS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ESCAPE,
+                                 KeyEvent.VK_ESCAPE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_EURO,
+                                 KeyEvent.VK_EURO_SIGN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_EXCLAMATION,
+                                 KeyEvent.VK_EXCLAMATION_MARK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F10,
+                                 KeyEvent.VK_F10);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F11,
+                                 KeyEvent.VK_F11);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F12,
+                                 KeyEvent.VK_F12);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F13,
+                                 KeyEvent.VK_F13);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F14,
+                                 KeyEvent.VK_F14);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F15,
+                                 KeyEvent.VK_F15);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F16,
+                                 KeyEvent.VK_F16);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F17,
+                                 KeyEvent.VK_F17);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F18,
+                                 KeyEvent.VK_F18);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F19,
+                                 KeyEvent.VK_F19);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F1,
+                                 KeyEvent.VK_F1);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F20,
+                                 KeyEvent.VK_F20);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F21,
+                                 KeyEvent.VK_F21);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F22,
+                                 KeyEvent.VK_F22);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F23,
+                                 KeyEvent.VK_F23);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F24,
+                                 KeyEvent.VK_F24);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F2,
+                                 KeyEvent.VK_F2);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F3,
+                                 KeyEvent.VK_F3);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F4,
+                                 KeyEvent.VK_F4);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F5,
+                                 KeyEvent.VK_F5);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F6,
+                                 KeyEvent.VK_F6);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F7,
+                                 KeyEvent.VK_F7);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F8,
+                                 KeyEvent.VK_F8);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F9,
+                                 KeyEvent.VK_F9);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FINAL_MODE,
+                                 KeyEvent.VK_FINAL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FIND,
+                                 KeyEvent.VK_FIND);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F,
+                                 KeyEvent.VK_F);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FULL_STOP,
+                                 KeyEvent.VK_PERIOD);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FULL_WIDTH,
+                                 KeyEvent.VK_FULL_WIDTH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_G,
+                                 KeyEvent.VK_G);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_GRAVE,
+                                 KeyEvent.VK_BACK_QUOTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_GREATER_THAN,
+                                 KeyEvent.VK_GREATER);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HALF_WIDTH,
+                                 KeyEvent.VK_HALF_WIDTH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HASH,
+                                 KeyEvent.VK_NUMBER_SIGN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HELP,
+                                 KeyEvent.VK_HELP);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HIRAGANA,
+                                 KeyEvent.VK_HIRAGANA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_H,
+                                 KeyEvent.VK_H);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HOME,
+                                 KeyEvent.VK_HOME);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_I,
+                                 KeyEvent.VK_I);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_INSERT,
+                                 KeyEvent.VK_INSERT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_INVERTED_EXCLAMATION,
+                                 KeyEvent.VK_INVERTED_EXCLAMATION_MARK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_JAPANESE_HIRAGANA,
+                                 KeyEvent.VK_JAPANESE_HIRAGANA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_JAPANESE_KATAKANA,
+                                 KeyEvent.VK_JAPANESE_KATAKANA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_JAPANESE_ROMAJI,
+                                 KeyEvent.VK_JAPANESE_ROMAN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_J,
+                                 KeyEvent.VK_J);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_KANA_MODE,
+                                 KeyEvent.VK_KANA_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_KANJI_MODE,
+                                 KeyEvent.VK_KANJI);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_KATAKANA,
+                                 KeyEvent.VK_KATAKANA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_K,
+                                 KeyEvent.VK_K);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT_BRACE,
+                                 KeyEvent.VK_BRACELEFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT,
+                                 KeyEvent.VK_LEFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT_PARENTHESIS,
+                                 KeyEvent.VK_LEFT_PARENTHESIS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT_SQUARE_BRACKET,
+                                 KeyEvent.VK_OPEN_BRACKET);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LESS_THAN,
+                                 KeyEvent.VK_LESS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_L,
+                                 KeyEvent.VK_L);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_META,
+                                 KeyEvent.VK_META);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_META,
+                                 KeyEvent.VK_META);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_MINUS,
+                                 KeyEvent.VK_MINUS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_M,
+                                 KeyEvent.VK_M);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_MODE_CHANGE,
+                                 KeyEvent.VK_MODECHANGE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_N,
+                                 KeyEvent.VK_N);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_NONCONVERT,
+                                 KeyEvent.VK_NONCONVERT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_NUM_LOCK,
+                                 KeyEvent.VK_NUM_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_NUM_LOCK,
+                                 KeyEvent.VK_NUM_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_O,
+                                 KeyEvent.VK_O);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PAGE_DOWN,
+                                 KeyEvent.VK_PAGE_DOWN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PAGE_UP,
+                                 KeyEvent.VK_PAGE_UP);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PASTE,
+                                 KeyEvent.VK_PASTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PAUSE,
+                                 KeyEvent.VK_PAUSE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_P,
+                                 KeyEvent.VK_P);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PLUS,
+                                 KeyEvent.VK_PLUS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PREVIOUS_CANDIDATE,
+                                 KeyEvent.VK_PREVIOUS_CANDIDATE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PRINT_SCREEN,
+                                 KeyEvent.VK_PRINTSCREEN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PROPS,
+                                 KeyEvent.VK_PROPS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_Q,
+                                 KeyEvent.VK_Q);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_QUOTE,
+                                 KeyEvent.VK_QUOTEDBL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT_BRACE,
+                                 KeyEvent.VK_BRACERIGHT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT,
+                                 KeyEvent.VK_RIGHT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT_PARENTHESIS,
+                                 KeyEvent.VK_RIGHT_PARENTHESIS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT_SQUARE_BRACKET,
+                                 KeyEvent.VK_CLOSE_BRACKET);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_R,
+                                 KeyEvent.VK_R);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ROMAN_CHARACTERS,
+                                 KeyEvent.VK_ROMAN_CHARACTERS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SCROLL,
+                                 KeyEvent.VK_SCROLL_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SCROLL,
+                                 KeyEvent.VK_SCROLL_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SEMICOLON,
+                                 KeyEvent.VK_SEMICOLON);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SEMIVOICED_SOUND,
+                                 KeyEvent.VK_DEAD_SEMIVOICED_SOUND);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SHIFT,
+                                 KeyEvent.VK_SHIFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SHIFT,
+                                 KeyEvent.VK_SHIFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_S,
+                                 KeyEvent.VK_S);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SLASH,
+                                 KeyEvent.VK_SLASH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SPACE,
+                                 KeyEvent.VK_SPACE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_STOP,
+                                 KeyEvent.VK_STOP);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_TAB,
+                                 KeyEvent.VK_TAB);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_T,
+                                 KeyEvent.VK_T);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_U,
+                                 KeyEvent.VK_U);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UNDERSCORE,
+                                 KeyEvent.VK_UNDERSCORE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UNDO,
+                                 KeyEvent.VK_UNDO);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UNIDENTIFIED,
+                                 KeyEvent.VK_UNDEFINED);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UP,
+                                 KeyEvent.VK_UP);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_V,
+                                 KeyEvent.VK_V);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_VOICED_SOUND,
+                                 KeyEvent.VK_DEAD_VOICED_SOUND);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_W,
+                                 KeyEvent.VK_W);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_X,
+                                 KeyEvent.VK_X);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_Y,
+                                 KeyEvent.VK_Y);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_Z,
+                                 KeyEvent.VK_Z);
+            // Java keycodes for duplicate keys
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_0,
+                                 KeyEvent.VK_NUMPAD0);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_1,
+                                 KeyEvent.VK_NUMPAD1);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_2,
+                                 KeyEvent.VK_NUMPAD2);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_3,
+                                 KeyEvent.VK_NUMPAD3);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_4,
+                                 KeyEvent.VK_NUMPAD4);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_5,
+                                 KeyEvent.VK_NUMPAD5);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_6,
+                                 KeyEvent.VK_NUMPAD6);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_7,
+                                 KeyEvent.VK_NUMPAD7);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_8,
+                                 KeyEvent.VK_NUMPAD8);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_9,
+                                 KeyEvent.VK_NUMPAD9);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ASTERISK,
+                                 KeyEvent.VK_MULTIPLY);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_DOWN,
+                                 KeyEvent.VK_KP_DOWN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FULL_STOP,
+                                 KeyEvent.VK_DECIMAL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT,
+                                 KeyEvent.VK_KP_LEFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_MINUS,
+                                 KeyEvent.VK_SUBTRACT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PLUS,
+                                 KeyEvent.VK_ADD);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT,
+                                 KeyEvent.VK_KP_RIGHT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SLASH,
+                                 KeyEvent.VK_DIVIDE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UP,
+                                 KeyEvent.VK_KP_UP);
+        }
+
+        /**
+         * Put a key code to key identifier mapping into the
+         * IDENTIFIER_KEY_CODES table.
+         */
+        protected static void putIdentifierKeyCode(String keyIdentifier,
+                                                   int keyCode) {
+            if (IDENTIFIER_KEY_CODES[keyCode / 256] == null) {
+                IDENTIFIER_KEY_CODES[keyCode / 256] = new String[256];
+            }
+            IDENTIFIER_KEY_CODES[keyCode / 256][keyCode % 256] = keyIdentifier;
+        }
+
+        /**
+         * Convert a Java key code to a DOM 3 key string.
+         */
+        protected String mapKeyCodeToIdentifier(int keyCode) {
+            String[] a = IDENTIFIER_KEY_CODES[keyCode / 256];
+            if (a == null) {
+                return DOMKeyboardEvent.KEY_UNIDENTIFIED;
+            }
+            return a[keyCode % 256];
+        }
+
+        // MouseWheel ------------------------------------------------------
+
+        public void mouseWheelMoved(GraphicsNodeMouseWheelEvent evt) {
+            Document doc = context.getPrimaryBridgeContext().getDocument();
+            Element targetElement = doc.getDocumentElement();
+            DocumentEvent d = (DocumentEvent) doc;
+            SVGOMWheelEvent wheelEvt
+                = (SVGOMWheelEvent) d.createEvent("WheelEvent");
+            wheelEvt.initWheelEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                                      "wheel", 
+                                      true,
+                                      true,
+                                      null,
+                                      evt.getWheelDelta());
+
+            try {
+                ((EventTarget)targetElement).dispatchEvent(wheelEvt);
+            } catch (RuntimeException e) {
+                ua.displayError(e);
+            }
+        }
+
+        // Mouse -----------------------------------------------------------
+
+        public void mouseEntered(GraphicsNodeMouseEvent evt) {
+            Point clientXY = evt.getClientPoint();
+            GraphicsNode node = evt.getGraphicsNode();
+            Element targetElement = getEventTarget
+                (node, new Point2D.Float(evt.getX(), evt.getY()));
+            Element relatedElement = getRelatedElement(evt);
+            int n = 0;
+            if (relatedElement != null && targetElement != null) {
+                n = DefaultXBLManager.computeBubbleLimit(targetElement,
+                                                         relatedElement);
+            }
+            dispatchMouseEvent("mouseover", 
+                               targetElement,
+                               relatedElement,
+                               clientXY, 
+                               evt, 
+                               true,
+                               n);
+        }
+
+        public void mouseExited(GraphicsNodeMouseEvent evt) {
+            Point clientXY = evt.getClientPoint();
+            // Get the 'new' node for the DOM event.
+            GraphicsNode node = evt.getRelatedNode();
+            Element targetElement = getEventTarget(node, clientXY);
+            if (lastTargetElement != null) {
+                int n = 0;
+                if (targetElement != null) {
+                    // moving from one element to another
+                    n = DefaultXBLManager.computeBubbleLimit(lastTargetElement,
+                                                             targetElement);
+                }
+                dispatchMouseEvent("mouseout", 
+                                   lastTargetElement, // target
+                                   targetElement,     // relatedTarget
+                                   clientXY,
+                                   evt,
+                                   true,
+                                   n);
+                lastTargetElement = null;
+            }
+        }
+
+        public void mouseMoved(GraphicsNodeMouseEvent evt) {
+            Point clientXY = evt.getClientPoint();
+            GraphicsNode node = evt.getGraphicsNode();
+            Element targetElement = getEventTarget(node, clientXY);
+            Element holdLTE = lastTargetElement;
+            if (holdLTE != targetElement) {
+                if (holdLTE != null) {
+                    int n = 0;
+                    if (targetElement != null) {
+                        n = DefaultXBLManager.computeBubbleLimit(holdLTE,
+                                                                 targetElement);
+                    }
+                    dispatchMouseEvent("mouseout", 
+                                       holdLTE, // target
+                                       targetElement,     // relatedTarget
+                                       clientXY,
+                                       evt,
+                                       true,
+                                       n);
+                }
+                if (targetElement != null) {
+                    int n = 0;
+                    if (holdLTE != null) {
+                        n = DefaultXBLManager.computeBubbleLimit(targetElement,
+                                                                 holdLTE);
+                    }
+                    dispatchMouseEvent("mouseover", 
+                                       targetElement,     // target
+                                       holdLTE, // relatedTarget
+                                       clientXY,
+                                       evt,
+                                       true,
+                                       n);
+                }
+            }
+            dispatchMouseEvent("mousemove", 
+                               targetElement,     // target
+                               null,              // relatedTarget
+                               clientXY,
+                               evt,
+                               false,
+                               0);
+        }
+
+
+        /**
+         * Dispatches a DOM MouseEvent according to the specified
+         * parameters.
+         *
+         * @param eventType the event type
+         * @param targetElement the target of the event
+         * @param relatedElement the related target if any
+         * @param clientXY the mouse coordinates in the client space
+         * @param evt the GVT GraphicsNodeMouseEvent
+         * @param cancelable true means the event is cancelable
+         */
+        protected void dispatchMouseEvent(String eventType,
+                                          Element targetElement,
+                                          Element relatedElement,
+                                          Point clientXY,
+                                          GraphicsNodeMouseEvent evt,
+                                          boolean cancelable) {
+            dispatchMouseEvent(eventType, targetElement, relatedElement,
+                               clientXY, evt, cancelable, 0);
+        }
+
+        /**
+         * Dispatches a DOM MouseEvent according to the specified
+         * parameters.
+         *
+         * @param eventType the event type
+         * @param targetElement the target of the event
+         * @param relatedElement the related target if any
+         * @param clientXY the mouse coordinates in the client space
+         * @param evt the GVT GraphicsNodeMouseEvent
+         * @param cancelable true means the event is cancelable
+         * @param bubbleLimit the limit to the number of nodes the event
+         *                    will bubble to
+         */
+        protected void dispatchMouseEvent(String eventType,
+                                          Element targetElement,
+                                          Element relatedElement,
+                                          Point clientXY,
+                                          GraphicsNodeMouseEvent evt,
+                                          boolean cancelable,
+                                          int bubbleLimit) {
+            if (ctx12.mouseCaptureTarget != null) {
+                NodeEventTarget net = null;
+                if (targetElement != null) {
+                    net = (NodeEventTarget) targetElement;
+                    while (net != null && net != ctx12.mouseCaptureTarget) {
+                        net = net.getParentNodeEventTarget();
+                    }
+                }
+                if (net == null) {
+                    if (ctx12.mouseCaptureSendAll) {
+                        targetElement = (Element) ctx12.mouseCaptureTarget;
+                    } else {
+                        targetElement = null;
+                    }
+                }
+            }
+
+            if (targetElement != null) {
+                Point screenXY = evt.getScreenPoint();
+                // create the coresponding DOM MouseEvent
+                DocumentEvent d
+                    = (DocumentEvent) targetElement.getOwnerDocument();
+                DOMMouseEvent mouseEvt
+                    = (DOMMouseEvent) d.createEvent("MouseEvents");
+                String modifiers
+                    = DOMUtilities.getModifiersList(evt.getLockState(),
+                                                    evt.getModifiers());
+                mouseEvt.initMouseEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                                          eventType, 
+                                          true, 
+                                          cancelable, 
+                                          null,
+                                          evt.getClickCount(),
+                                          screenXY.x, 
+                                          screenXY.y,
+                                          clientXY.x,
+                                          clientXY.y,
+                                          (short) (evt.getButton() - 1), 
+                                          (EventTarget) relatedElement,
+                                          modifiers);
+
+                ((AbstractEvent) mouseEvt).setBubbleLimit(bubbleLimit);
+
+                try {
+                    ((EventTarget) targetElement).dispatchEvent(mouseEvt);
+                } catch (RuntimeException e) {
+                    ua.displayError(e);
+                } finally {
+                    lastTargetElement = targetElement;
+                }
+            }
+
+            if (ctx12.mouseCaptureTarget != null
+                    && ctx12.mouseCaptureAutoRelease
+                    && "mouseup".equals(eventType)) {
+                ctx12.stopMouseCapture();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeExtension.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeExtension.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeExtension.java
index b3a73c9..789eba5 100644
--- a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeExtension.java
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeExtension.java
@@ -1,10 +1,11 @@
 /*
 
-   Copyright 2001-2002,2004-2005  The Apache Software Foundation 
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
+   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
 
@@ -23,11 +24,16 @@ import java.util.Iterator;
 import org.apache.flex.forks.batik.bridge.BridgeContext;
 import org.apache.flex.forks.batik.bridge.SVGBridgeExtension;
 import org.apache.flex.forks.batik.util.SVGConstants;
+import org.apache.flex.forks.batik.util.SVG12Constants;
+import org.apache.flex.forks.batik.util.XBLConstants;
 import org.w3c.dom.Element;
 
 /**
  * This is a Service interface for classes that want to extend the
  * functionality of the Bridge, to support new tags in the rendering tree.
+ *
+ * @author <a href="mailto:thomas.deweese@kodak.com">Thomas DeWeese</a>
+ * @version $Id: SVG12BridgeExtension.java 475477 2006-11-15 22:44:28Z cam $
  */
 public class SVG12BridgeExtension extends SVGBridgeExtension {
 
@@ -93,8 +99,48 @@ public class SVG12BridgeExtension extends SVGBridgeExtension {
         // bridges to handle elements in the SVG namespace
         super.registerTags(ctx);
 
+        // Bridges for SVG 1.2 elements
         ctx.putBridge(new SVGFlowRootElementBridge());
         ctx.putBridge(new SVGMultiImageElementBridge());
         ctx.putBridge(new SVGSolidColorElementBridge());
+
+        ctx.putBridge(new SVG12TextElementBridge());
+
+        // Bridges for XBL shadow trees and content elements
+        ctx.putBridge(new XBLShadowTreeElementBridge());
+        ctx.putBridge(new XBLContentElementBridge());
+
+        // Default bridge to handle bindable elements
+        ctx.setDefaultBridge(new BindableElementBridge());
+
+        // Namespaces to avoid for default bridges
+        ctx.putReservedNamespaceURI(null);
+        ctx.putReservedNamespaceURI(SVGConstants.SVG_NAMESPACE_URI);
+        ctx.putReservedNamespaceURI(XBLConstants.XBL_NAMESPACE_URI);
+    }
+
+    /**
+     * Whether the presence of the specified element should cause
+     * the document to be dynamic.  If this element isn't handled
+     * by this BridgeExtension, just return false.
+     *
+     * @param e The element to check.
+     */
+    public boolean isDynamicElement(Element e) {
+        String ns = e.getNamespaceURI();
+        if (XBLConstants.XBL_NAMESPACE_URI.equals(ns)) {
+            return true;
+        }
+        if (!SVGConstants.SVG_NAMESPACE_URI.equals(ns)) {
+            return false;
+        }
+        String ln = e.getLocalName();
+        if (ln.equals(SVGConstants.SVG_SCRIPT_TAG)
+                || ln.equals(SVG12Constants.SVG_HANDLER_TAG)
+                || ln.startsWith("animate")
+                || ln.equals("set")) {
+            return true;
+        }
+        return false;
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeUpdateHandler.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeUpdateHandler.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeUpdateHandler.java
new file mode 100644
index 0000000..480f5ee
--- /dev/null
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12BridgeUpdateHandler.java
@@ -0,0 +1,44 @@
+/*
+
+   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.flex.forks.batik.bridge.svg12;
+
+import org.apache.flex.forks.batik.bridge.BridgeUpdateHandler;
+
+import org.w3c.dom.Element;
+
+/**
+ * A BridgeUpdateHandler interface for SVG 1.2 specific events.  This is
+ * for XBL event notification.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id: SVG12BridgeUpdateHandler.java 475477 2006-11-15 22:44:28Z cam $
+ */
+public interface SVG12BridgeUpdateHandler extends BridgeUpdateHandler {
+
+    /**
+     * Invoked when a bindable element's binding has changed.
+     */
+    void handleBindingEvent(Element bindableElement, Element shadowTree);
+
+    /**
+     * Invoked when the xblChildNodes property has changed because a
+     * descendant xbl:content element has updated its selected nodes.
+     */
+    void handleContentSelectionChangedEvent(ContentSelectionChangedEvent csce);
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12FocusManager.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12FocusManager.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12FocusManager.java
new file mode 100644
index 0000000..0287579
--- /dev/null
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/svg12/SVG12FocusManager.java
@@ -0,0 +1,202 @@
+/*
+
+   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.flex.forks.batik.bridge.svg12;
+
+import org.apache.flex.forks.batik.bridge.FocusManager;
+import org.apache.flex.forks.batik.dom.AbstractNode;
+import org.apache.flex.forks.batik.dom.events.AbstractEvent;
+import org.apache.flex.forks.batik.dom.events.DOMUIEvent;
+import org.apache.flex.forks.batik.dom.events.EventSupport;
+import org.apache.flex.forks.batik.dom.svg12.XBLEventSupport;
+import org.apache.flex.forks.batik.util.XMLConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.events.DocumentEvent;
+import org.w3c.dom.events.Event;
+import org.w3c.dom.events.EventTarget;
+
+/**
+ * Focus manager for SVG 1.2 documents.  Ensures bubble limits of DOM
+ * focus events are set appropriately for sXBL. support.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id: SVG12FocusManager.java 475477 2006-11-15 22:44:28Z cam $
+ */
+public class SVG12FocusManager extends FocusManager {
+
+    /**
+     * Constructs a new <tt>SVG12FocusManager</tt> for the specified document.
+     *
+     * @param doc the document
+     */
+    public SVG12FocusManager(Document doc) {
+        super(doc);
+    }
+
+    /**
+     * Adds the event listeners to the document.
+     */
+    protected void addEventListeners(Document doc) {
+        AbstractNode n = (AbstractNode) doc;
+        XBLEventSupport es = (XBLEventSupport) n.initializeEventSupport();
+
+        mouseclickListener = new MouseClickTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "click",
+             mouseclickListener, true);
+
+        mouseoverListener = new MouseOverTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "mouseover",
+             mouseoverListener, true);
+
+        mouseoutListener = new MouseOutTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "mouseout",
+             mouseoutListener, true);
+
+        domFocusInListener = new DOMFocusInTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMFocusIn",
+             domFocusInListener, true);
+
+        domFocusOutListener = new DOMFocusOutTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMFocusOut",
+             domFocusOutListener, true);
+    }
+
+    /**
+     * Removes the event listeners from the document.
+     */
+    protected void removeEventListeners(Document doc) {
+        AbstractNode n = (AbstractNode) doc;
+        XBLEventSupport es = (XBLEventSupport) n.getEventSupport();
+
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "click",
+             mouseclickListener, true);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "mouseover",
+             mouseoverListener, true);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "mouseout",
+             mouseoutListener, true);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMFocusIn",
+             domFocusInListener, true);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMFocusOut",
+             domFocusOutListener, true);
+    }
+
+    /**
+     * The class that is responsible for tracking 'mouseclick' changes.
+     */
+    protected class MouseClickTracker extends FocusManager.MouseClickTracker {
+        public void handleEvent(Event evt) {
+            super.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+    }
+
+    /**
+     * The class that is responsible for tracking 'DOMFocusIn' changes.
+     */
+    protected class DOMFocusInTracker extends FocusManager.DOMFocusInTracker {
+        public void handleEvent(Event evt) {
+            super.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+    }
+
+    /**
+     * The class that is responsible for tracking 'mouseover' changes.
+     */
+    protected class MouseOverTracker extends FocusManager.MouseOverTracker {
+        public void handleEvent(Event evt) {
+            super.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+    }
+
+    /**
+     * The class that is responsible for tracking 'mouseout' changes.
+     */
+    protected class MouseOutTracker extends FocusManager.MouseOutTracker {
+        public void handleEvent(Event evt) {
+            super.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+    }
+
+    /**
+     * Fires a 'DOMFocusIn' event to the specified target.
+     *
+     * @param target the newly focussed event target
+     * @param relatedTarget the previously focussed event target
+     */
+    protected void fireDOMFocusInEvent(EventTarget target,
+                                       EventTarget relatedTarget) {
+        DocumentEvent docEvt = 
+            (DocumentEvent)((Element)target).getOwnerDocument();
+        DOMUIEvent uiEvt = (DOMUIEvent)docEvt.createEvent("UIEvents");
+        uiEvt.initUIEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                            "DOMFocusIn",
+                            true,
+                            false,  // canBubbleArg
+                            null,   // cancelableArg
+                            0);     // detailArg
+        int limit = DefaultXBLManager.computeBubbleLimit((Node) relatedTarget,
+                                                         (Node) target);
+        ((AbstractEvent) uiEvt).setBubbleLimit(limit);
+        target.dispatchEvent(uiEvt);
+    }
+
+    /**
+     * Fires a 'DOMFocusOut' event to the specified target.
+     *
+     * @param target the previously focussed event target
+     * @param relatedTarget the newly focussed event target
+     */
+    protected void fireDOMFocusOutEvent(EventTarget target,
+                                        EventTarget relatedTarget) {
+        DocumentEvent docEvt = 
+            (DocumentEvent)((Element)target).getOwnerDocument();
+        DOMUIEvent uiEvt = (DOMUIEvent)docEvt.createEvent("UIEvents");
+        uiEvt.initUIEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                            "DOMFocusOut",
+                            true,
+                            false,  // canBubbleArg
+                            null,   // cancelableArg
+                            0);     // detailArg
+        int limit = DefaultXBLManager.computeBubbleLimit((Node) target,
+                                                         (Node) relatedTarget);
+        ((AbstractEvent) uiEvt).setBubbleLimit(limit);
+        target.dispatchEvent(uiEvt);
+    }
+}