/*
 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.java.accessibility.internal;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.lang.*;
import java.lang.reflect.*;

import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.tree.*;
import javax.swing.table.*;
import javax.swing.plaf.TreeUI;

import javax.accessibility.*;
import com.sun.java.accessibility.util.*;
import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.SunToolkit;

import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/*
 * Note: This class has to be public.  It's loaded from the VM like this:
 *       Class.forName(atName).newInstance();
 */
final public class AccessBridge {

    private static AccessBridge theAccessBridge;
    private ObjectReferences references;
    private EventHandler eventHandler;

    // Maps AccessibleRoles strings to AccessibleRoles.
    private ConcurrentHashMap<String,AccessibleRole> accessibleRoleMap = new ConcurrentHashMap<>();

    /**
       If the object's role is in the following array getVirtualAccessibleName
       will use the extended search algorithm.
    */
    private ArrayList<AccessibleRole> extendedVirtualNameSearchRoles = new ArrayList<>();
    /**
       If the role of the object's parent is in the following array
       getVirtualAccessibleName will NOT use the extended search
       algorithm even if the object's role is in the
       extendedVirtualNameSearchRoles array.
    */
    private ArrayList<AccessibleRole> noExtendedVirtualNameSearchParentRoles = new ArrayList<>();

    private static native boolean isSysWow();


    /**
     * Load DLLs
     */
    static {
        // Load the appropriate DLLs
        boolean is32on64 = false;
        if (System.getProperty("os.arch").equals("x86")) {
            // 32 bit JRE
            // Load jabsysinfo.dll so can determine Win bitness
            java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction<Void>() {
                    public Void run() {
                        System.loadLibrary("jabsysinfo");
                        return null;
                    }
                }, null, new java.lang.RuntimePermission("loadLibrary.jabsysinfo")
            );
            if (isSysWow()) {
                // 32 bit JRE on 64 bit OS
                is32on64 = true;
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                            System.loadLibrary("javaaccessbridge-32");
                            return null;
                        }
                    }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge-32")
                );
            }
        }
        if (!is32on64) {
            // 32 bit JRE on 32 bit OS or 64 bit JRE on 64 bit OS
            java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction<Void>() {
                    public Void run() {
                        System.loadLibrary("javaaccessbridge");
                        return null;
                    }
                }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge")
            );
        }
    }

    /**
     * AccessBridge constructor
     *
     * Note: This constructor has to be public.  It's called from the VM like this:
     *       Class.forName(atName).newInstance();
     */
    public AccessBridge() {
        theAccessBridge = this;
        references = new ObjectReferences();

        // initialize shutdown hook
        Runtime runTime = Runtime.getRuntime();
        shutdownHook hook = new shutdownHook();
        runTime.addShutdownHook(new Thread(hook));

        // initialize AccessibleRole map
        initAccessibleRoleMap();

        // initialize the methods that map HWNDs and Java top-level
        // windows
        initHWNDcalls();

        // is this a JVM we can use?
        // install JDK 1.2 and later Swing ToolKit listener
        EventQueueMonitor.isGUIInitialized();

        // start the Java event handler
        eventHandler = new EventHandler(this);

        // register for menu selection events
        MenuSelectionManager.defaultManager().addChangeListener(eventHandler);

        // register as a NativeWindowHandler
        addNativeWindowHandler(new DefaultNativeWindowHandler());

        // start in a new thread
        Thread abthread = new Thread(new dllRunner());
        abthread.setDaemon(true);
        abthread.start();
        debugString("AccessBridge started");
    }

    /*
     * adaptor to run the AccessBridge DLL
     */
    private class dllRunner implements Runnable {
        public void run() {
            runDLL();
        }
    }

    /*
     * shutdown hook
     */
    private class shutdownHook implements Runnable {

        public void run() {
            debugString("***** shutdownHook: shutting down...");
            javaShutdown();
        }
    }


    /*
     * Initialize the hashtable that maps Strings to AccessibleRoles.
     */
    private void initAccessibleRoleMap() {
        /*
         * Initialize the AccessibleRoles map. This code uses methods in
         * java.lang.reflect.* to build the map.
         */
        try {
            Class<?> clAccessibleRole = Class.forName ("javax.accessibility.AccessibleRole");
            if (null != clAccessibleRole) {
                AccessibleRole roleUnknown = AccessibleRole.UNKNOWN;
                Field [] fields = clAccessibleRole.getFields ();
                int i = 0;
                for (i = 0; i < fields.length; i ++) {
                    Field f = fields [i];
                    if (javax.accessibility.AccessibleRole.class == f.getType ()) {
                        AccessibleRole nextRole = (AccessibleRole) (f.get (roleUnknown));
                        String nextRoleString = nextRole.toDisplayString (Locale.US);
                        accessibleRoleMap.put (nextRoleString, nextRole);
                    }
                }
            }
        } catch (Exception e) {}

    /*
      Build the extendedVirtualNameSearchRoles array list.
    */
    extendedVirtualNameSearchRoles.add (AccessibleRole.COMBO_BOX);
    try {
        /*
          Added in J2SE 1.4
        */
        extendedVirtualNameSearchRoles.add (AccessibleRole.DATE_EDITOR);
    } catch (NoSuchFieldError e) {}
    extendedVirtualNameSearchRoles.add (AccessibleRole.LIST);
    extendedVirtualNameSearchRoles.add (AccessibleRole.PASSWORD_TEXT);
    extendedVirtualNameSearchRoles.add (AccessibleRole.SLIDER);
    try {
        /*
          Added in J2SE 1.3
        */
        extendedVirtualNameSearchRoles.add (AccessibleRole.SPIN_BOX);
    } catch (NoSuchFieldError e) {}
    extendedVirtualNameSearchRoles.add (AccessibleRole.TABLE);
    extendedVirtualNameSearchRoles.add (AccessibleRole.TEXT);
    extendedVirtualNameSearchRoles.add (AccessibleRole.UNKNOWN);

    noExtendedVirtualNameSearchParentRoles.add (AccessibleRole.TABLE);
    noExtendedVirtualNameSearchParentRoles.add (AccessibleRole.TOOL_BAR);
    }

    /**
     * start the AccessBridge DLL running in its own thread
     */
    private native void runDLL();

    /**
     * debugging output (goes to OutputDebugStr())
     */
    private native void sendDebugString(String debugStr);

    /**
     * debugging output (goes to OutputDebugStr())
     */
    private void debugString(String debugStr) {
    sendDebugString(debugStr);
    }

    /* ===== utility methods ===== */

    /**
     * decrement the reference to the object (called by native code)
     */
    private void decrementReference(Object o) {
    references.decrement(o);
    }

    /**
     * get the java.version property from the JVM
     */
    private String getJavaVersionProperty() {
        String s = System.getProperty("java.version");
        if (s != null) {
            references.increment(s);
            return s;
        }
        return null;
    }

    /* ===== HWND/Java window mapping methods ===== */

    // Java toolkit methods for mapping HWNDs to Java components
    private Method javaGetComponentFromNativeWindowHandleMethod;
    private Method javaGetNativeWindowHandleFromComponentMethod;

    // native jawt methods for mapping HWNDs to Java components
    private native int jawtGetNativeWindowHandleFromComponent(Component comp);

    private native Component jawtGetComponentFromNativeWindowHandle(int handle);

    Toolkit toolkit;

    /**
     * map an HWND to an AWT Component
     */
    private void initHWNDcalls() {
        Class<?> integerParemter[] = new Class<?>[1];
        integerParemter[0] = Integer.TYPE;
        Class<?> componentParemter[] = new Class<?>[1];
        try {
            componentParemter[0] = Class.forName("java.awt.Component");
        } catch (ClassNotFoundException e) {
            debugString("Exception: " + e.toString());
        }
        toolkit = Toolkit.getDefaultToolkit();
        return;
    }

    // native window handler interface
    private interface NativeWindowHandler {
        public Accessible getAccessibleFromNativeWindowHandle(int nativeHandle);
    }

    // hash table of native window handle to AccessibleContext mappings
    static private ConcurrentHashMap<Integer,AccessibleContext> windowHandleToContextMap = new ConcurrentHashMap<>();

    // hash table of AccessibleContext to native window handle mappings
    static private ConcurrentHashMap<AccessibleContext,Integer> contextToWindowHandleMap = new ConcurrentHashMap<>();

    /*
     * adds a virtual window handler to our hash tables
     */
    static private void registerVirtualFrame(final Accessible a,
                                             Integer nativeWindowHandle ) {
        if (a != null) {
            AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                @Override
                public AccessibleContext call() throws Exception {
                    return a.getAccessibleContext();
                }
            }, a);
            windowHandleToContextMap.put(nativeWindowHandle, ac);
            contextToWindowHandleMap.put(ac, nativeWindowHandle);
        }
    }

    /*
     * removes a virtual window handler to our hash tables
     */
    static private void revokeVirtualFrame(final Accessible a,
                                           Integer nativeWindowHandle ) {
        AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                return a.getAccessibleContext();
            }
        }, a);
        windowHandleToContextMap.remove(nativeWindowHandle);
        contextToWindowHandleMap.remove(ac);
    }

    // vector of native window handlers
    private static Vector<NativeWindowHandler> nativeWindowHandlers = new Vector<>();

    /*
    * adds a native window handler to our list
    */
    private static void addNativeWindowHandler(NativeWindowHandler handler) {
        if (handler == null) {
            throw new IllegalArgumentException();
        }
        nativeWindowHandlers.addElement(handler);
    }

    /*
     * removes a native window handler to our list
     */
    private static boolean removeNativeWindowHandler(NativeWindowHandler handler) {
        if (handler == null) {
            throw new IllegalArgumentException();
        }
        return nativeWindowHandlers.removeElement(handler);
    }

    /**
     * verifies that a native window handle is a Java window
     */
    private boolean isJavaWindow(int nativeHandle) {
        AccessibleContext ac = getContextFromNativeWindowHandle(nativeHandle);
        if (ac != null) {
            saveContextToWindowHandleMapping(ac, nativeHandle);
            return true;
        }
        return false;
    }

    /*
     * saves the mapping between an AccessibleContext and a window handle
     */
    private void saveContextToWindowHandleMapping(AccessibleContext ac,
                                                  int nativeHandle) {
        debugString("saveContextToWindowHandleMapping...");
        if (ac == null) {
            return;
        }
        if (! contextToWindowHandleMap.containsKey(ac)) {
            debugString("saveContextToWindowHandleMapping: ac = "+ac+"; handle = "+nativeHandle);
            contextToWindowHandleMap.put(ac, nativeHandle);
        }
    }

    /**
     * maps a native window handle to an Accessible Context
     */
    private AccessibleContext getContextFromNativeWindowHandle(int nativeHandle) {
        // First, look for the Accessible in our hash table of
        // virtual window handles.
        AccessibleContext ac = windowHandleToContextMap.get(nativeHandle);
        if(ac!=null) {
            saveContextToWindowHandleMapping(ac, nativeHandle);
            return ac;
        }

        // Next, look for the native window handle in our vector
        // of native window handles.
        int numHandlers = nativeWindowHandlers.size();
        for (int i = 0; i < numHandlers; i++) {
            NativeWindowHandler nextHandler = nativeWindowHandlers.elementAt(i);
            final Accessible a = nextHandler.getAccessibleFromNativeWindowHandle(nativeHandle);
            if (a != null) {
                ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                    @Override
                    public AccessibleContext call() throws Exception {
                        return a.getAccessibleContext();
                    }
                }, a);
                saveContextToWindowHandleMapping(ac, nativeHandle);
                return ac;
            }
        }
        // Not found.
        return null;
    }

    /**
     * maps an AccessibleContext to a native window handle
     *     returns 0 on error
     */
    private int getNativeWindowHandleFromContext(AccessibleContext ac) {
    debugString("getNativeWindowHandleFromContext: ac = "+ac);
        try {
            return contextToWindowHandleMap.get(ac);
        } catch (Exception ex) {
            return 0;
        }
    }

    private class DefaultNativeWindowHandler implements NativeWindowHandler {
        /*
        * returns the Accessible associated with a native window
        */
        public Accessible getAccessibleFromNativeWindowHandle(int nativeHandle) {
            final Component c = jawtGetComponentFromNativeWindowHandle(nativeHandle);
            if (c instanceof Accessible) {
                AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                    @Override
                    public AccessibleContext call() throws Exception {
                        return c.getAccessibleContext();
                    }
                }, c);
                saveContextToWindowHandleMapping(ac, nativeHandle);
                return (Accessible)c;
            } else {
                return null;
            }
        }
    }

    /* ===== AccessibleContext methods =====*/

    /*
     * returns the inner-most AccessibleContext in parent at Point(x, y)
     */
    private AccessibleContext getAccessibleContextAt(int x, int y,
                                                    AccessibleContext parent) {
        if (parent == null) {
            return null;
        }
        if (windowHandleToContextMap != null &&
            windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) {
            // Path for applications that register their top-level
            // windows with the AccessBridge (e.g., StarOffice 6.1)
            return getAccessibleContextAt_1(x, y, parent);
        } else {
            // Path for applications that do not register
            // their top-level windows with the AccessBridge
            // (e.g., Swing/AWT applications)
            return getAccessibleContextAt_2(x, y, parent);
        }
    }

    /*
     * returns the root accessible context
     */
    private AccessibleContext getRootAccessibleContext(final AccessibleContext ac) {
        if (ac == null) {
            return null;
        }
        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                Accessible parent = ac.getAccessibleParent();
                if (parent == null) {
                    return ac;
                }
                Accessible tmp = parent.getAccessibleContext().getAccessibleParent();
                while (tmp != null) {
                    parent = tmp;
                    tmp = parent.getAccessibleContext().getAccessibleParent();
                }
                return parent.getAccessibleContext();
            }
        }, ac);
    }

    /*
     * StarOffice version that does not use the EventQueueMonitor
     */
    private AccessibleContext getAccessibleContextAt_1(final int x, final int y,
                                                      final AccessibleContext parent) {
        debugString(" : getAccessibleContextAt_1 called");
        debugString("   -> x = " + x + " y = " + y + " parent = " + parent);

        if (parent == null) return null;
            final AccessibleComponent acmp = InvocationUtils.invokeAndWait(new Callable<AccessibleComponent>() {
                @Override
                public AccessibleComponent call() throws Exception {
                    return parent.getAccessibleComponent();
                }
            }, parent);
        if (acmp!=null) {
            final Point loc = InvocationUtils.invokeAndWait(new Callable<Point>() {
                @Override
                public Point call() throws Exception {
                    return acmp.getLocation();
                }
            }, parent);
            final Accessible a = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                @Override
                public Accessible call() throws Exception {
                    return acmp.getAccessibleAt(new Point(x - loc.x, y - loc.y));
                }
            }, parent);
            if (a != null) {
                AccessibleContext foundAC = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                    @Override
                    public AccessibleContext call() throws Exception {
                        return a.getAccessibleContext();
                    }
                }, parent);
                if (foundAC != null) {
                    if (foundAC != parent) {
                        // recurse down into the child
                        return getAccessibleContextAt_1(x - loc.x, y - loc.y,
                                                        foundAC);
                    } else
                        return foundAC;
                }
            }
        }
        return parent;
    }

    /*
     * AWT/Swing version
     */
    private AccessibleContext getAccessibleContextAt_2(final int x, final int y,
                                                      AccessibleContext parent) {
        debugString("getAccessibleContextAt_2 called");
        debugString("   -> x = " + x + " y = " + y + " parent = " + parent);

        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                Accessible a = EventQueueMonitor.getAccessibleAt(new Point(x, y));
                if (a != null) {
                    AccessibleContext childAC = a.getAccessibleContext();
                    if (childAC != null) {
                        debugString("   returning childAC = " + childAC);
                        return childAC;
                    }
                }
                return null;
            }
        }, parent);
    }

    /**
     * returns the Accessible that has focus
     */
    private AccessibleContext getAccessibleContextWithFocus() {
        Component c = AWTEventMonitor.getComponentWithFocus();
        if (c != null) {
            final Accessible a = Translator.getAccessible(c);
            if (a != null) {
                AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                    @Override
                    public AccessibleContext call() throws Exception {
                        return a.getAccessibleContext();
                    }
                }, c);
                if (ac != null) {
                    return ac;
                }
            }
        }
        return null;
    }

    /**
     * returns the AccessibleName from an AccessibleContext
     */
    private String getAccessibleNameFromContext(final AccessibleContext ac) {
        debugString("***** ac = "+ac.getClass());
        if (ac != null) {
            String s = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return ac.getAccessibleName();
                }
            }, ac);
            if (s != null) {
                references.increment(s);
                debugString("Returning AccessibleName from Context: " + s);
                return s;
            } else {
                return null;
            }
        } else {
            debugString("getAccessibleNameFromContext; ac = null!");
            return null;
        }
    }

    /**
     * Returns an AccessibleName for a component using an algorithm optimized
     * for the JAWS screen reader.  This method is only intended for JAWS. All
     * other uses are entirely optional.
     */
    private String getVirtualAccessibleNameFromContext(final AccessibleContext ac) {
        if (null != ac) {
            /*
            Step 1:
            =======
            Determine if we can obtain the Virtual Accessible Name from the
            Accessible Name or Accessible Description of the object.
            */
            String nameString = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return ac.getAccessibleName();
                }
            }, ac);
            if ( ( null != nameString ) && ( 0 != nameString.length () ) ) {
                debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName.");
                references.increment (nameString);
                return nameString;
            }
            String descriptionString = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return ac.getAccessibleDescription();
                }
            }, ac);
            if ( ( null != descriptionString ) && ( 0 != descriptionString.length () ) ) {
                debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription.");
                references.increment (descriptionString);
                return descriptionString;
            }

            debugString ("The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName");
            /*
            Step 2:
            =======
            Decide whether the extended name search algorithm should be
            used for this object.
            */
            boolean bExtendedSearch = false;
            AccessibleRole role = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                @Override
                public AccessibleRole call() throws Exception {
                    return ac.getAccessibleRole();
                }
            }, ac);
            AccessibleContext parentContext = null;
            AccessibleRole parentRole = AccessibleRole.UNKNOWN;

            if ( extendedVirtualNameSearchRoles.contains (role) ) {
                parentContext = getAccessibleParentFromContext (ac);
                if ( null != parentContext ) {
                    final AccessibleContext parentContextInnerTemp = parentContext;
                    parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                        @Override
                        public AccessibleRole call() throws Exception {
                            return parentContextInnerTemp.getAccessibleRole();
                        }
                    }, ac);
                    if ( AccessibleRole.UNKNOWN != parentRole ) {
                        bExtendedSearch = true;
                        if ( noExtendedVirtualNameSearchParentRoles.contains (parentRole) ) {
                            bExtendedSearch = false;
                        }
                    }
                }
            }

            if (false == bExtendedSearch) {
                debugString ("bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm.  role = " + role.toDisplayString (Locale.US) );
                /*
                Step 3:
                =======
                We have determined that we should not use the extended name
                search algorithm for this object (we must obtain the name of
                the object from the object itself and not from neighboring
                objects).  However the object name cannot be obtained from
                the Accessible Name or Accessible Description of the object.

                Handle several special cases here that might yield a value for
                the Virtual Accessible Name.  Return null if the object does
                not match the criteria for any of these special cases.
                */
                if (AccessibleRole.LABEL == role) {
                    /*
                    Does the label support the Accessible Text Interface?
                    */
                    final AccessibleText at = InvocationUtils.invokeAndWait(new Callable<AccessibleText>() {
                        @Override
                        public AccessibleText call() throws Exception {
                            return ac.getAccessibleText();
                        }
                    }, ac);
                    if (null != at) {
                        int charCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                            @Override
                            public Integer call() throws Exception {
                                return at.getCharCount();
                            }
                        }, ac);
                        String text = getAccessibleTextRangeFromContext (ac, 0, charCount);
                        if (null != text) {
                            debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object.");
                            references.increment (text);
                            return text;
                        }
                    }
                    /*
                    Does the label support the Accessible Icon Interface?
                    */
                    debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
                    final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
                        @Override
                        public AccessibleIcon[] call() throws Exception {
                            return ac.getAccessibleIcon();
                        }
                    }, ac);
                    if ( (null != ai) && (ai.length > 0) ) {
                        String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                            @Override
                            public String call() throws Exception {
                                return ai[0].getAccessibleIconDescription();
                            }
                        }, ac);
                        if (iconDescription != null){
                            debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object.");
                            references.increment (iconDescription);
                            return iconDescription;
                        }
                    } else {
                        parentContext = getAccessibleParentFromContext (ac);
                        if ( null != parentContext ) {
                            final AccessibleContext parentContextInnerTemp = parentContext;
                            parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                                @Override
                                public AccessibleRole call() throws Exception {
                                    return parentContextInnerTemp.getAccessibleRole();
                                }
                            }, ac);
                            if ( AccessibleRole.TABLE == parentRole ) {
                                int indexInParent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                                    @Override
                                    public Integer call() throws Exception {
                                        return ac.getAccessibleIndexInParent();
                                    }
                                }, ac);
                                final AccessibleContext acTableCell = getAccessibleChildFromContext (parentContext, indexInParent);
                                debugString ("bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell.");
                                if (acTableCell != null) {
                                    final AccessibleIcon [] aiRet =InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
                                        @Override
                                        public AccessibleIcon[] call() throws Exception {
                                            return acTableCell.getAccessibleIcon();
                                        }
                                    }, ac);
                                    if ( (null != aiRet) && (aiRet.length > 0) ) {
                                        String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                            @Override
                                            public String call() throws Exception {
                                                return aiRet[0].getAccessibleIconDescription();
                                            }
                                        }, ac);
                                        if (iconDescription != null){
                                            debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object.");
                                            references.increment (iconDescription);
                                            return iconDescription;
                                        }
                                    }
                                }
                            }
                        }
                    }
                } else if ( (AccessibleRole.TOGGLE_BUTTON == role) ||
                            (AccessibleRole.PUSH_BUTTON == role) ) {
                    /*
                    Does the button support the Accessible Icon Interface?
                    */
                    debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
                    final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
                        @Override
                        public AccessibleIcon[] call() throws Exception {
                            return ac.getAccessibleIcon();
                        }
                    }, ac);
                    if ( (null != ai) && (ai.length > 0) ) {
                        String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                            @Override
                            public String call() throws Exception {
                                return ai[0].getAccessibleIconDescription();
                            }
                        }, ac);
                        if (iconDescription != null){
                            debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object.");
                            references.increment (iconDescription);
                            return iconDescription;
                        }
                    }
                } else if ( AccessibleRole.CHECK_BOX == role ) {
                    /*
                    NOTE: The only case I know of in which a check box does not
                    have a name is when that check box is contained in a table.

                    In this case it would be appropriate to use the display string
                    of the check box object as the name (in US English the display
                    string is typically either "true" or "false").

                    I am using the AccessibleValue interface to obtain the display
                    string of the check box.  If the Accessible Value is 1, I am
                    returning Boolean.TRUE.toString (),  If the Accessible Value is
                    0, I am returning Boolean.FALSE.toString ().  If the Accessible
                    Value is some other number, I will return the display string of
                    the current numerical value of the check box.
                    */
                    final AccessibleValue av = InvocationUtils.invokeAndWait(new Callable<AccessibleValue>() {
                        @Override
                        public AccessibleValue call() throws Exception {
                            return ac.getAccessibleValue();
                        }
                    }, ac);
                    if ( null != av ) {
                        nameString = null;
                        Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
                            @Override
                            public Number call() throws Exception {
                                return av.getCurrentAccessibleValue();
                            }
                        }, ac);
                        if ( null != value ) {
                            if ( 1 == value.intValue () ) {
                                nameString = Boolean.TRUE.toString ();
                            } else if ( 0 == value.intValue () ) {
                                nameString = Boolean.FALSE.toString ();
                            } else {
                                nameString = value.toString ();
                            }
                            if ( null != nameString ) {
                                references.increment (nameString);
                                return nameString;
                            }
                        }
                    }
                }
                return null;
            }

            /*
            +
            Beginning of the extended name search
            +
            */
            final AccessibleContext parentContextOuterTemp = parentContext;
            String parentName = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return parentContextOuterTemp.getAccessibleName();
                }
            }, ac);
            String parentDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return parentContextOuterTemp.getAccessibleDescription();
                }
            }, ac);

            /*
            Step 4:
            =======
            Special case for Slider Bar objects.
            */
            if ( (AccessibleRole.SLIDER == role) &&
                 (AccessibleRole.PANEL == parentRole) &&
                 (null != parentName) ) {
                debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object.");
                references.increment (parentName);
                return parentName;
            }

            boolean bIsEditCombo = false;

            AccessibleContext testContext = ac;
            /*
            Step 5:
            =======
            Special case for Edit Combo Boxes
            */
            if ( (AccessibleRole.TEXT == role) &&
                 (AccessibleRole.COMBO_BOX == parentRole) ) {
                bIsEditCombo = true;
                if (null != parentName) {
                    debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object.");
                    references.increment (parentName);
                    return parentName;
                } else if (null != parentDescription) {
                    debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object.");
                    references.increment (parentDescription);
                    return parentDescription;
                }
                testContext = parentContext;
                parentRole = AccessibleRole.UNKNOWN;
                parentContext = getAccessibleParentFromContext (testContext);
                if ( null != parentContext ) {
                    final AccessibleContext parentContextInnerTemp = parentContext;
                    parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                        @Override
                        public AccessibleRole call() throws Exception {
                            return parentContextInnerTemp.getAccessibleRole();
                        }
                    }, ac);
                }
            }

            /*
            Step 6:
            =======
            Attempt to get the Virtual Accessible Name of the object using the
            Accessible Relation Set Info (the LABELED_BY Accessible Relation).
            */
            {
                final AccessibleContext parentContextTempInner = parentContext;
                AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable<AccessibleRelationSet>() {
                    @Override
                    public AccessibleRelationSet call() throws Exception {
                        return parentContextTempInner.getAccessibleRelationSet();
                    }
                }, ac);
                if ( ars != null && (ars.size () > 0) && (ars.contains (AccessibleRelation.LABELED_BY)) ) {
                    AccessibleRelation labeledByRelation = ars.get (AccessibleRelation.LABELED_BY);
                    if (labeledByRelation != null) {
                        Object [] targets = labeledByRelation.getTarget ();
                        Object o = targets [0];
                        if (o instanceof Accessible) {
                            AccessibleContext labelContext = ((Accessible)o).getAccessibleContext ();
                            if (labelContext != null) {
                                String labelName = labelContext.getAccessibleName ();
                                String labelDescription = labelContext.getAccessibleDescription ();
                                if (null != labelName) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case.");
                                    references.increment (labelName);
                                    return labelName;
                                } else if (null != labelDescription) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case.");
                                    references.increment (labelDescription);
                                    return labelDescription;
                                }
                            }
                        }
                    }
                }
            }

            //Note: add AccessibleContext to use InvocationUtils.invokeAndWait
            /*
            Step 7:
            =======
            Search for a label object that is positioned either just to the left
            or just above the object and get the Accessible Name of the Label
            object.
            */
            int testIndexMax = 0;
            int testX = 0;
            int testY = 0;
            int testWidth = 0;
            int testHeight = 0;
            int targetX = 0;
            int targetY = 0;
            final AccessibleContext tempContext = testContext;
            int testIndex = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return tempContext.getAccessibleIndexInParent();
                }
            }, ac);
            if ( null != parentContext ) {
                final AccessibleContext parentContextInnerTemp = parentContext;
                testIndexMax =  InvocationUtils.invokeAndWait(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        return parentContextInnerTemp.getAccessibleChildrenCount() - 1;
                    }
                }, ac);
            }
            testX = getAccessibleXcoordFromContext (testContext);
            testY = getAccessibleYcoordFromContext (testContext);
            testWidth = getAccessibleWidthFromContext (testContext);
            testHeight = getAccessibleHeightFromContext (testContext);
            targetX = testX + 2;
            targetY = testY + 2;

            int childIndex = testIndex - 1;
            /*Accessible child = null;
            AccessibleContext childContext = null;
            AccessibleRole childRole = AccessibleRole.UNKNOWN;*/
            int childX = 0;
            int childY = 0;
            int childWidth = 0;
            int childHeight = 0;
            String childName = null;
            String childDescription = null;
            while (childIndex >= 0) {
                final int childIndexTemp = childIndex;
                final AccessibleContext parentContextInnerTemp = parentContext;
                final Accessible child  =  InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                    @Override
                    public Accessible call() throws Exception {
                        return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
                    }
                }, ac);
                if ( null != child ) {
                    final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                        @Override
                        public AccessibleContext call() throws Exception {
                            return child.getAccessibleContext();
                        }
                    }, ac);
                    if ( null != childContext ) {
                        AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                            @Override
                            public AccessibleRole call() throws Exception {
                                return childContext.getAccessibleRole();
                            }
                        }, ac);
                        if ( AccessibleRole.LABEL == childRole ) {
                            childX = getAccessibleXcoordFromContext (childContext);
                            childY = getAccessibleYcoordFromContext (childContext);
                            childWidth = getAccessibleWidthFromContext (childContext);
                            childHeight = getAccessibleHeightFromContext (childContext);
                            if ( (childX < testX) &&
                                 ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
                                childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleName();
                                    }
                                }, ac);
                                if ( null != childName ) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
                                    references.increment (childName);
                                    return childName;
                                }
                                childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleDescription();
                                    }
                                }, ac);
                                if ( null != childDescription ) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
                                    references.increment (childDescription);
                                    return childDescription;
                                }
                            } else if ( (childY < targetY) &&
                                        ((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
                                childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleName();
                                    }
                                }, ac);
                                if ( null != childName ) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
                                    references.increment (childName);
                                    return childName;
                                }
                                childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleDescription();
                                    }
                                }, ac);
                                if ( null != childDescription ) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
                                    references.increment (childDescription);
                                    return childDescription;
                                }
                            }
                        }
                    }
                }
                childIndex --;
            }
            childIndex = testIndex + 1;
            while (childIndex <= testIndexMax) {
                final int childIndexTemp = childIndex;
                final AccessibleContext parentContextInnerTemp = parentContext;
                final Accessible child  =  InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                    @Override
                    public Accessible call() throws Exception {
                        return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
                    }
                }, ac);
                if ( null != child ) {
                    final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                        @Override
                        public AccessibleContext call() throws Exception {
                            return child.getAccessibleContext();
                        }
                    }, ac);
                    if ( null != childContext ) {
                        AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                            @Override
                            public AccessibleRole call() throws Exception {
                                return childContext.getAccessibleRole();
                            }
                        }, ac);
                        if ( AccessibleRole.LABEL == childRole ) {
                            childX = getAccessibleXcoordFromContext (childContext);
                            childY = getAccessibleYcoordFromContext (childContext);
                            childWidth = getAccessibleWidthFromContext (childContext);
                            childHeight = getAccessibleHeightFromContext (childContext);
                            if ( (childX < testX) &&
                                 ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
                                childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleName();
                                    }
                                }, ac);
                                if ( null != childName ) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
                                    references.increment (childName);
                                    return childName;
                                }
                                childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleDescription();
                                    }
                                }, ac);
                                if ( null != childDescription ) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
                                    references.increment (childDescription);
                                    return childDescription;
                                }
                            } else if ( (childY < targetY) &&
                                        ((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
                                childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleName();
                                    }
                                }, ac);
                                if ( null != childName ) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
                                    references.increment (childName);
                                    return childName;
                                }
                                childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleDescription();
                                    }
                                }, ac);
                                if ( null != childDescription ) {
                                    debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
                                    references.increment (childDescription);
                                    return childDescription;
                                }
                            }
                        }
                    }
                }
                childIndex ++;
            }
            /*
            Step 8:
            =======
            Special case for combo boxes and text objects, based on a
            similar special case I found in some of our internal JAWS code.

            Search for a button object that is positioned either just to the left
            or just above the object and get the Accessible Name of the button
            object.
            */
            if ( (AccessibleRole.TEXT == role) ||
                 (AccessibleRole.COMBO_BOX == role) ||
                 (bIsEditCombo) ) {
                childIndex = testIndex - 1;
                while (childIndex >= 0) {
                    final int childIndexTemp = childIndex;
                    final AccessibleContext parentContextInnerTemp = parentContext;
                    final Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                        @Override
                        public Accessible call() throws Exception {
                            return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
                        }
                    }, ac);
                    if ( null != child ) {
                        final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                            @Override
                            public AccessibleContext call() throws Exception {
                                return child.getAccessibleContext();
                            }
                        }, ac);
                        if ( null != childContext ) {
                            AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                                @Override
                                public AccessibleRole call() throws Exception {
                                    return childContext.getAccessibleRole();
                                }
                            }, ac);
                            if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
                                 ( AccessibleRole.TOGGLE_BUTTON == childRole )) {
                                childX = getAccessibleXcoordFromContext (childContext);
                                childY = getAccessibleYcoordFromContext (childContext);
                                childWidth = getAccessibleWidthFromContext (childContext);
                                childHeight = getAccessibleHeightFromContext (childContext);
                                if ( (childX < testX) &&
                                     ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
                                    childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                        @Override
                                        public String call() throws Exception {
                                            return childContext.getAccessibleName();
                                        }
                                    }, ac);
                                    if ( null != childName ) {
                                        debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                        references.increment (childName);
                                        return childName;
                                    }
                                    childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                        @Override
                                        public String call() throws Exception {
                                            return childContext.getAccessibleDescription();
                                        }
                                    }, ac);
                                    if ( null != childDescription ) {
                                        debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                        references.increment (childDescription);
                                        return childDescription;
                                    }
                                }
                            }
                        }
                    }
                    childIndex --;
                }
                childIndex = testIndex + 1;
                while (childIndex <= testIndexMax) {
                    final int childIndexTemp = childIndex;
                    final AccessibleContext parentContextInnerTemp = parentContext;
                    final Accessible child  =  InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                        @Override
                        public Accessible call() throws Exception {
                            return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
                        }
                    }, ac);
                    if ( null != child ) {
                        final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                            @Override
                            public AccessibleContext call() throws Exception {
                                return child.getAccessibleContext();
                            }
                        }, ac);
                        if ( null != childContext ) {
                            AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                                @Override
                                public AccessibleRole call() throws Exception {
                                    return childContext.getAccessibleRole();
                                }
                            }, ac);
                            if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
                                    ( AccessibleRole.TOGGLE_BUTTON == childRole ) ) {
                                childX = getAccessibleXcoordFromContext (childContext);
                                childY = getAccessibleYcoordFromContext (childContext);
                                childWidth = getAccessibleWidthFromContext (childContext);
                                childHeight = getAccessibleHeightFromContext (childContext);
                                if ( (childX < testX) &&
                                     ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
                                    childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                        @Override
                                        public String call() throws Exception {
                                            return childContext.getAccessibleName();
                                        }
                                    }, ac);
                                    if ( null != childName ) {
                                        debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                        references.increment (childName);
                                        return childName;
                                    }
                                    childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                        @Override
                                        public String call() throws Exception {
                                            return childContext.getAccessibleDescription();
                                        }
                                    }, ac);
                                    if ( null != childDescription ) {
                                        debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                        references.increment (childDescription);
                                        return childDescription;
                                    }
                                }
                            }
                        }
                    }
                    childIndex ++;
                }
            }
            return null;
        } else {
            debugString ("AccessBridge::getVirtualAccessibleNameFromContext error - ac == null.");
            return null;
        }
    }

    /**
     * returns the AccessibleDescription from an AccessibleContext
     */
    private String getAccessibleDescriptionFromContext(final AccessibleContext ac) {
        if (ac != null) {
            String s = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return ac.getAccessibleDescription();
                }
            }, ac);
            if (s != null) {
                references.increment(s);
                debugString("Returning AccessibleDescription from Context: " + s);
                return s;
            }
        } else {
            debugString("getAccessibleDescriptionFromContext; ac = null");
        }
        return null;
    }

    /**
     * returns the AccessibleRole from an AccessibleContext
     */
    private String getAccessibleRoleStringFromContext(final AccessibleContext ac) {
        if (ac != null) {
            AccessibleRole role = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                @Override
                public AccessibleRole call() throws Exception {
                    return ac.getAccessibleRole();
                }
            }, ac);
            if (role != null) {
                String s = role.toDisplayString(Locale.US);
                if (s != null) {
                    references.increment(s);
                    debugString("Returning AccessibleRole from Context: " + s);
                    return s;
                }
            }
        } else {
            debugString("getAccessibleRoleStringFromContext; ac = null");
        }
        return null;
    }

    /**
     * return the AccessibleRole from an AccessibleContext in the en_US locale
     */
    private String getAccessibleRoleStringFromContext_en_US(final AccessibleContext ac) {
        return getAccessibleRoleStringFromContext(ac);
    }

    /**
     * return the AccessibleStates from an AccessibleContext
     */
    private String getAccessibleStatesStringFromContext(final AccessibleContext ac) {
        if (ac != null) {
            AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable<AccessibleStateSet>() {
                @Override
                public AccessibleStateSet call() throws Exception {
                    return ac.getAccessibleStateSet();
                }
            }, ac);
            if (stateSet != null) {
                String s = stateSet.toString();
                if (s != null &&
                    s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) {
                    // Indicate whether this component manages its own
                    // children
                    AccessibleRole role = ac.getAccessibleRole();
                    if (role == AccessibleRole.LIST ||
                        role == AccessibleRole.TABLE ||
                        role == AccessibleRole.TREE) {
                        s += ",";
                        s += AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US);
                    }
                    references.increment(s);
                    debugString("Returning AccessibleStateSet from Context: " + s);
                    return s;
                }
            }
        } else {
            debugString("getAccessibleStatesStringFromContext; ac = null");
        }
        return null;
    }

    /**
     * returns the AccessibleStates from an AccessibleContext in the en_US locale
     */
    private String getAccessibleStatesStringFromContext_en_US(final AccessibleContext ac) {
        if (ac != null) {
            AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable<AccessibleStateSet>() {
                @Override
                public AccessibleStateSet call() throws Exception {
                    return ac.getAccessibleStateSet();
                }
            }, ac);
            if (stateSet != null) {
                String s = "";
                AccessibleState[] states = stateSet.toArray();
                if (states != null && states.length > 0) {
                    s = states[0].toDisplayString(Locale.US);
                    for (int i = 1; i < states.length; i++) {
                        s = s + "," + states[i].toDisplayString(Locale.US);
                    }
                }
                references.increment(s);
                debugString("Returning AccessibleStateSet en_US from Context: " + s);
                return s;
            }
        }
        debugString("getAccessibleStatesStringFromContext; ac = null");
        return null;
    }

    /**
     * returns the AccessibleParent from an AccessibleContext
     */
    private AccessibleContext getAccessibleParentFromContext(final AccessibleContext ac) {
        if (ac==null)
            return null;
        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                Accessible a = ac.getAccessibleParent();
                if (a != null) {
                    AccessibleContext apc = a.getAccessibleContext();
                    if (apc != null) {
                        return apc;
                    }
                }
                return null;
            }
        }, ac);
    }

    /**
     * returns the AccessibleIndexInParent from an AccessibleContext
     */
    private int getAccessibleIndexInParentFromContext(final AccessibleContext ac) {
        if (ac==null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return ac.getAccessibleIndexInParent();
            }
        }, ac);
    }

    /**
     * returns the AccessibleChild count from an AccessibleContext
     */
    private int getAccessibleChildrenCountFromContext(final AccessibleContext ac) {
        if (ac==null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return ac.getAccessibleChildrenCount();
            }
        }, ac);
    }

    /**
     * returns the AccessibleChild Context from an AccessibleContext
     */
    private AccessibleContext getAccessibleChildFromContext(final AccessibleContext ac, final int index) {

        if (ac == null) {
            return null;
        }

        final JTable table = InvocationUtils.invokeAndWait(new Callable<JTable>() {
            @Override
            public JTable call() throws Exception {
                // work-around for AccessibleJTable.getCurrentAccessibleContext returning
                // wrong renderer component when cell contains more than one component
                Accessible parent = ac.getAccessibleParent();
                if (parent != null) {
                    int indexInParent = ac.getAccessibleIndexInParent();
                    Accessible child =
                            parent.getAccessibleContext().getAccessibleChild(indexInParent);
                    if (child instanceof JTable) {
                        return (JTable) child;
                    }
                }
                return null;
            }
        }, ac);

        if (table == null) {
            return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                @Override
                public AccessibleContext call() throws Exception {
                    Accessible a = ac.getAccessibleChild(index);
                    if (a != null) {
                        return a.getAccessibleContext();
                    }
                    return null;
                }
            }, ac);
        }

        final AccessibleTable at = getAccessibleTableFromContext(ac);

        final int row = getAccessibleTableRow(at, index);
        final int column = getAccessibleTableColumn(at, index);

        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                TableCellRenderer renderer = table.getCellRenderer(row, column);
                if (renderer == null) {
                    Class<?> columnClass = table.getColumnClass(column);
                    renderer = table.getDefaultRenderer(columnClass);
                }
                Component component =
                        renderer.getTableCellRendererComponent(table, table.getValueAt(row, column),
                                false, false, row, column);
                if (component instanceof Accessible) {
                    return component.getAccessibleContext();
                }
                return null;
            }
        }, ac);
    }

    /**
     * returns the AccessibleComponent bounds on screen from an AccessibleContext
     */
    private Rectangle getAccessibleBoundsOnScreenFromContext(final AccessibleContext ac) {
        if(ac==null)
            return null;
        return InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
            @Override
            public Rectangle call() throws Exception {
                AccessibleComponent acmp = ac.getAccessibleComponent();
                if (acmp != null) {
                    Rectangle r = acmp.getBounds();
                    if (r != null) {
                        try {
                            Point p = acmp.getLocationOnScreen();
                            if (p != null) {
                                r.x = p.x;
                                r.y = p.y;
                                return r;
                            }
                        } catch (Exception e) {
                            return null;
                        }
                    }
                }
                return null;
            }
        }, ac);
    }

    /**
     * returns the AccessibleComponent x-coord from an AccessibleContext
     */
    private int getAccessibleXcoordFromContext(AccessibleContext ac) {
        if (ac != null) {
            Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
            if (r != null) {
                debugString(" - Returning Accessible x coord from Context: " + r.x);
                return r.x;
            }
        } else {
            debugString("getAccessibleXcoordFromContext ac = null");
        }
        return -1;
    }

    /**
     * returns the AccessibleComponent y-coord from an AccessibleContext
     */
    private int getAccessibleYcoordFromContext(AccessibleContext ac) {
        debugString("getAccessibleYcoordFromContext() called");
        if (ac != null) {
            Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
            if (r != null) {
                return r.y;
            }
        } else {
        debugString("getAccessibleYcoordFromContext; ac = null");
        }
        return -1;
    }

    /**
     * returns the AccessibleComponent height from an AccessibleContext
     */
    private int getAccessibleHeightFromContext(AccessibleContext ac) {
        if (ac != null) {
            Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
            if (r != null) {
                return r.height;
            }
        } else {
            debugString("getAccessibleHeightFromContext; ac = null");
        }
        return -1;
    }

    /**
     * returns the AccessibleComponent width from an AccessibleContext
     */
    private int getAccessibleWidthFromContext(AccessibleContext ac) {
        if (ac != null) {
            Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
            if (r != null) {
                return r.width;
            }
        } else {
            debugString("getAccessibleWidthFromContext; ac = null");
        }
        return -1;
    }


    /**
     * returns the AccessibleComponent from an AccessibleContext
     */
    private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) {
        if (ac != null) {
            AccessibleComponent acmp = ac.getAccessibleComponent();
            if (acmp != null) {
                debugString("Returning AccessibleComponent Context");
                return acmp;
            }
        } else {
            debugString("getAccessibleComponentFromContext; ac = null");
        }
        return null;
    }

    /**
     * returns the AccessibleAction from an AccessibleContext
     */
    private AccessibleAction getAccessibleActionFromContext(final AccessibleContext ac) {
        debugString("Returning AccessibleAction Context");
        return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleAction>() {
            @Override
            public AccessibleAction call() throws Exception {
                return ac.getAccessibleAction();
            }
        }, ac);
    }

    /**
     * returns the AccessibleSelection from an AccessibleContext
     */
    private AccessibleSelection getAccessibleSelectionFromContext(final AccessibleContext ac) {
        return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleSelection>() {
            @Override
            public AccessibleSelection call() throws Exception {
                return ac.getAccessibleSelection();
            }
        }, ac);
    }

    /**
     * return the AccessibleText from an AccessibleContext
     */
    private AccessibleText getAccessibleTextFromContext(final AccessibleContext ac) {
        return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleText>() {
            @Override
            public AccessibleText call() throws Exception {
                return ac.getAccessibleText();
            }
        }, ac);
    }

    /**
     * return the AccessibleComponent from an AccessibleContext
     */
    private AccessibleValue getAccessibleValueFromContext(final AccessibleContext ac) {
        return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleValue>() {
            @Override
            public AccessibleValue call() throws Exception {
                return ac.getAccessibleValue();
            }
        }, ac);
    }

    /* ===== AccessibleText methods ===== */

    /**
     * returns the bounding rectangle for the text cursor
     * XXX
     */
    private Rectangle getCaretLocation(final AccessibleContext ac) {
    debugString("getCaretLocation");
        if (ac==null)
            return null;
        return InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
            @Override
            public Rectangle call() throws Exception {
                // workaround for JAAPI not returning cursor bounding rectangle
                Rectangle r = null;
                Accessible parent = ac.getAccessibleParent();
                if (parent instanceof Accessible) {
                    int indexInParent = ac.getAccessibleIndexInParent();
                    Accessible child =
                            parent.getAccessibleContext().getAccessibleChild(indexInParent);

                    if (child instanceof JTextComponent) {
                        JTextComponent text = (JTextComponent) child;
                        try {
                            r = text.modelToView(text.getCaretPosition());
                            if (r != null) {
                                Point p = text.getLocationOnScreen();
                                r.translate(p.x, p.y);
                            }
                        } catch (BadLocationException ble) {
                        }
                    }
                }
                return r;
            }
        }, ac);
    }

    /**
     * returns the x-coordinate for the text cursor rectangle
     */
    private int getCaretLocationX(AccessibleContext ac) {
        Rectangle r = getCaretLocation(ac);
        if (r != null) {
            return r.x;
        } else {
            return -1;
        }
    }

    /**
     * returns the y-coordinate for the text cursor rectangle
     */
    private int getCaretLocationY(AccessibleContext ac) {
        Rectangle r = getCaretLocation(ac);
        if (r != null) {
            return r.y;
        } else {
            return -1;
        }
    }

    /**
     * returns the height for the text cursor rectangle
     */
    private int getCaretLocationHeight(AccessibleContext ac) {
        Rectangle r = getCaretLocation(ac);
        if (r != null) {
            return r.height;
        } else {
            return -1;
        }
    }

    /**
     * returns the width for the text cursor rectangle
     */
    private int getCaretLocationWidth(AccessibleContext ac) {
        Rectangle r = getCaretLocation(ac);
        if (r != null) {
            return r.width;
        } else {
            return -1;
        }
    }

    /**
     * returns the character count from an AccessibleContext
     */
    private int getAccessibleCharCountFromContext(final AccessibleContext ac) {
        if (ac==null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (at != null) {
                    return at.getCharCount();
                }
                return -1;
            }
        }, ac);
    }

    /**
     * returns the caret position from an AccessibleContext
     */
    private int getAccessibleCaretPositionFromContext(final AccessibleContext ac) {
        if (ac==null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (at != null) {
                    return at.getCaretPosition();
                }
                return -1;
            }
        }, ac);
    }

    /**
     * Return the index at a specific point from an AccessibleContext
     * Point(x, y) is in screen coordinates.
     */
    private int getAccessibleIndexAtPointFromContext(final AccessibleContext ac,
                                                    final int x, final int y) {
        debugString("getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y);
        if (ac==null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                AccessibleComponent acomp = ac.getAccessibleComponent();
                if (at != null && acomp != null) {
                    // Convert x and y from screen coordinates to
                    // local coordinates.
                    try {
                        Point p = acomp.getLocationOnScreen();
                        int x1, y1;
                        if (p != null) {
                            x1 = x - p.x;
                            if (x1 < 0) {
                                x1 = 0;
                            }
                            y1 = y - p.y;
                            if (y1 < 0) {
                                y1 = 0;
                            }

                            Point newPoint = new Point(x1, y1);
                            int indexAtPoint = at.getIndexAtPoint(new Point(x1, y1));
                            return indexAtPoint;
                        }
                    } catch (Exception e) {
                    }
                }
                return -1;
            }
        }, ac);
    }

    /**
     * return the letter at a specific point from an AccessibleContext
     */
    private String getAccessibleLetterAtIndexFromContext(final AccessibleContext ac, final int index) {
        if (ac != null) {
            String s = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    AccessibleText at = ac.getAccessibleText();
                    if (at == null) return null;
                    return at.getAtIndex(AccessibleText.CHARACTER, index);
                }
            }, ac);
            if (s != null) {
                references.increment(s);
                return s;
            }
        } else {
            debugString("getAccessibleLetterAtIndexFromContext; ac = null");
        }
        return null;
    }

    /**
     * return the word at a specific point from an AccessibleContext
     */
    private String getAccessibleWordAtIndexFromContext(final AccessibleContext ac, final int index) {
        if (ac != null) {
            String s = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    AccessibleText at = ac.getAccessibleText();
                    if (at == null) return null;
                    return at.getAtIndex(AccessibleText.WORD, index);
                }
            }, ac);
            if (s != null) {
                references.increment(s);
                return s;
            }
        } else {
            debugString("getAccessibleWordAtIndexFromContext; ac = null");
        }
        return null;
    }

    /**
     * return the sentence at a specific point from an AccessibleContext
     */
    private String getAccessibleSentenceAtIndexFromContext(final AccessibleContext ac, final int index) {
        if (ac != null) {
            String s = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    AccessibleText at = ac.getAccessibleText();
                    if (at == null) return null;
                    return at.getAtIndex(AccessibleText.SENTENCE, index);
                }
            }, ac);
            if (s != null) {
                references.increment(s);
                return s;
            }
        } else {
            debugString("getAccessibleSentenceAtIndexFromContext; ac = null");
        }
        return null;
    }

    /**
     * return the text selection start from an AccessibleContext
     */
    private int getAccessibleTextSelectionStartFromContext(final AccessibleContext ac) {
        if (ac == null) return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (at != null) {
                    return at.getSelectionStart();
                }
                return -1;
            }
        }, ac);
    }

    /**
     * return the text selection end from an AccessibleContext
     */
    private int getAccessibleTextSelectionEndFromContext(final AccessibleContext ac) {
        if (ac == null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (at != null) {
                    return at.getSelectionEnd();
                }
                return -1;
            }
        }, ac);
    }

    /**
     * return the selected text from an AccessibleContext
     */
    private String getAccessibleTextSelectedTextFromContext(final AccessibleContext ac) {
        if (ac != null) {
            String s = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    AccessibleText at = ac.getAccessibleText();
                    if (at == null) return null;
                    return at.getSelectedText();
                }
            }, ac);
            if (s != null) {
                references.increment(s);
                return s;
            }
        } else {
            debugString("getAccessibleTextSelectedTextFromContext; ac = null");
        }
        return null;
    }

    /**
     * return the attribute string at a given index from an AccessibleContext
     */
    private String getAccessibleAttributesAtIndexFromContext(final AccessibleContext ac,
                                                             final int index) {
        if (ac == null)
            return null;
        AttributeSet as = InvocationUtils.invokeAndWait(new Callable<AttributeSet>() {
            @Override
            public AttributeSet call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (at != null) {
                    return at.getCharacterAttribute(index);
                }
                return null;
            }
        }, ac);
        String s = expandStyleConstants(as);
        if (s != null) {
            references.increment(s);
            return s;
        }
        return null;
    }

    /**
     * Get line info: left index of line
     *
     * algorithm:  cast back, doubling each time,
     *             'till find line boundaries
     *
     * return -1 if we can't get the info (e.g. index or at passed in
     * is bogus; etc.)
     */
    private int getAccessibleTextLineLeftBoundsFromContext(final AccessibleContext ac,
                                                          final int index) {
        if (ac == null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (at != null) {
                    int lineStart;
                    int offset;
                    Rectangle charRect;
                    Rectangle indexRect = at.getCharacterBounds(index);
                    int textLen = at.getCharCount();
                    if (indexRect == null) {
                        return -1;
                    }
                    // find the start of the line
                    //
                    offset = 1;
                    lineStart = index - offset < 0 ? 0 : index - offset;
                    charRect = at.getCharacterBounds(lineStart);
                    // slouch behind beginning of line
                    while (charRect != null
                            && charRect.y >= indexRect.y
                            && lineStart > 0) {
                        offset = offset << 1;
                        lineStart = index - offset < 0 ? 0 : index - offset;
                        charRect = at.getCharacterBounds(lineStart);
                    }
                    if (lineStart == 0) {    // special case: we're on the first line!
                        // we found it!
                    } else {
                        offset = offset >> 1;   // know boundary within last expansion
                        // ground forward to beginning of line
                        while (offset > 0) {
                            charRect = at.getCharacterBounds(lineStart + offset);
                            if (charRect.y < indexRect.y) { // still before line
                                lineStart += offset;
                            } else {
                                // leave lineStart alone, it's close!
                            }
                            offset = offset >> 1;
                        }
                        // subtract one 'cause we're already too far...
                        lineStart += 1;
                    }
                    return lineStart;
                }
                return -1;
            }
        }, ac);
    }

    /**
     * Get line info: right index of line
     *
     * algorithm:  cast back, doubling each time,
     *             'till find line boundaries
     *
     * return -1 if we can't get the info (e.g. index or at passed in
     * is bogus; etc.)
     */
    private int getAccessibleTextLineRightBoundsFromContext(final AccessibleContext ac, final int index) {
        if(ac == null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (at != null) {
                    int lineEnd;
                    int offset;
                    Rectangle charRect;
                    Rectangle indexRect = at.getCharacterBounds(index);
                    int textLen = at.getCharCount();
                    if (indexRect == null) {
                        return -1;
                    }
                    // find the end of the line
                    //
                    offset = 1;
                    lineEnd = index + offset > textLen - 1
                            ? textLen - 1 : index + offset;
                    charRect = at.getCharacterBounds(lineEnd);
                    // push past end of line
                    while (charRect != null &&
                            charRect.y <= indexRect.y &&
                            lineEnd < textLen - 1) {
                        offset = offset << 1;
                        lineEnd = index + offset > textLen - 1
                                ? textLen - 1 : index + offset;
                        charRect = at.getCharacterBounds(lineEnd);
                    }
                    if (lineEnd == textLen - 1) {    // special case: on the last line!
                        // we found it!
                    } else {
                        offset = offset >> 1;   // know boundary within last expansion
                        // pull back to end of line
                        while (offset > 0) {
                            charRect = at.getCharacterBounds(lineEnd - offset);
                            if (charRect.y > indexRect.y) { // still beyond line
                                lineEnd -= offset;
                            } else {
                                // leave lineEnd alone, it's close!
                            }
                            offset = offset >> 1;
                        }
                        // subtract one 'cause we're already too far...
                        lineEnd -= 1;
                    }
                    return lineEnd;
                }
                return -1;
            }
        }, ac);
    }

    /**
     * Get a range of text; null if indicies are bogus
     */
    private String getAccessibleTextRangeFromContext(final AccessibleContext ac,
                                                    final int start, final int end) {
        String s = InvocationUtils.invokeAndWait(new Callable<String>() {
            @Override
            public String call() throws Exception {
                if (ac != null) {
                    AccessibleText at = ac.getAccessibleText();
                    if (at != null) {
                        // start - end is inclusive
                        if (start > end) {
                            return null;
                        }
                        if (end >= at.getCharCount()) {
                            return null;
                        }
                        StringBuffer buf = new StringBuffer(end - start + 1);
                        for (int i = start; i <= end; i++) {
                            buf.append(at.getAtIndex(AccessibleText.CHARACTER, i));
                        }
                        return buf.toString();
                    }
                }
                return null;
            }
        }, ac);
        if (s != null) {
            references.increment(s);
            return s;
        } else {
            return null;
        }
    }

    /**
     * return the AttributeSet object at a given index from an AccessibleContext
     */
    private AttributeSet getAccessibleAttributeSetAtIndexFromContext(final AccessibleContext ac,
                                                                    final int index) {
        return InvocationUtils.invokeAndWait(new Callable<AttributeSet>() {
            @Override
            public AttributeSet call() throws Exception {
                if (ac != null) {
                    AccessibleText at = ac.getAccessibleText();
                    if (at != null) {
                        AttributeSet as = at.getCharacterAttribute(index);
                        if (as != null) {
                            AccessBridge.this.references.increment(as);
                            return as;
                        }
                    }
                }
                return null;
            }
        }, ac);
    }


    /**
     * return the bounding rectangle at index from an AccessibleContext
     */
    private Rectangle getAccessibleTextRectAtIndexFromContext(final AccessibleContext ac,
                                                        final int index) {
        // want to do this in global coords, so need to combine w/ac global coords
        Rectangle r = InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
            @Override
            public Rectangle call() throws Exception {
                // want to do this in global coords, so need to combine w/ac global coords
                if (ac != null) {
                    AccessibleText at = ac.getAccessibleText();
                    if (at != null) {
                        Rectangle rect = at.getCharacterBounds(index);
                        if (rect != null) {
                            String s = at.getAtIndex(AccessibleText.CHARACTER, index);
                            if (s != null && s.equals("\n")) {
                                rect.width = 0;
                            }
                            return rect;
                        }
                    }
                }
                return null;
            }
        }, ac);
        Rectangle acRect = getAccessibleBoundsOnScreenFromContext(ac);
        if (r != null && acRect != null) {
            r.translate(acRect.x, acRect.y);
            return r;
        }
        return null;
    }

    /**
     * return the AccessibleText character x-coord at index from an AccessibleContext
     */
    private int getAccessibleXcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) {
        if (ac != null) {
            Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
            if (r != null) {
                return r.x;
            }
        } else {
            debugString("getAccessibleXcoordTextRectAtIndexFromContext; ac = null");
        }
        return -1;
    }

    /**
     * return the AccessibleText character y-coord at index from an AccessibleContext
     */
    private int getAccessibleYcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) {
        if (ac != null) {
            Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
            if (r != null) {
                return r.y;
            }
        } else {
            debugString("getAccessibleYcoordTextRectAtIndexFromContext; ac = null");
        }
        return -1;
    }

    /**
     * return the AccessibleText character height at index from an AccessibleContext
     */
    private int getAccessibleHeightTextRectAtIndexFromContext(AccessibleContext ac, int index) {
        if (ac != null) {
            Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
            if (r != null) {
                return r.height;
            }
        } else {
            debugString("getAccessibleHeightTextRectAtIndexFromContext; ac = null");
        }
        return -1;
    }

    /**
     * return the AccessibleText character width at index from an AccessibleContext
     */
    private int getAccessibleWidthTextRectAtIndexFromContext(AccessibleContext ac, int index) {
        if (ac != null) {
            Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
            if (r != null) {
                return r.width;
            }
        } else {
            debugString("getAccessibleWidthTextRectAtIndexFromContext; ac = null");
        }
        return -1;
    }

    /* ===== AttributeSet methods for AccessibleText ===== */

    /**
     * return the bold setting from an AttributeSet
     */
    private boolean getBoldFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.isBold(as);
        } else {
            debugString("getBoldFromAttributeSet; as = null");
        }
        return false;
    }

    /**
     * return the italic setting from an AttributeSet
     */
    private boolean getItalicFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.isItalic(as);
        } else {
            debugString("getItalicFromAttributeSet; as = null");
        }
        return false;
    }

    /**
     * return the underline setting from an AttributeSet
     */
    private boolean getUnderlineFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.isUnderline(as);
        } else {
            debugString("getUnderlineFromAttributeSet; as = null");
        }
        return false;
    }

    /**
     * return the strikethrough setting from an AttributeSet
     */
    private boolean getStrikethroughFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.isStrikeThrough(as);
        } else {
            debugString("getStrikethroughFromAttributeSet; as = null");
        }
        return false;
    }

    /**
     * return the superscript setting from an AttributeSet
     */
    private boolean getSuperscriptFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.isSuperscript(as);
        } else {
            debugString("getSuperscriptFromAttributeSet; as = null");
        }
        return false;
    }

    /**
     * return the subscript setting from an AttributeSet
     */
    private boolean getSubscriptFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.isSubscript(as);
        } else {
            debugString("getSubscriptFromAttributeSet; as = null");
        }
        return false;
    }

    /**
     * return the background color from an AttributeSet
     */
    private String getBackgroundColorFromAttributeSet(AttributeSet as) {
        if (as != null) {
            String s = StyleConstants.getBackground(as).toString();
            if (s != null) {
                references.increment(s);
                return s;
            }
        } else {
            debugString("getBackgroundColorFromAttributeSet; as = null");
        }
        return null;
    }

    /**
     * return the foreground color from an AttributeSet
     */
    private String getForegroundColorFromAttributeSet(AttributeSet as) {
        if (as != null) {
            String s = StyleConstants.getForeground(as).toString();
            if (s != null) {
                references.increment(s);
                return s;
            }
        } else {
            debugString("getForegroundColorFromAttributeSet; as = null");
        }
        return null;
    }

    /**
     * return the font family from an AttributeSet
     */
    private String getFontFamilyFromAttributeSet(AttributeSet as) {
        if (as != null) {
            String s = StyleConstants.getFontFamily(as).toString();
            if (s != null) {
                references.increment(s);
                return s;
            }
        } else {
            debugString("getFontFamilyFromAttributeSet; as = null");
        }
        return null;
    }

    /**
     * return the font size from an AttributeSet
     */
    private int getFontSizeFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getFontSize(as);
        } else {
            debugString("getFontSizeFromAttributeSet; as = null");
        }
        return -1;
    }

    /**
     * return the alignment from an AttributeSet
     */
    private int getAlignmentFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getAlignment(as);
        } else {
            debugString("getAlignmentFromAttributeSet; as = null");
        }
        return -1;
    }

    /**
     * return the BiDi level from an AttributeSet
     */
    private int getBidiLevelFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getBidiLevel(as);
        } else {
            debugString("getBidiLevelFromAttributeSet; as = null");
        }
        return -1;
    }


    /**
     * return the first line indent from an AttributeSet
     */
    private float getFirstLineIndentFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getFirstLineIndent(as);
        } else {
            debugString("getFirstLineIndentFromAttributeSet; as = null");
        }
        return -1;
    }

    /**
     * return the left indent from an AttributeSet
     */
    private float getLeftIndentFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getLeftIndent(as);
        } else {
            debugString("getLeftIndentFromAttributeSet; as = null");
        }
        return -1;
    }

    /**
     * return the right indent from an AttributeSet
     */
    private float getRightIndentFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getRightIndent(as);
        } else {
            debugString("getRightIndentFromAttributeSet; as = null");
        }
        return -1;
    }

    /**
     * return the line spacing from an AttributeSet
     */
    private float getLineSpacingFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getLineSpacing(as);
        } else {
            debugString("getLineSpacingFromAttributeSet; as = null");
        }
        return -1;
    }

    /**
     * return the space above from an AttributeSet
     */
    private float getSpaceAboveFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getSpaceAbove(as);
        } else {
            debugString("getSpaceAboveFromAttributeSet; as = null");
        }
        return -1;
    }

    /**
     * return the space below from an AttributeSet
     */
    private float getSpaceBelowFromAttributeSet(AttributeSet as) {
        if (as != null) {
            return StyleConstants.getSpaceBelow(as);
        } else {
            debugString("getSpaceBelowFromAttributeSet; as = null");
        }
        return -1;
    }

    /**
     * Enumerate all StyleConstants in the AttributeSet
     *
     * We need to check explicitly, 'cause of the HTML package conversion
     * mechanism (they may not be stored as StyleConstants, just translated
     * to them when asked).
     *
     * (Use convenience methods where they are defined...)
     *
     * Not checking the following (which the IBM SNS guidelines says
     * should be defined):
     *    - ComponentElementName
     *    - IconElementName
     *    - NameAttribute
     *    - ResolveAttribute
     */
    private String expandStyleConstants(AttributeSet as) {
        Color c;
        Object o;
        String attrString = "";

        // ---------- check for various Character Constants

        attrString += "BidiLevel = " + StyleConstants.getBidiLevel(as);

        final Component comp = StyleConstants.getComponent(as);
        if (comp != null) {
            if (comp instanceof Accessible) {
                final AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                    @Override
                    public AccessibleContext call() throws Exception {
                        return comp.getAccessibleContext();
                    }
                }, comp);
                if (ac != null) {
                    attrString += "; Accessible Component = " + InvocationUtils.invokeAndWait(new Callable<String>() {
                        @Override
                        public String call() throws Exception {
                            return ac.getAccessibleName();
                        }
                    }, ac);
                } else {
                    attrString += "; Innaccessible Component = " + comp;
                }
            } else {
                attrString += "; Innaccessible Component = " + comp;
            }
        }

        Icon i = StyleConstants.getIcon(as);
        if (i != null) {
            if (i instanceof ImageIcon) {
                attrString += "; ImageIcon = " + ((ImageIcon) i).getDescription();
            } else {
                attrString += "; Icon = " + i;
            }
        }

        attrString += "; FontFamily = " + StyleConstants.getFontFamily(as);

        attrString += "; FontSize = " + StyleConstants.getFontSize(as);

        if (StyleConstants.isBold(as)) {
            attrString += "; bold";
        }

        if (StyleConstants.isItalic(as)) {
            attrString += "; italic";
        }

        if (StyleConstants.isUnderline(as)) {
            attrString += "; underline";
        }

        if (StyleConstants.isStrikeThrough(as)) {
            attrString += "; strikethrough";
        }

        if (StyleConstants.isSuperscript(as)) {
            attrString += "; superscript";
        }

        if (StyleConstants.isSubscript(as)) {
            attrString += "; subscript";
        }

        c = StyleConstants.getForeground(as);
        if (c != null) {
            attrString += "; Foreground = " + c;
        }

        c = StyleConstants.getBackground(as);
        if (c != null) {
            attrString += "; Background = " + c;
        }

        attrString += "; FirstLineIndent = " + StyleConstants.getFirstLineIndent(as);

        attrString += "; RightIndent = " + StyleConstants.getRightIndent(as);

        attrString += "; LeftIndent = " + StyleConstants.getLeftIndent(as);

        attrString += "; LineSpacing = " + StyleConstants.getLineSpacing(as);

        attrString += "; SpaceAbove = " + StyleConstants.getSpaceAbove(as);

        attrString += "; SpaceBelow = " + StyleConstants.getSpaceBelow(as);

        attrString += "; Alignment = " + StyleConstants.getAlignment(as);

        TabSet ts = StyleConstants.getTabSet(as);
        if (ts != null) {
            attrString += "; TabSet = " + ts;
        }

        return attrString;
    }


    /* ===== AccessibleValue methods ===== */

    /**
     * return the AccessibleValue current value from an AccessibleContext
     * returned using a String 'cause the value is a java Number
     *
     */
    private String getCurrentAccessibleValueFromContext(final AccessibleContext ac) {
        if (ac != null) {
            final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
                @Override
                public Number call() throws Exception {
                    AccessibleValue av = ac.getAccessibleValue();
                    if (av == null) return null;
                    return av.getCurrentAccessibleValue();
                }
            }, ac);
            if (value != null) {
                String s = value.toString();
                if (s != null) {
                    references.increment(s);
                    return s;
                }
            }
        } else {
            debugString("getCurrentAccessibleValueFromContext; ac = null");
        }
        return null;
    }

    /**
     * return the AccessibleValue maximum value from an AccessibleContext
     * returned using a String 'cause the value is a java Number
     *
     */
    private String getMaximumAccessibleValueFromContext(final AccessibleContext ac) {
        if (ac != null) {
            final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
                @Override
                public Number call() throws Exception {
                    AccessibleValue av = ac.getAccessibleValue();
                    if (av == null) return null;
                    return av.getMaximumAccessibleValue();
                }
            }, ac);
            if (value != null) {
                String s = value.toString();
                if (s != null) {
                    references.increment(s);
                    return s;
                }
            }
        } else {
            debugString("getMaximumAccessibleValueFromContext; ac = null");
        }
        return null;
    }

    /**
     * return the AccessibleValue minimum value from an AccessibleContext
     * returned using a String 'cause the value is a java Number
     *
     */
    private String getMinimumAccessibleValueFromContext(final AccessibleContext ac) {
        if (ac != null) {
            final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
                @Override
                public Number call() throws Exception {
                    AccessibleValue av = ac.getAccessibleValue();
                    if (av == null) return null;
                    return av.getMinimumAccessibleValue();
                }
            }, ac);
            if (value != null) {
                String s = value.toString();
                if (s != null) {
                    references.increment(s);
                    return s;
                }
            }
        } else {
            debugString("getMinimumAccessibleValueFromContext; ac = null");
        }
        return null;
    }


    /* ===== AccessibleSelection methods ===== */

    /**
     * add to the AccessibleSelection of an AccessibleContext child i
     *
     */
    private void addAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
        try {
            InvocationUtils.invokeAndWait(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    if (ac != null) {
                        AccessibleSelection as = ac.getAccessibleSelection();
                        if (as != null) {
                            as.addAccessibleSelection(i);
                        }
                    }
                    return null;
                }
            }, ac);
        } catch(Exception e){}
    }

    /**
     * clear all of the AccessibleSelection of an AccessibleContex
     *
     */
    private void clearAccessibleSelectionFromContext(final AccessibleContext ac) {
        try {
            InvocationUtils.invokeAndWait(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    AccessibleSelection as = ac.getAccessibleSelection();
                    if (as != null) {
                        as.clearAccessibleSelection();
                    }
                    return null;
                }
            }, ac);
        } catch(Exception e){}

    }

    /**
     * get the AccessibleContext of the i-th AccessibleSelection of an AccessibleContext
     *
     */
    private AccessibleContext getAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                if (ac != null) {
                    AccessibleSelection as = ac.getAccessibleSelection();
                    if (as != null) {
                        Accessible a = as.getAccessibleSelection(i);
                        if (a == null)
                            return null;
                        else
                            return a.getAccessibleContext();
                    }
                }
                return null;
            }
        }, ac);
    }

    /**
     * get number of things selected in the AccessibleSelection of an AccessibleContext
     *
     */
    private int getAccessibleSelectionCountFromContext(final AccessibleContext ac) {
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                if (ac != null) {
                    AccessibleSelection as = ac.getAccessibleSelection();
                    if (as != null) {
                        return as.getAccessibleSelectionCount();
                    }
                }
                return -1;
            }
        }, ac);
    }

    /**
     * return true if the i-th child of the AccessibleSelection of an AccessibleContext is selected
     *
     */
    private boolean isAccessibleChildSelectedFromContext(final AccessibleContext ac, final int i) {
        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                if (ac != null) {
                    AccessibleSelection as = ac.getAccessibleSelection();
                    if (as != null) {
                        return as.isAccessibleChildSelected(i);
                    }
                }
                return false;
            }
        }, ac);
    }

    /**
     * remove the i-th child from the AccessibleSelection of an AccessibleContext
     *
     */
    private void removeAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
        InvocationUtils.invokeAndWait(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                if (ac != null) {
                    AccessibleSelection as = ac.getAccessibleSelection();
                    if (as != null) {
                        as.removeAccessibleSelection(i);
                    }
                }
                return null;
            }
        }, ac);
    }

    /**
     * select all (if possible) of the children of the AccessibleSelection of an AccessibleContext
     *
     */
    private void selectAllAccessibleSelectionFromContext(final AccessibleContext ac) {
            InvocationUtils.invokeAndWait(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    if (ac != null) {
                        AccessibleSelection as = ac.getAccessibleSelection();
                        if (as != null) {
                            as.selectAllAccessibleSelection();
                        }
                    }
                    return null;
                }
            }, ac);
    }

    // ======== AccessibleTable ========

    ConcurrentHashMap<AccessibleTable,AccessibleContext> hashtab = new ConcurrentHashMap<>();

    /**
     * returns the AccessibleTable for an AccessibleContext
     */
    private AccessibleTable getAccessibleTableFromContext(final AccessibleContext ac) {
        return InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
            @Override
            public AccessibleTable call() throws Exception {
                if (ac != null) {
                    AccessibleTable at = ac.getAccessibleTable();
                    if (at != null) {
                        AccessBridge.this.hashtab.put(at, ac);
                        return at;
                    }
                }
                return null;
            }
        }, ac);
    }


    /*
     * returns the AccessibleContext that contains an AccessibleTable
     */
    private AccessibleContext getContextFromAccessibleTable(AccessibleTable at) {
        return hashtab.get(at);
    }

    /*
     * returns the row count for an AccessibleTable
     */
    private int getAccessibleTableRowCount(final AccessibleContext ac) {
        debugString("##### getAccessibleTableRowCount");
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                if (ac != null) {
                    AccessibleTable at = ac.getAccessibleTable();
                    if (at != null) {
                        return at.getAccessibleRowCount();
                    }
                }
                return -1;
            }
        }, ac);
    }

    /*
     * returns the column count for an AccessibleTable
     */
    private int getAccessibleTableColumnCount(final AccessibleContext ac) {
        debugString("##### getAccessibleTableColumnCount");
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                if (ac != null) {
                    AccessibleTable at = ac.getAccessibleTable();
                    if (at != null) {
                        return at.getAccessibleColumnCount();
                    }
                }
                return -1;
            }
        }, ac);
    }

    /*
     * returns the AccessibleContext for an AccessibleTable cell
     */
    private AccessibleContext getAccessibleTableCellAccessibleContext(final AccessibleTable at,
                                                                      final int row, final int column) {
        debugString("getAccessibleTableCellAccessibleContext: at = "+at.getClass());
        if (at == null) return null;
        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                if (!(at instanceof AccessibleContext)) {
                    Accessible a = at.getAccessibleAt(row, column);
                    if (a != null) {
                        return a.getAccessibleContext();
                    }
                } else {
                    // work-around for AccessibleJTable.getCurrentAccessibleContext returning
                    // wrong renderer component when cell contains more than one component
                    AccessibleContext ac = (AccessibleContext) at;
                    Accessible parent = ac.getAccessibleParent();
                    if (parent != null) {
                        int indexInParent = ac.getAccessibleIndexInParent();
                        Accessible child =
                                parent.getAccessibleContext().getAccessibleChild(indexInParent);
                        if (child instanceof JTable) {
                            JTable table = (JTable) child;

                            TableCellRenderer renderer = table.getCellRenderer(row, column);
                            if (renderer == null) {
                                Class<?> columnClass = table.getColumnClass(column);
                                renderer = table.getDefaultRenderer(columnClass);
                            }
                            Component component =
                                    renderer.getTableCellRendererComponent(table, table.getValueAt(row, column),
                                            false, false, row, column);
                            if (component instanceof Accessible) {
                                return component.getAccessibleContext();
                            }
                        }
                    }
                }
                return null;
            }
        }, getContextFromAccessibleTable(at));
    }

    /*
     * returns the index of a cell at a given row and column in an AccessibleTable
     */
    private int getAccessibleTableCellIndex(final AccessibleTable at, int row, int column) {
        debugString("##### getAccessibleTableCellIndex: at="+at);
        if (at != null) {
            int cellIndex = row *
                InvocationUtils.invokeAndWait(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        return at.getAccessibleColumnCount();
                    }
                }, getContextFromAccessibleTable(at)) +
                column;
            debugString("   ##### getAccessibleTableCellIndex="+cellIndex);
            return cellIndex;
        }
        debugString(" ##### getAccessibleTableCellIndex FAILED");
        return -1;
    }

    /*
     * returns the row extent of a cell at a given row and column in an AccessibleTable
     */
    private int getAccessibleTableCellRowExtent(final AccessibleTable at, final int row, final int column) {
        debugString("##### getAccessibleTableCellRowExtent");
        if (at != null) {
            int rowExtent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                                                              @Override
                                                              public Integer call() throws Exception {
                                                                  return at.getAccessibleRowExtentAt(row, column);
                                                              }
                                                          },
                    getContextFromAccessibleTable(at));
            debugString("   ##### getAccessibleTableCellRowExtent="+rowExtent);
            return rowExtent;
        }
        debugString(" ##### getAccessibleTableCellRowExtent FAILED");
        return -1;
    }

    /*
     * returns the column extent of a cell at a given row and column in an AccessibleTable
     */
    private int getAccessibleTableCellColumnExtent(final AccessibleTable at, final int row, final int column) {
        debugString("##### getAccessibleTableCellColumnExtent");
        if (at != null) {
            int columnExtent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                                                                 @Override
                                                                 public Integer call() throws Exception {
                                                                     return at.getAccessibleColumnExtentAt(row, column);
                                                                 }
                                                             },
                    getContextFromAccessibleTable(at));
            debugString("   ##### getAccessibleTableCellColumnExtent="+columnExtent);
            return columnExtent;
        }
        debugString(" ##### getAccessibleTableCellColumnExtent FAILED");
        return -1;
    }

    /*
     * returns whether a cell is selected at a given row and column in an AccessibleTable
     */
    private boolean isAccessibleTableCellSelected(final AccessibleTable at, final int row,
                         final int column) {
        debugString("##### isAccessibleTableCellSelected: ["+row+"]["+column+"]");
        if (at == null)
            return false;
        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                boolean isSelected = false;
                Accessible a = at.getAccessibleAt(row, column);
                if (a != null) {
                    AccessibleContext ac = a.getAccessibleContext();
                    if (ac == null)
                        return false;
                    AccessibleStateSet as = ac.getAccessibleStateSet();
                    if (as != null) {
                        isSelected = as.contains(AccessibleState.SELECTED);
                    }
                }
                return isSelected;
            }
        }, getContextFromAccessibleTable(at));
    }

    /*
     * returns an AccessibleTable that represents the row header in an
     * AccessibleTable
     */
    private AccessibleTable getAccessibleTableRowHeader(final AccessibleContext ac) {
        debugString(" #####  getAccessibleTableRowHeader called");
        AccessibleTable at = InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
            @Override
            public AccessibleTable call() throws Exception {
                if (ac != null) {
                    AccessibleTable at = ac.getAccessibleTable();
                    if (at != null) {
                        return at.getAccessibleRowHeader();
                    }
                }
                return null;
            }
        }, ac);
        if (at != null) {
            hashtab.put(at, ac);
        }
        return at;
    }

    /*
     * returns an AccessibleTable that represents the column header in an
     * AccessibleTable
     */
    private AccessibleTable getAccessibleTableColumnHeader(final AccessibleContext ac) {
    debugString("##### getAccessibleTableColumnHeader");
        if (ac == null)
            return null;
        AccessibleTable at = InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
            @Override
            public AccessibleTable call() throws Exception {
                // workaround for getAccessibleColumnHeader NPE
                // when the table header is null
                Accessible parent = ac.getAccessibleParent();
                if (parent != null) {
                    int indexInParent = ac.getAccessibleIndexInParent();
                    Accessible child =
                            parent.getAccessibleContext().getAccessibleChild(indexInParent);
                    if (child instanceof JTable) {
                        JTable table = (JTable) child;
                        if (table.getTableHeader() == null) {
                            return null;
                        }
                    }
                }
                AccessibleTable at = ac.getAccessibleTable();
                if (at != null) {
                    return at.getAccessibleColumnHeader();
                }
                return null;
            }
        }, ac);
        if (at != null) {
            hashtab.put(at, ac);
        }
        return at;
    }

    /*
     * returns the number of row headers in an AccessibleTable that represents
     * the row header in an AccessibleTable
     */
    private int getAccessibleTableRowHeaderRowCount(AccessibleContext ac) {

    debugString(" #####  getAccessibleTableRowHeaderRowCount called");
        if (ac != null) {
            final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac);
            if (atRowHeader != null) {
                return InvocationUtils.invokeAndWait(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        if (atRowHeader != null) {
                            return atRowHeader.getAccessibleRowCount();
                        }
                        return -1;
                    }
                }, ac);
            }
        }
        return -1;
    }

    /*
     * returns the number of column headers in an AccessibleTable that represents
     * the row header in an AccessibleTable
     */
    private int getAccessibleTableRowHeaderColumnCount(AccessibleContext ac) {
        debugString(" #####  getAccessibleTableRowHeaderColumnCount called");
        if (ac != null) {
            final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac);
            if (atRowHeader != null) {
                return InvocationUtils.invokeAndWait(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        if (atRowHeader != null) {
                            return atRowHeader.getAccessibleColumnCount();
                        }
                        return -1;
                    }
                }, ac);
            }
        }
        debugString(" ##### getAccessibleTableRowHeaderColumnCount FAILED");
        return -1;
    }

    /*
     * returns the number of row headers in an AccessibleTable that represents
     * the column header in an AccessibleTable
     */
    private int getAccessibleTableColumnHeaderRowCount(AccessibleContext ac) {

    debugString("##### getAccessibleTableColumnHeaderRowCount");
        if (ac != null) {
            final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac);
            if (atColumnHeader != null) {
                return InvocationUtils.invokeAndWait(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        if (atColumnHeader != null) {
                            return atColumnHeader.getAccessibleRowCount();
                        }
                        return -1;
                    }
                }, ac);
            }
        }
        debugString(" ##### getAccessibleTableColumnHeaderRowCount FAILED");
        return -1;
    }

    /*
     * returns the number of column headers in an AccessibleTable that represents
     * the column header in an AccessibleTable
     */
    private int getAccessibleTableColumnHeaderColumnCount(AccessibleContext ac) {

    debugString("#####  getAccessibleTableColumnHeaderColumnCount");
        if (ac != null) {
            final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac);
            if (atColumnHeader != null) {
                return InvocationUtils.invokeAndWait(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        if (atColumnHeader != null) {
                            return atColumnHeader.getAccessibleColumnCount();
                        }
                        return -1;
                    }
                }, ac);
            }
        }
        debugString(" ##### getAccessibleTableColumnHeaderColumnCount FAILED");
        return -1;
    }

    /*
     * returns the description of a row header in an AccessibleTable
     */
    private AccessibleContext getAccessibleTableRowDescription(final AccessibleTable table,
                                                              final int row) {
        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                if (table != null) {
                    Accessible a = table.getAccessibleRowDescription(row);
                    if (a != null) {
                        return a.getAccessibleContext();
                    }
                }
                return null;
            }
        }, getContextFromAccessibleTable(table));
    }

    /*
     * returns the description of a column header in an AccessibleTable
     */
    private AccessibleContext getAccessibleTableColumnDescription(final AccessibleTable at,
                                                                 final int column) {
        if (at == null)
            return null;
        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                Accessible a = at.getAccessibleColumnDescription(column);
                if (a != null) {
                    return a.getAccessibleContext();
                }
                return null;
            }
        }, getContextFromAccessibleTable(at));
    }

    /*
     * returns the number of rows selected in an AccessibleTable
     */
    private int getAccessibleTableRowSelectionCount(final AccessibleTable at) {
        if (at != null) {
            return InvocationUtils.invokeAndWait(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    int[] selections = at.getSelectedAccessibleRows();
                    if (selections != null)
                        return selections.length;
                    else
                        return -1;
                }
            }, getContextFromAccessibleTable(at));
        }
        return -1;
    }

    /*
     * returns the row number of the i-th selected row in an AccessibleTable
     */
    private int getAccessibleTableRowSelections(final AccessibleTable at, final int i) {
        if (at != null) {
            return InvocationUtils.invokeAndWait(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    int[] selections = at.getSelectedAccessibleRows();
                    if (selections.length > i) {
                        return selections[i];
                    }
                    return -1;
                }
            }, getContextFromAccessibleTable(at));
        }
        return -1;
    }

    /*
     * returns whether a row is selected in an AccessibleTable
     */
    private boolean isAccessibleTableRowSelected(final AccessibleTable at,
                                                 final int row) {
        if (at == null)
            return false;
        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                return at.isAccessibleRowSelected(row);
            }
         }, getContextFromAccessibleTable(at));
    }

    /*
     * returns whether a column is selected in an AccessibleTable
     */
    private boolean isAccessibleTableColumnSelected(final AccessibleTable at,
                                                   final int column) {
        if (at == null)
            return false;
        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                return at.isAccessibleColumnSelected(column);
            }
         }, getContextFromAccessibleTable(at));
    }

    /*
     * returns the number of columns selected in an AccessibleTable
     */
    private int getAccessibleTableColumnSelectionCount(final AccessibleTable at) {
        if (at == null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int[] selections = at.getSelectedAccessibleColumns();
                if (selections != null)
                    return selections.length;
                else
                    return -1;
            }
        }, getContextFromAccessibleTable(at));
    }

    /*
     * returns the row number of the i-th selected row in an AccessibleTable
     */
    private int getAccessibleTableColumnSelections(final AccessibleTable at, final int i) {
        if (at == null)
            return -1;
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int[] selections = at.getSelectedAccessibleColumns();
                if (selections != null && selections.length > i) {
                    return selections[i];
                }
                return -1;
            }
        }, getContextFromAccessibleTable(at));
    }

    /* ===== AccessibleExtendedTable (since 1.4) ===== */

    /*
     * returns the row number for a cell at a given index in an AccessibleTable
     */
    private int getAccessibleTableRow(final AccessibleTable at, int index) {
        if (at == null)
            return -1;
        int colCount=InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return at.getAccessibleColumnCount();
            }
        }, getContextFromAccessibleTable(at));
        return index / colCount;
    }

    /*
     * returns the column number for a cell at a given index in an AccessibleTable
     */
    private int getAccessibleTableColumn(final AccessibleTable at, int index) {
        if (at == null)
            return -1;
        int colCount=InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return at.getAccessibleColumnCount();
            }
        }, getContextFromAccessibleTable(at));
        return index % colCount;
    }

    /*
     * returns the index for a cell at a given row and column in an
     * AccessibleTable
     */
    private int getAccessibleTableIndex(final AccessibleTable at, int row, int column) {
        if (at == null)
            return -1;
        int colCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return at.getAccessibleColumnCount();
            }
         }, getContextFromAccessibleTable(at));
        return row * colCount + column;
    }

    // ===== AccessibleRelationSet =====

    /*
     * returns the number of relations in the AccessibleContext's
     * AccessibleRelationSet
     */
    private int getAccessibleRelationCount(final AccessibleContext ac) {
        {
            if (ac != null) {
                AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable<AccessibleRelationSet>() {
                    @Override
                    public AccessibleRelationSet call() throws Exception {
                        return ac.getAccessibleRelationSet();
                    }
                }, ac);
                if (ars != null)
                    return ars.size();
            }
        }
        return 0;
    }

    /*
     * returns the ith relation key in the AccessibleContext's
     * AccessibleRelationSet
     */
    private String getAccessibleRelationKey(final AccessibleContext ac, final int i) {
        return InvocationUtils.invokeAndWait(new Callable<String>() {
            @Override
            public String call() throws Exception {
                if (ac != null) {
                    AccessibleRelationSet ars = ac.getAccessibleRelationSet();
                    if (ars != null) {
                        AccessibleRelation[] relations = ars.toArray();
                        if (relations != null && i >= 0 && i < relations.length) {
                            return relations[i].getKey();
                        }
                    }
                }
                return null;
            }
        }, ac);
    }

    /*
     * returns the number of targets in a relation in the AccessibleContext's
     * AccessibleRelationSet
     */
    private int getAccessibleRelationTargetCount(final AccessibleContext ac, final int i) {
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                if (ac != null) {
                    AccessibleRelationSet ars = ac.getAccessibleRelationSet();
                    if (ars != null) {
                        AccessibleRelation[] relations = ars.toArray();
                        if (relations != null && i >= 0 && i < relations.length) {
                            Object[] targets = relations[i].getTarget();
                            return targets.length;
                        }
                    }
                }
                return -1;
            }
        }, ac);
    }

    /*
     * returns the jth target in the ith relation in the AccessibleContext's
     * AccessibleRelationSet
     */
    private AccessibleContext getAccessibleRelationTarget(final AccessibleContext ac,
                                                         final int i, final int j) {
        debugString("***** getAccessibleRelationTarget");
        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                if (ac != null) {
                    AccessibleRelationSet ars = ac.getAccessibleRelationSet();
                    if (ars != null) {
                        AccessibleRelation[] relations = ars.toArray();
                        if (relations != null && i >= 0 && i < relations.length) {
                            Object[] targets = relations[i].getTarget();
                            if (targets != null && j >= 0 & j < targets.length) {
                                Object o = targets[j];
                                if (o instanceof Accessible) {
                                    return ((Accessible) o).getAccessibleContext();
                                }
                            }
                        }
                    }
                }
                return null;
            }
        }, ac);
    }

    // ========= AccessibleHypertext =========

    private Map<AccessibleHypertext, AccessibleContext> hyperTextContextMap = new WeakHashMap<>();
    private Map<AccessibleHyperlink, AccessibleContext> hyperLinkContextMap = new WeakHashMap<>();

    /*
     * Returns the AccessibleHypertext
     */
    private AccessibleHypertext getAccessibleHypertext(final AccessibleContext ac) {
        debugString("getAccessibleHyperlink");
        if (ac==null)
            return null;
        AccessibleHypertext hypertext = InvocationUtils.invokeAndWait(new Callable<AccessibleHypertext>() {
            @Override
            public AccessibleHypertext call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (!(at instanceof AccessibleHypertext)) {
                    return null;
                }
                return ((AccessibleHypertext) at);
            }
        }, ac);
        hyperTextContextMap.put(hypertext, ac);
        return hypertext;
    }

    /*
     * Returns the number of AccessibleHyperlinks
     */
    private int getAccessibleHyperlinkCount(AccessibleContext ac) {
        debugString("getAccessibleHyperlinkCount");
        if (ac == null) {
            return 0;
        }
        final AccessibleHypertext hypertext = getAccessibleHypertext(ac);
        if (hypertext == null) {
            return 0;
        }
        //return hypertext.getLinkCount();
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return hypertext.getLinkCount();
            }
        }, ac);
    }

    /*
     * Returns the hyperlink at the specified index
     */
    private AccessibleHyperlink getAccessibleHyperlink(final AccessibleHypertext hypertext, final int i) {
        debugString("getAccessibleHyperlink");
        if (hypertext == null) {
            return null;
        }
        AccessibleContext ac = hyperTextContextMap.get(hypertext);
        if ( i < 0 || i >=
             InvocationUtils.invokeAndWait(new Callable<Integer>() {
                 @Override
                 public Integer call() throws Exception {
                     return hypertext.getLinkCount();
                 }
             }, ac) ) {
            return null;
        }
        AccessibleHyperlink acLink = InvocationUtils.invokeAndWait(new Callable<AccessibleHyperlink>() {
            @Override
            public AccessibleHyperlink call() throws Exception {
                AccessibleHyperlink link = hypertext.getLink(i);
                if (link == null || (!link.isValid())) {
                    return null;
                }
                return link;
            }
        }, ac);
        hyperLinkContextMap.put(acLink, ac);
        return acLink;
    }

    /*
     * Returns the hyperlink object description
     */
    private String getAccessibleHyperlinkText(final AccessibleHyperlink link) {
        debugString("getAccessibleHyperlinkText");
        if (link == null) {
            return null;
        }
        return InvocationUtils.invokeAndWait(new Callable<String>() {
            @Override
            public String call() throws Exception {
                Object o = link.getAccessibleActionDescription(0);
                if (o != null) {
                    return o.toString();
                }
                return null;
            }
        }, hyperLinkContextMap.get(link));
    }

    /*
     * Returns the hyperlink URL
     */
    private String getAccessibleHyperlinkURL(final AccessibleHyperlink link) {
        debugString("getAccessibleHyperlinkURL");
        if (link == null) {
            return null;
        }
        return InvocationUtils.invokeAndWait(new Callable<String>() {
            @Override
            public String call() throws Exception {
                Object o = link.getAccessibleActionObject(0);
                if (o != null) {
                    return o.toString();
                } else {
                    return null;
                }
            }
        }, hyperLinkContextMap.get(link));
    }

    /*
     * Returns the start index of the hyperlink text
     */
    private int getAccessibleHyperlinkStartIndex(final AccessibleHyperlink link) {
        debugString("getAccessibleHyperlinkStartIndex");
        if (link == null) {
            return -1;
        }
        return  InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return link.getStartIndex();
            }
        }, hyperLinkContextMap.get(link));
    }

    /*
     * Returns the end index of the hyperlink text
     */
    private int getAccessibleHyperlinkEndIndex(final AccessibleHyperlink link) {
        debugString("getAccessibleHyperlinkEndIndex");
        if (link == null) {
            return -1;
        }
        return  InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return link.getEndIndex();
            }
        }, hyperLinkContextMap.get(link));
    }

    /*
     * Returns the index into an array of hyperlinks that
     * is associated with this character index, or -1 if there
     * is no hyperlink associated with this index.
     */
    private int getAccessibleHypertextLinkIndex(final AccessibleHypertext hypertext, final int charIndex) {
        debugString("getAccessibleHypertextLinkIndex: charIndex = "+charIndex);
        if (hypertext == null) {
            return -1;
        }
        int linkIndex = InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return hypertext.getLinkIndex(charIndex);
            }
        }, hyperTextContextMap.get(hypertext));
        debugString("getAccessibleHypertextLinkIndex returning "+linkIndex);
        return linkIndex;
    }

    /*
     * Actives the hyperlink
     */
    private boolean activateAccessibleHyperlink(final AccessibleContext ac,
                                                final AccessibleHyperlink link) {
        //debugString("activateAccessibleHyperlink: link = "+link.getClass());
        if (link == null) {
            return false;
        }
        boolean retval = InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                return link.doAccessibleAction(0);
            }
        }, ac);
        debugString("activateAccessibleHyperlink: returning = "+retval);
        return retval;
    }


    // ============ AccessibleKeyBinding =============

    /*
     * returns the component mnemonic
     */
    private KeyStroke getMnemonic(final AccessibleContext ac) {
        if (ac == null)
            return null;
        return InvocationUtils.invokeAndWait(new Callable<KeyStroke>() {
            @Override
            public KeyStroke call() throws Exception {
                AccessibleComponent comp = ac.getAccessibleComponent();
                if (!(comp instanceof AccessibleExtendedComponent)) {
                    return null;
                }
                AccessibleExtendedComponent aec = (AccessibleExtendedComponent) comp;
                if (aec != null) {
                    AccessibleKeyBinding akb = aec.getAccessibleKeyBinding();
                    if (akb != null) {
                        Object o = akb.getAccessibleKeyBinding(0);
                        if (o instanceof KeyStroke) {
                            return (KeyStroke) o;
                        }
                    }
                }
                return null;
            }
        }, ac);
    }

    /*
     * returns the JMenuItem accelerator
     */
    private KeyStroke getAccelerator(final AccessibleContext ac) {
        // workaround for getAccessibleKeyBinding not returning the
        // JMenuItem accelerator
        if (ac == null)
            return null;
        return InvocationUtils.invokeAndWait(new Callable<KeyStroke>() {
            @Override
            public KeyStroke call() throws Exception {
                Accessible parent = ac.getAccessibleParent();
                if (parent instanceof Accessible) {
                    int indexInParent = ac.getAccessibleIndexInParent();
                    Accessible child =
                            parent.getAccessibleContext().getAccessibleChild(indexInParent);
                    if (child instanceof JMenuItem) {
                        JMenuItem menuItem = (JMenuItem) child;
                        if (menuItem == null)
                            return null;
                        KeyStroke keyStroke = menuItem.getAccelerator();
                        return keyStroke;
                    }
                }
                return null;
            }
        }, ac);
    }

    /*
     * returns 1-24 to indicate which F key is being used for a shortcut or 0 otherwise
     */
    private int fKeyNumber(KeyStroke keyStroke) {
        if (keyStroke == null)
            return 0;
        int fKey = 0;
        String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode());
        if (keyText != null && (keyText.length() == 2 || keyText.length() == 3)) {
            String prefix = keyText.substring(0, 1);
            if (prefix.equals("F")) {
                try {
                    int suffix = Integer.parseInt(keyText.substring(1));
                    if (suffix >= 1 && suffix <= 24) {
                        fKey = suffix;
                    }
                } catch (Exception e) { // ignore NumberFormatException
                }
            }
        }
        return fKey;
    }

    /*
     * returns one of several important control characters or 0 otherwise
     */
    private int controlCode(KeyStroke keyStroke) {
        if (keyStroke == null)
            return 0;
        int code = keyStroke.getKeyCode();
        switch (code) {
            case KeyEvent.VK_BACK_SPACE:
            case KeyEvent.VK_DELETE:
            case KeyEvent.VK_DOWN:
            case KeyEvent.VK_END:
            case KeyEvent.VK_HOME:
            case KeyEvent.VK_INSERT:
            case KeyEvent.VK_KP_DOWN:
            case KeyEvent.VK_KP_LEFT:
            case KeyEvent.VK_KP_RIGHT:
            case KeyEvent.VK_KP_UP:
            case KeyEvent.VK_LEFT:
            case KeyEvent.VK_PAGE_DOWN:
            case KeyEvent.VK_PAGE_UP:
            case KeyEvent.VK_RIGHT:
            case KeyEvent.VK_UP:
                break;
            default:
                code = 0;
                break;
        }
        return code;
    }

    /*
     * returns the KeyStoke character
     */
    private char getKeyChar(KeyStroke keyStroke) {
        // If the shortcut is an FKey return 1-24
        if (keyStroke == null)
            return 0;
        int fKey = fKeyNumber(keyStroke);
        if (fKey != 0) {
            // return 0x00000001 through 0x00000018
            debugString("   Shortcut is: F" + fKey);
            return (char)fKey;
        }
        // If the accelerator is a control character, return it
        int keyCode = controlCode(keyStroke);
        if (keyCode != 0) {
            debugString("   Shortcut is control character: " + Integer.toHexString(keyCode));
            return (char)keyCode;
        }
        String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode());
        debugString("   Shortcut is: " + keyText);
        if (keyText != null || keyText.length() > 0) {
            CharSequence seq = keyText.subSequence(0, 1);
            if (seq != null || seq.length() > 0) {
                return seq.charAt(0);
            }
        }
        return 0;
    }

    /*
     * returns the KeyStroke modifiers as an int
     */
    private int getModifiers(KeyStroke keyStroke) {
        if (keyStroke == null)
            return 0;
        debugString("In AccessBridge.getModifiers");
        // modifiers is a bit strip where bits 0-7 indicate a traditional modifier
        // such as Ctrl/Alt/Shift, bit 8 indicates an F key shortcut, and bit 9 indicates
        // a control code shortcut such as the delete key.

        int modifiers = 0;
        // Is the shortcut an FKey?
        if (fKeyNumber(keyStroke) != 0) {
            modifiers |= 1 << 8;
        }
        // Is the shortcut a control code?
        if (controlCode(keyStroke) != 0) {
            modifiers |= 1 << 9;
        }
        // The following is needed in order to handle translated modifiers.
        // getKeyModifiersText doesn't work because for example in German Strg is
        // returned for Ctrl.

        // There can be more than one modifier, e.g. if the modifier is ctrl + shift + B
        // the toString text is "shift ctrl pressed B". Need to parse through that.
        StringTokenizer st = new StringTokenizer(keyStroke.toString());
        while (st.hasMoreTokens()) {
            String text = st.nextToken();
            // Meta+Ctrl+Alt+Shift
            // 0-3 are shift, ctrl, meta, alt
            // 4-7 are for Solaris workstations (though not being used)
            if (text.startsWith("met")) {
                debugString("   found meta");
                modifiers |= ActionEvent.META_MASK;
            }
            if (text.startsWith("ctr")) {
                debugString("   found ctrl");
                modifiers |= ActionEvent.CTRL_MASK;
            }
            if (text.startsWith("alt")) {
                debugString("   found alt");
                modifiers |= ActionEvent.ALT_MASK;
            }
            if (text.startsWith("shi")) {
                debugString("   found shift");
                modifiers |= ActionEvent.SHIFT_MASK;
            }
        }
        debugString("   returning modifiers: 0x" + Integer.toHexString(modifiers));
        return modifiers;
    }

    /*
     * returns the number of key bindings associated with this context
     */
    private int getAccessibleKeyBindingsCount(AccessibleContext ac) {
        if (ac == null)
            return 0;
        int count = 0;

        if (getMnemonic(ac) != null) {
            count++;
        }
        if (getAccelerator(ac) != null) {
            count++;
        }
        return count;
    }

    /*
     * returns the key binding character at the specified index
     */
    private char getAccessibleKeyBindingChar(AccessibleContext ac, int index) {
        if (ac == null)
            return 0;
        if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic
            KeyStroke keyStroke = getAccelerator(ac);
            if (keyStroke != null) {
                return getKeyChar(keyStroke);
            }
        }
        if (index == 0) {   // mnemonic
            KeyStroke keyStroke = getMnemonic(ac);
            if (keyStroke != null) {
                return getKeyChar(keyStroke);
            }
        } else if (index == 1) { // accelerator
            KeyStroke keyStroke = getAccelerator(ac);
            if (keyStroke != null) {
                return getKeyChar(keyStroke);
            }
        }
        return 0;
    }

    /*
     * returns the key binding modifiers at the specified index
     */
    private int getAccessibleKeyBindingModifiers(AccessibleContext ac, int index) {
        if (ac == null)
            return 0;
        if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic
            KeyStroke keyStroke = getAccelerator(ac);
            if (keyStroke != null) {
                return getModifiers(keyStroke);
            }
        }
        if (index == 0) {   // mnemonic
            KeyStroke keyStroke = getMnemonic(ac);
            if (keyStroke != null) {
                return getModifiers(keyStroke);
            }
        } else if (index == 1) { // accelerator
            KeyStroke keyStroke = getAccelerator(ac);
            if (keyStroke != null) {
                return getModifiers(keyStroke);
            }
        }
        return 0;
    }

    // ========== AccessibleIcon ============

    /*
     * return the number of icons associated with this context
     */
    private int getAccessibleIconsCount(final AccessibleContext ac) {
        debugString("getAccessibleIconsCount");
        if (ac == null) {
            return 0;
        }
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleIcon[] ai = ac.getAccessibleIcon();
                if (ai == null) {
                    return 0;
                }
                return ai.length;
            }
        }, ac);
    }

    /*
     * return icon description at the specified index
     */
    private String getAccessibleIconDescription(final AccessibleContext ac, final int index) {
        debugString("getAccessibleIconDescription: index = "+index);
        if (ac == null) {
            return null;
        }
        return InvocationUtils.invokeAndWait(new Callable<String>() {
            @Override
            public String call() throws Exception {
                AccessibleIcon[] ai = ac.getAccessibleIcon();
                if (ai == null || index < 0 || index >= ai.length) {
                    return null;
                }
                return ai[index].getAccessibleIconDescription();
            }
        }, ac);
    }

    /*
     * return icon height at the specified index
     */
    private int getAccessibleIconHeight(final AccessibleContext ac, final int index) {
        debugString("getAccessibleIconHeight: index = "+index);
        if (ac == null) {
            return 0;
        }
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleIcon[] ai = ac.getAccessibleIcon();
                if (ai == null || index < 0 || index >= ai.length) {
                    return 0;
                }
                return ai[index].getAccessibleIconHeight();
            }
        }, ac);
    }

    /*
     * return icon width at the specified index
     */
    private int getAccessibleIconWidth(final AccessibleContext ac, final int index) {
        debugString("getAccessibleIconWidth: index = "+index);
        if (ac == null) {
            return 0;
        }
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleIcon[] ai = ac.getAccessibleIcon();
                if (ai == null || index < 0 || index >= ai.length) {
                    return 0;
                }
                return ai[index].getAccessibleIconWidth();
            }
        }, ac);
    }

    // ========= AccessibleAction ===========

    /*
     * return the number of icons associated with this context
     */
    private int getAccessibleActionsCount(final AccessibleContext ac) {
        debugString("getAccessibleActionsCount");
        if (ac == null) {
            return 0;
        }
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                AccessibleAction aa = ac.getAccessibleAction();
                if (aa == null)
                    return 0;
                return aa.getAccessibleActionCount();
            }
        }, ac);
    }

    /*
     * return icon description at the specified index
     */
    private String getAccessibleActionName(final AccessibleContext ac, final int index) {
        debugString("getAccessibleActionName: index = "+index);
        if (ac == null) {
            return null;
        }
        return InvocationUtils.invokeAndWait(new Callable<String>() {
            @Override
            public String call() throws Exception {
                AccessibleAction aa = ac.getAccessibleAction();
                if (aa == null) {
                    return null;
                }
                return aa.getAccessibleActionDescription(index);
            }
        }, ac);
    }
    /*
     * return icon description at the specified index
     */
    private boolean doAccessibleActions(final AccessibleContext ac, final String name) {
        debugString("doAccessibleActions: action name = "+name);
        if (ac == null || name == null) {
            return false;
        }
        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                AccessibleAction aa = ac.getAccessibleAction();
                if (aa == null) {
                    return false;
                }
                int index = -1;
                int numActions = aa.getAccessibleActionCount();
                for (int i = 0; i < numActions; i++) {
                    String actionName = aa.getAccessibleActionDescription(i);
                    if (name.equals(actionName)) {
                        index = i;
                        break;
                    }
                }
                if (index == -1) {
                    return false;
                }
                boolean retval = aa.doAccessibleAction(index);
                return retval;
            }
        }, ac);
    }

    /* ===== AT utility methods ===== */

    /**
     * Sets the contents of an AccessibleContext that
     * implements AccessibleEditableText with the
     * specified text string.
     * Returns whether successful.
     */
    private boolean setTextContents(final AccessibleContext ac, final String text) {
        debugString("setTextContents: ac = "+ac+"; text = "+text);

        if (! (ac instanceof AccessibleEditableText)) {
            debugString("   ac not instanceof AccessibleEditableText: "+ac);
            return false;
        }
        if (text == null) {
            debugString("   text is null");
            return false;
        }

        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                // check whether the text field is editable
                AccessibleStateSet ass = ac.getAccessibleStateSet();
                if (!ass.contains(AccessibleState.ENABLED)) {
                    return false;
                }
                ((AccessibleEditableText) ac).setTextContents(text);
                return true;
            }
        }, ac);
    }

    /**
     * Returns the Accessible Context of an Internal Frame object that is
     * the ancestor of a given object.  If the object is an Internal Frame
     * object or an Internal Frame ancestor object was found, returns the
     * object's AccessibleContext.
     * If there is no ancestor object that has an Accessible Role of
     * Internal Frame, returns (AccessibleContext)0.
     */
    private AccessibleContext getInternalFrame (AccessibleContext ac) {
        return getParentWithRole(ac, AccessibleRole.INTERNAL_FRAME.toString());
    }

    /**
     * Returns the Accessible Context for the top level object in
     * a Java Window.  This is same Accessible Context that is obtained
     * from GetAccessibleContextFromHWND for that window.  Returns
     * (AccessibleContext)0 on error.
     */
    private AccessibleContext getTopLevelObject (final AccessibleContext ac) {
        debugString("getTopLevelObject; ac = "+ac);
        if (ac == null) {
            return null;
        }
        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                if (ac.getAccessibleRole() == AccessibleRole.DIALOG) {
                    // return the dialog, not the parent window
                    return ac;
                }

                Accessible parent = ac.getAccessibleParent();
                if (parent == null) {
                    return ac;
                }
                Accessible tmp = parent;
                while (tmp != null && tmp.getAccessibleContext() != null) {
                    AccessibleContext ac2 = tmp.getAccessibleContext();
                    if (ac2 != null && ac2.getAccessibleRole() == AccessibleRole.DIALOG) {
                        // return the dialog, not the parent window
                        return ac2;
                    }
                    parent = tmp;
                    tmp = parent.getAccessibleContext().getAccessibleParent();
                }
                return parent.getAccessibleContext();
            }
        }, ac);
    }

    /**
     * Returns the parent AccessibleContext that has the specified AccessibleRole.
     * Returns null on error or if the AccessibleContext does not exist.
     */
    private AccessibleContext getParentWithRole (final AccessibleContext ac,
                                                 final String roleName) {
        debugString("getParentWithRole; ac = "+ac);
        debugString("role = "+roleName);
        if (ac == null || roleName == null) {
            return null;
        }

        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                AccessibleRole role = AccessBridge.this.accessibleRoleMap.get(roleName);
                if (role == null) {
                    return ac;
                }

                Accessible parent = ac.getAccessibleParent();
                if (parent == null && ac.getAccessibleRole() == role) {
                    return ac;
                }

                Accessible tmp = parent;
                AccessibleContext tmp_ac = null;

                while (tmp != null && (tmp_ac = tmp.getAccessibleContext()) != null) {
                    AccessibleRole ar = tmp_ac.getAccessibleRole();
                    if (ar == role) {
                        // found
                        return tmp_ac;
                    }
                    parent = tmp;
                    tmp = parent.getAccessibleContext().getAccessibleParent();
                }
                // not found
                return null;
            }
        }, ac);
    }

    /**
     * Returns the parent AccessibleContext that has the specified AccessibleRole.
     * Otherwise, returns the top level object for the Java Window.
     * Returns (AccessibleContext)0 on error.
     */
    private AccessibleContext getParentWithRoleElseRoot (AccessibleContext ac,
                                                         String roleName) {
        AccessibleContext retval = getParentWithRole(ac, roleName);
        if (retval == null) {
            retval = getTopLevelObject(ac);
        }
        return retval;
    }

    /**
     * Returns how deep in the object hierarchy a given object is.
     * The top most object in the object hierarchy has an object depth of 0.
     * Returns -1 on error.
     */
    private int getObjectDepth(final AccessibleContext ac) {
        debugString("getObjectDepth: ac = "+ac);

        if (ac == null) {
            return -1;
        }
        return InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int count = 0;
                Accessible parent = ac.getAccessibleParent();
                if (parent == null) {
                    return count;
                }
                Accessible tmp = parent;
                while (tmp != null && tmp.getAccessibleContext() != null) {
                    parent = tmp;
                    tmp = parent.getAccessibleContext().getAccessibleParent();
                    count++;
                }
                return count;
            }
        }, ac);
    }

    /**
     * Returns the Accessible Context of the current ActiveDescendent of an object.
     * Returns (AccessibleContext)0 on error.
     */
    private AccessibleContext getActiveDescendent (final AccessibleContext ac) {
        debugString("getActiveDescendent: ac = "+ac);
        if (ac == null) {
            return null;
        }
        // workaround for JTree bug where the only possible active
        // descendent is the JTree root
        final Accessible parent = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
            @Override
            public Accessible call() throws Exception {
                return ac.getAccessibleParent();
            }
        }, ac);

        if (parent != null) {
            Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                @Override
                public Accessible call() throws Exception {
                    int indexInParent = ac.getAccessibleIndexInParent();
                    return parent.getAccessibleContext().getAccessibleChild(indexInParent);
                }
            }, ac);

            if (child instanceof JTree) {
                // return the selected node
                final JTree tree = (JTree)child;
                return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                    @Override
                    public AccessibleContext call() throws Exception {
                        return new AccessibleJTreeNode(tree,
                                tree.getSelectionPath(),
                                null);
                    }
                }, child);
            }
        }

        return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
            @Override
            public AccessibleContext call() throws Exception {
                AccessibleSelection as = ac.getAccessibleSelection();
                if (as == null) {
                    return null;
                }
                // assume single selection
                if (as.getAccessibleSelectionCount() != 1) {
                    return null;
                }
                Accessible a = as.getAccessibleSelection(0);
                if (a == null) {
                    return null;
                }
                return a.getAccessibleContext();
            }
        }, ac);
    }


    /**
     * Additional methods for Teton
     */

    /**
     * Gets the AccessibleName for a component based upon the JAWS algorithm.
     * Returns whether successful.
     *
     * Bug ID 4916682 - Implement JAWS AccessibleName policy
     */
    private String getJAWSAccessibleName(final AccessibleContext ac) {
        debugString("getJAWSAccessibleName");
        if (ac == null) {
            return null;
        }
        // placeholder
        return InvocationUtils.invokeAndWait(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return ac.getAccessibleName();
            }
        }, ac);
    }

    /**
     * Request focus for a component. Returns whether successful;
     *
     * Bug ID 4944757 - requestFocus method needed
     */
    private boolean requestFocus(final AccessibleContext ac) {
        debugString("requestFocus");
        if (ac == null) {
            return false;
        }
        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                AccessibleComponent acomp = ac.getAccessibleComponent();
                if (acomp == null) {
                    return false;
                }
                acomp.requestFocus();
                return ac.getAccessibleStateSet().contains(AccessibleState.FOCUSED);
            }
        }, ac);
    }

    /**
     * Selects text between two indices.  Selection includes the
     * text at the start index and the text at the end index. Returns
     * whether successful;
     *
     * Bug ID 4944758 - selectTextRange method needed
     */
    private boolean selectTextRange(final AccessibleContext ac, final int startIndex, final int endIndex) {
        debugString("selectTextRange: start = "+startIndex+"; end = "+endIndex);
        if (ac == null) {
            return false;
        }
        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (!(at instanceof AccessibleEditableText)) {
                    return false;
                }
                ((AccessibleEditableText) at).selectText(startIndex, endIndex);

                boolean result = at.getSelectionStart() == startIndex &&
                        at.getSelectionEnd() == endIndex;
                return result;
            }
        }, ac);
    }

    /**
     * Set the caret to a text position. Returns whether successful;
     *
     * Bug ID 4944770 - setCaretPosition method needed
     */
    private boolean setCaretPosition(final AccessibleContext ac, final int position) {
        debugString("setCaretPosition: position = "+position);
        if (ac == null) {
            return false;
        }
        return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                AccessibleText at = ac.getAccessibleText();
                if (!(at instanceof AccessibleEditableText)) {
                    return false;
                }
                ((AccessibleEditableText) at).selectText(position, position);
                return at.getCaretPosition() == position;
            }
        }, ac);
    }

    /**
     * Gets the number of visible children of an AccessibleContext.
     *
     * Bug ID 4944762- getVisibleChildren for list-like components needed
     */
    private int _visibleChildrenCount;
    private AccessibleContext _visibleChild;
    private int _currentVisibleIndex;
    private boolean _foundVisibleChild;

    private int getVisibleChildrenCount(AccessibleContext ac) {
        debugString("getVisibleChildrenCount");
        if (ac == null) {
            return -1;
        }
        _visibleChildrenCount = 0;
        _getVisibleChildrenCount(ac);
        debugString("  _visibleChildrenCount = "+_visibleChildrenCount);
        return _visibleChildrenCount;
    }

    /*
     * Recursively descends AccessibleContext and gets the number
     * of visible children
     */
    private void _getVisibleChildrenCount(final AccessibleContext ac) {
        if (ac == null)
            return;
        int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return ac.getAccessibleChildrenCount();
            }
        }, ac);
        for (int i = 0; i < numChildren; i++) {
            final int idx = i;
            final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                @Override
                public AccessibleContext call() throws Exception {
                    Accessible a = ac.getAccessibleChild(idx);
                    if (a != null)
                        return a.getAccessibleContext();
                    else
                        return null;
                }
            }, ac);
            if ( ac2 == null ||
                 (!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
                     @Override
                     public Boolean call() throws Exception {
                         return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
                     }
                 }, ac))
               ) {
                continue;
            }
            _visibleChildrenCount++;

            if (InvocationUtils.invokeAndWait(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return ac2.getAccessibleChildrenCount();
                }
            }, ac) > 0 ) {
                _getVisibleChildrenCount(ac2);
            }
        }
    }

    /**
     * Gets the visible child of an AccessibleContext at the
     * specified index
     *
     * Bug ID 4944762- getVisibleChildren for list-like components needed
     */
    private AccessibleContext getVisibleChild(AccessibleContext ac, int index) {
        debugString("getVisibleChild: index = "+index);
        if (ac == null) {
            return null;
        }
        _visibleChild = null;
        _currentVisibleIndex = 0;
        _foundVisibleChild = false;
        _getVisibleChild(ac, index);

        if (_visibleChild != null) {
            debugString( "    getVisibleChild: found child = " +
                         InvocationUtils.invokeAndWait(new Callable<String>() {
                             @Override
                             public String call() throws Exception {
                                 return AccessBridge.this._visibleChild.getAccessibleName();
                             }
                         }, ac) );
        }
        return _visibleChild;
    }

    /*
     * Recursively searchs AccessibleContext and finds the visible component
     * at the specified index
     */
    private void _getVisibleChild(final AccessibleContext ac, final int index) {
        if (_visibleChild != null) {
            return;
        }

        int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return ac.getAccessibleChildrenCount();
            }
        }, ac);
        for (int i = 0; i < numChildren; i++) {
            final int idx=i;
            final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                @Override
                public AccessibleContext call() throws Exception {
                    Accessible a = ac.getAccessibleChild(idx);
                    if (a == null)
                        return null;
                    else
                        return a.getAccessibleContext();
                }
            }, ac);
            if (ac2 == null ||
            (!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
                @Override
                public Boolean call() throws Exception {
                    return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
                }
            }, ac))) {
                continue;
            }
            if (!_foundVisibleChild && _currentVisibleIndex == index) {
            _visibleChild = ac2;
            _foundVisibleChild = true;
            return;
            }
            _currentVisibleIndex++;

            if ( InvocationUtils.invokeAndWait(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return ac2.getAccessibleChildrenCount();
                }
            }, ac) > 0 ) {
                _getVisibleChild(ac2, index);
            }
        }
    }


    /* ===== Java object memory management code ===== */

    /**
     * Class to track object references to ensure the
     * Java VM doesn't garbage collect them
     */
    private class ObjectReferences {

        private class Reference {
            private int value;

            Reference(int i) {
                value = i;
            }

            public String toString() {
                return ("refCount: " + value);
            }
        }

        /**
        * table object references, to keep 'em from being garbage collected
        */
        private ConcurrentHashMap<Object,Reference> refs;

        /**
        * Constructor
        */
        ObjectReferences() {
            refs = new ConcurrentHashMap<>(4);
        }

        /**
        * Debugging: dump the contents of ObjectReferences' refs Hashtable
        */
        String dump() {
            return refs.toString();
        }

        /**
        * Increment ref count; set to 1 if we have no references for it
        */
        void increment(Object o) {
            if (o == null){
                debugString("ObjectReferences::increment - Passed in object is null");
                return;
            }

            if (refs.containsKey(o)) {
                (refs.get(o)).value++;
            } else {
                refs.put(o, new Reference(1));
            }
        }

        /**
        * Decrement ref count; remove if count drops to 0
        */
        void decrement(Object o) {
            Reference aRef = refs.get(o);
            if (aRef != null) {
                aRef.value--;
                if (aRef.value == 0) {
                    refs.remove(o);
                } else if (aRef.value < 0) {
                    debugString("ERROR: decrementing reference count below 0");
                }
            } else {
                debugString("ERROR: object to decrement not in ObjectReferences table");
            }
        }

    }

    /* ===== event handling code ===== */

   /**
     * native method for handling property change events
     */
    private native void propertyCaretChange(PropertyChangeEvent e,
                        AccessibleContext src,
                        int oldValue, int newValue);
    private native void propertyDescriptionChange(PropertyChangeEvent e,
                        AccessibleContext src,
                        String oldValue, String newValue);
    private native void propertyNameChange(PropertyChangeEvent e,
                        AccessibleContext src,
                        String oldValue, String newValue);
    private native void propertySelectionChange(PropertyChangeEvent e,
                        AccessibleContext src);
    private native void propertyStateChange(PropertyChangeEvent e,
                        AccessibleContext src,
                        String oldValue, String newValue);
    private native void propertyTextChange(PropertyChangeEvent e,
                        AccessibleContext src);
    private native void propertyValueChange(PropertyChangeEvent e,
                        AccessibleContext src,
                        String oldValue, String newValue);
    private native void propertyVisibleDataChange(PropertyChangeEvent e,
                        AccessibleContext src);
    private native void propertyChildChange(PropertyChangeEvent e,
                        AccessibleContext src,
                        AccessibleContext oldValue,
                        AccessibleContext newValue);
    private native void propertyActiveDescendentChange(PropertyChangeEvent e,
                        AccessibleContext src,
                        AccessibleContext oldValue,
                        AccessibleContext newValue);

    private native void javaShutdown();

    /**
     * native methods for handling focus events
     */
    private native void focusGained(FocusEvent e, AccessibleContext src);
    private native void focusLost(FocusEvent e, AccessibleContext src);

    /**
     * native method for handling caret events
     */
    private native void caretUpdate(CaretEvent e, AccessibleContext src);

    /**
     * native methods for handling mouse events
     */
    private native void mouseClicked(MouseEvent e, AccessibleContext src);
    private native void mouseEntered(MouseEvent e, AccessibleContext src);
    private native void mouseExited(MouseEvent e, AccessibleContext src);
    private native void mousePressed(MouseEvent e, AccessibleContext src);
    private native void mouseReleased(MouseEvent e, AccessibleContext src);

    /**
     * native methods for handling menu & popupMenu events
     */
    private native void menuCanceled(MenuEvent e, AccessibleContext src);
    private native void menuDeselected(MenuEvent e, AccessibleContext src);
    private native void menuSelected(MenuEvent e, AccessibleContext src);
    private native void popupMenuCanceled(PopupMenuEvent e, AccessibleContext src);
    private native void popupMenuWillBecomeInvisible(PopupMenuEvent e,
                                                     AccessibleContext src);
    private native void popupMenuWillBecomeVisible(PopupMenuEvent e,
                                                   AccessibleContext src);

    /* ===== event definitions ===== */

    private static final long PROPERTY_CHANGE_EVENTS = 1;
    private static final long FOCUS_GAINED_EVENTS = 2;
    private static final long FOCUS_LOST_EVENTS = 4;
    private static final long FOCUS_EVENTS = (FOCUS_GAINED_EVENTS | FOCUS_LOST_EVENTS);

    private static final long CARET_UPATE_EVENTS = 8;
    private static final long CARET_EVENTS = CARET_UPATE_EVENTS;

    private static final long MOUSE_CLICKED_EVENTS = 16;
    private static final long MOUSE_ENTERED_EVENTS = 32;
    private static final long MOUSE_EXITED_EVENTS = 64;
    private static final long MOUSE_PRESSED_EVENTS = 128;
    private static final long MOUSE_RELEASED_EVENTS = 256;
    private static final long MOUSE_EVENTS = (MOUSE_CLICKED_EVENTS | MOUSE_ENTERED_EVENTS |
                                             MOUSE_EXITED_EVENTS | MOUSE_PRESSED_EVENTS |
                                             MOUSE_RELEASED_EVENTS);

    private static final long MENU_CANCELED_EVENTS = 512;
    private static final long MENU_DESELECTED_EVENTS = 1024;
    private static final long MENU_SELECTED_EVENTS = 2048;
    private static final long MENU_EVENTS = (MENU_CANCELED_EVENTS | MENU_DESELECTED_EVENTS |
                                            MENU_SELECTED_EVENTS);

    private static final long POPUPMENU_CANCELED_EVENTS = 4096;
    private static final long POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS = 8192;
    private static final long POPUPMENU_WILL_BECOME_VISIBLE_EVENTS = 16384;
    private static final long POPUPMENU_EVENTS = (POPUPMENU_CANCELED_EVENTS |
                                                 POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS |
                                                 POPUPMENU_WILL_BECOME_VISIBLE_EVENTS);

    /* These use their own numbering scheme, to ensure sufficient expansion room */
    private static final long PROPERTY_NAME_CHANGE_EVENTS = 1;
    private static final long PROPERTY_DESCRIPTION_CHANGE_EVENTS = 2;
    private static final long PROPERTY_STATE_CHANGE_EVENTS = 4;
    private static final long PROPERTY_VALUE_CHANGE_EVENTS = 8;
    private static final long PROPERTY_SELECTION_CHANGE_EVENTS = 16;
    private static final long PROPERTY_TEXT_CHANGE_EVENTS = 32;
    private static final long PROPERTY_CARET_CHANGE_EVENTS = 64;
    private static final long PROPERTY_VISIBLEDATA_CHANGE_EVENTS = 128;
    private static final long PROPERTY_CHILD_CHANGE_EVENTS = 256;
    private static final long PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS = 512;


    private static final long PROPERTY_EVENTS = (PROPERTY_NAME_CHANGE_EVENTS |
                                                PROPERTY_DESCRIPTION_CHANGE_EVENTS |
                                                PROPERTY_STATE_CHANGE_EVENTS |
                                                PROPERTY_VALUE_CHANGE_EVENTS |
                                                PROPERTY_SELECTION_CHANGE_EVENTS |
                                                PROPERTY_TEXT_CHANGE_EVENTS |
                                                PROPERTY_CARET_CHANGE_EVENTS |
                                                PROPERTY_VISIBLEDATA_CHANGE_EVENTS |
                                                PROPERTY_CHILD_CHANGE_EVENTS |
                                                PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS);

    /**
     * The EventHandler class listens for Java events and
     * forwards them to the AT
     */
    private class EventHandler implements PropertyChangeListener,
                                          FocusListener, CaretListener,
                                          MenuListener, PopupMenuListener,
                                          MouseListener, WindowListener,
                                          ChangeListener {

        private AccessBridge accessBridge;
        private long javaEventMask = 0;
        private long accessibilityEventMask = 0;

        EventHandler(AccessBridge bridge) {
            accessBridge = bridge;

            // Register to receive WINDOW_OPENED and WINDOW_CLOSED
            // events.  Add the event source as a native window
            // handler is it implements NativeWindowHandler.
            // SwingEventMonitor.addWindowListener(this);
        }

        // --------- Event Notification Registration methods

        /**
         * Invoked the first time a window is made visible.
         */
        public void windowOpened(WindowEvent e) {
            // If the window is a NativeWindowHandler, add it.
            Object o = null;
            if (e != null)
                o = e.getSource();
            if (o instanceof NativeWindowHandler) {
                addNativeWindowHandler((NativeWindowHandler)o);
            }
        }

        /**
         * Invoked when the user attempts to close the window
         * from the window's system menu.  If the program does not
         * explicitly hide or dispose the window while processing
         * this event, the window close operation will be canceled.
         */
        public void windowClosing(WindowEvent e) {}

        /**
         * Invoked when a window has been closed as the result
         * of calling dispose on the window.
         */
        public void windowClosed(WindowEvent e) {
            // If the window is a NativeWindowHandler, remove it.
            Object o = null;
            if (e != null)
                o = e.getSource();
            if (o instanceof NativeWindowHandler) {
                removeNativeWindowHandler((NativeWindowHandler)o);
            }
        }

        /**
         * Invoked when a window is changed from a normal to a
         * minimized state. For many platforms, a minimized window
         * is displayed as the icon specified in the window's
         * iconImage property.
         * @see java.awt.Frame#setIconImage
         */
        public void windowIconified(WindowEvent e) {}

        /**
         * Invoked when a window is changed from a minimized
         * to a normal state.
         */
        public void windowDeiconified(WindowEvent e) {}

        /**
         * Invoked when the Window is set to be the active Window. Only a Frame or
         * a Dialog can be the active Window. The native windowing system may
         * denote the active Window or its children with special decorations, such
         * as a highlighted title bar. The active Window is always either the
         * focused Window, or the first Frame or Dialog that is an owner of the
         * focused Window.
         */
        public void windowActivated(WindowEvent e) {}

        /**
         * Invoked when a Window is no longer the active Window. Only a Frame or a
         * Dialog can be the active Window. The native windowing system may denote
         * the active Window or its children with special decorations, such as a
         * highlighted title bar. The active Window is always either the focused
         * Window, or the first Frame or Dialog that is an owner of the focused
         * Window.
         */
        public void windowDeactivated(WindowEvent e) {}

        /**
         * Turn on event monitoring for the event type passed in
         * If necessary, add the appropriate event listener (if
         * no other event of that type is being listened for)
         */
        void addJavaEventNotification(long type) {
            long newEventMask = javaEventMask | type;
            /*
            if ( ((javaEventMask & PROPERTY_EVENTS) == 0) &&
                 ((newEventMask & PROPERTY_EVENTS) != 0) ) {
                AccessibilityEventMonitor.addPropertyChangeListener(this);
            }
            */
            if ( ((javaEventMask & FOCUS_EVENTS) == 0) &&
                ((newEventMask & FOCUS_EVENTS) != 0) ) {
                SwingEventMonitor.addFocusListener(this);
            }
            if ( ((javaEventMask & CARET_EVENTS) == 0) &&
                ((newEventMask & CARET_EVENTS) != 0) ) {
                SwingEventMonitor.addCaretListener(this);
            }
            if ( ((javaEventMask & MOUSE_EVENTS) == 0) &&
                ((newEventMask & MOUSE_EVENTS) != 0) ) {
                SwingEventMonitor.addMouseListener(this);
            }
            if ( ((javaEventMask & MENU_EVENTS) == 0) &&
                ((newEventMask & MENU_EVENTS) != 0) ) {
                SwingEventMonitor.addMenuListener(this);
                SwingEventMonitor.addPopupMenuListener(this);
            }
            if ( ((javaEventMask & POPUPMENU_EVENTS) == 0) &&
                ((newEventMask & POPUPMENU_EVENTS) != 0) ) {
                SwingEventMonitor.addPopupMenuListener(this);
            }

            javaEventMask = newEventMask;
        }

        /**
         * Turn off event monitoring for the event type passed in
         * If necessary, remove the appropriate event listener (if
         * no other event of that type is being listened for)
         */
        void removeJavaEventNotification(long type) {
            long newEventMask = javaEventMask & (~type);
            /*
            if ( ((javaEventMask & PROPERTY_EVENTS) != 0) &&
                 ((newEventMask & PROPERTY_EVENTS) == 0) ) {
                AccessibilityEventMonitor.removePropertyChangeListener(this);
            }
            */
            if (((javaEventMask & FOCUS_EVENTS) != 0) &&
                ((newEventMask & FOCUS_EVENTS) == 0)) {
                SwingEventMonitor.removeFocusListener(this);
            }
            if (((javaEventMask & CARET_EVENTS) != 0) &&
                ((newEventMask & CARET_EVENTS) == 0)) {
                SwingEventMonitor.removeCaretListener(this);
            }
            if (((javaEventMask & MOUSE_EVENTS) == 0) &&
                ((newEventMask & MOUSE_EVENTS) != 0)) {
                SwingEventMonitor.removeMouseListener(this);
            }
            if (((javaEventMask & MENU_EVENTS) == 0) &&
                ((newEventMask & MENU_EVENTS) != 0)) {
                SwingEventMonitor.removeMenuListener(this);
            }
            if (((javaEventMask & POPUPMENU_EVENTS) == 0) &&
                ((newEventMask & POPUPMENU_EVENTS) != 0)) {
                SwingEventMonitor.removePopupMenuListener(this);
            }

            javaEventMask = newEventMask;
        }

        /**
         * Turn on event monitoring for the event type passed in
         * If necessary, add the appropriate event listener (if
         * no other event of that type is being listened for)
         */
        void addAccessibilityEventNotification(long type) {
            long newEventMask = accessibilityEventMask | type;
            if ( ((accessibilityEventMask & PROPERTY_EVENTS) == 0) &&
                 ((newEventMask & PROPERTY_EVENTS) != 0) ) {
                AccessibilityEventMonitor.addPropertyChangeListener(this);
            }
            accessibilityEventMask = newEventMask;
        }

        /**
         * Turn off event monitoring for the event type passed in
         * If necessary, remove the appropriate event listener (if
         * no other event of that type is being listened for)
         */
        void removeAccessibilityEventNotification(long type) {
            long newEventMask = accessibilityEventMask & (~type);
            if ( ((accessibilityEventMask & PROPERTY_EVENTS) != 0) &&
                 ((newEventMask & PROPERTY_EVENTS) == 0) ) {
                AccessibilityEventMonitor.removePropertyChangeListener(this);
            }
            accessibilityEventMask = newEventMask;
        }

        /**
         *  ------- property change event glue
         */
        // This is invoked on the EDT , as
        public void propertyChange(PropertyChangeEvent e) {

            accessBridge.debugString("propertyChange(" + e.toString() + ") called");

            if (e != null && (accessibilityEventMask & PROPERTY_EVENTS) != 0) {
                Object o = e.getSource();
                AccessibleContext ac;

                if (o instanceof AccessibleContext) {
                    ac = (AccessibleContext) o;
                } else {
                    Accessible a = Translator.getAccessible(e.getSource());
                    if (a == null)
                        return;
                    else
                        ac = a.getAccessibleContext();
                }
                if (ac != null) {
                    InvocationUtils.registerAccessibleContext(ac, AppContext.getAppContext());

                    accessBridge.debugString("AccessibleContext: " + ac);
                    String propertyName = e.getPropertyName();

                    if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) {
                        int oldValue = 0;
                        int newValue = 0;

                        if (e.getOldValue() instanceof Integer) {
                            oldValue = ((Integer) e.getOldValue()).intValue();
                        }
                        if (e.getNewValue() instanceof Integer) {
                            newValue = ((Integer) e.getNewValue()).intValue();
                        }
                        accessBridge.debugString(" - about to call propertyCaretChange()");
                        accessBridge.debugString("   old value: " + oldValue + "new value: " + newValue);
                        accessBridge.propertyCaretChange(e, ac, oldValue, newValue);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY) == 0) {
                        String oldValue = null;
                        String newValue = null;

                        if (e.getOldValue() != null) {
                            oldValue = e.getOldValue().toString();
                        }
                        if (e.getNewValue() != null) {
                            newValue = e.getNewValue().toString();
                        }
                        accessBridge.debugString(" - about to call propertyDescriptionChange()");
                        accessBridge.debugString("   old value: " + oldValue + "new value: " + newValue);
                        accessBridge.propertyDescriptionChange(e, ac, oldValue, newValue);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_NAME_PROPERTY) == 0) {
                        String oldValue = null;
                        String newValue = null;

                        if (e.getOldValue() != null) {
                            oldValue = e.getOldValue().toString();
                        }
                        if (e.getNewValue() != null) {
                            newValue = e.getNewValue().toString();
                        }
                        accessBridge.debugString(" - about to call propertyNameChange()");
                        accessBridge.debugString("   old value: " + oldValue + " new value: " + newValue);
                        accessBridge.propertyNameChange(e, ac, oldValue, newValue);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY) == 0) {
                        accessBridge.debugString(" - about to call propertySelectionChange() " + ac +  "   " + Thread.currentThread() + "   " + e.getSource());

                        accessBridge.propertySelectionChange(e, ac);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_STATE_PROPERTY) == 0) {
                        String oldValue = null;
                        String newValue = null;

                        // Localization fix requested by Oliver for EA-1
                        if (e.getOldValue() != null) {
                            AccessibleState oldState = (AccessibleState) e.getOldValue();
                            oldValue = oldState.toDisplayString(Locale.US);
                        }
                        if (e.getNewValue() != null) {
                            AccessibleState newState = (AccessibleState) e.getNewValue();
                            newValue = newState.toDisplayString(Locale.US);
                        }

                        accessBridge.debugString(" - about to call propertyStateChange()");
                        accessBridge.propertyStateChange(e, ac, oldValue, newValue);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0) {
                        accessBridge.debugString(" - about to call propertyTextChange()");
                        accessBridge.propertyTextChange(e, ac);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY) == 0) {  // strings 'cause of floating point, etc.
                        String oldValue = null;
                        String newValue = null;

                        if (e.getOldValue() != null) {
                            oldValue = e.getOldValue().toString();
                        }
                        if (e.getNewValue() != null) {
                            newValue = e.getNewValue().toString();
                        }
                        accessBridge.debugString(" - about to call propertyDescriptionChange()");
                        accessBridge.propertyValueChange(e, ac, oldValue, newValue);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY) == 0) {
                        accessBridge.propertyVisibleDataChange(e, ac);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) {
                        AccessibleContext oldAC = null;
                        AccessibleContext newAC = null;
                        Accessible a;

                        if (e.getOldValue() instanceof AccessibleContext) {
                            oldAC = (AccessibleContext) e.getOldValue();
                            InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext());
                        }
                        if (e.getNewValue() instanceof AccessibleContext) {
                            newAC = (AccessibleContext) e.getNewValue();
                            InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext());
                        }
                        accessBridge.debugString(" - about to call propertyChildChange()");
                        accessBridge.debugString("   old AC: " + oldAC + "new AC: " + newAC);
                        accessBridge.propertyChildChange(e, ac, oldAC, newAC);

                    } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0) {
                        handleActiveDescendentEvent(e, ac);
                    }
                }
            }
        }

        /*
        * Handle an ActiveDescendent PropertyChangeEvent.  This
        * method works around a JTree bug where ActiveDescendent
        * PropertyChangeEvents have the wrong parent.
        */
        private AccessibleContext prevAC = null; // previous AccessibleContext

        private void handleActiveDescendentEvent(PropertyChangeEvent e,
                                                 AccessibleContext ac) {
            if (e == null || ac == null)
                return;
            AccessibleContext oldAC = null;
            AccessibleContext newAC = null;
            Accessible a;

            // get the old active descendent
            if (e.getOldValue() instanceof Accessible) {
                oldAC = ((Accessible) e.getOldValue()).getAccessibleContext();
            } else if (e.getOldValue() instanceof Component) {
                a = Translator.getAccessible(e.getOldValue());
                if (a != null) {
                    oldAC = a.getAccessibleContext();
                }
            }
            if (oldAC != null) {
                Accessible parent = oldAC.getAccessibleParent();
                if (parent instanceof JTree) {
                    // use the previous AccessibleJTreeNode
                    oldAC = prevAC;
                }
            }

            // get the new active descendent
            if (e.getNewValue() instanceof Accessible) {
                newAC = ((Accessible) e.getNewValue()).getAccessibleContext();
            } else if (e.getNewValue() instanceof Component) {
                a = Translator.getAccessible(e.getNewValue());
                if (a != null) {
                    newAC = a.getAccessibleContext();
                }
            }
            if (newAC != null) {
                Accessible parent = newAC.getAccessibleParent();
                if (parent instanceof JTree) {
                    // use a new AccessibleJTreeNode with the right parent
                    JTree tree = (JTree)parent;
                    newAC = new AccessibleJTreeNode(tree,
                                                    tree.getSelectionPath(),
                                                    null);
                }
            }
            prevAC = newAC;

            accessBridge.debugString("  - about to call propertyActiveDescendentChange()");
            accessBridge.debugString("   AC: " + ac);
            accessBridge.debugString("   old AC: " + oldAC + "new AC: " + newAC);

            InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext());
            InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext());
            accessBridge.propertyActiveDescendentChange(e, ac, oldAC, newAC);
        }

        /**
        *  ------- focus event glue
        */
        private boolean stateChangeListenerAdded = false;

        public void focusGained(FocusEvent e) {
            processFocusGained();
        }

        public void stateChanged(ChangeEvent e) {
            processFocusGained();
        }

        private void processFocusGained() {
            Component focusOwner = KeyboardFocusManager.
            getCurrentKeyboardFocusManager().getFocusOwner();
            if (focusOwner == null) {
                return;
            }

            // Only menus and popup selections are handled by the JRootPane.
            if (focusOwner instanceof JRootPane) {
                MenuElement [] path =
                MenuSelectionManager.defaultManager().getSelectedPath();
                if (path.length > 1) {
                    Component penult = path[path.length-2].getComponent();
                    Component last = path[path.length-1].getComponent();

                    if (last instanceof JPopupMenu) {
                        // This is a popup with nothing in the popup
                        // selected. The menu itself is selected.
                        FocusEvent e = new FocusEvent(penult, FocusEvent.FOCUS_GAINED);
                        AccessibleContext context = penult.getAccessibleContext();
                        InvocationUtils.registerAccessibleContext(context, SunToolkit.targetToAppContext(penult));
                        accessBridge.focusGained(e, context);
                    } else if (penult instanceof JPopupMenu) {
                        // This is a popup with an item selected
                        FocusEvent e =
                        new FocusEvent(last, FocusEvent.FOCUS_GAINED);
                        accessBridge.debugString(" - about to call focusGained()");
                        AccessibleContext focusedAC = last.getAccessibleContext();
                        InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(last));
                        accessBridge.debugString("   AC: " + focusedAC);
                        accessBridge.focusGained(e, focusedAC);
                    }
                }
            } else {
                // The focus owner has the selection.
                if (focusOwner instanceof Accessible) {
                    FocusEvent e = new FocusEvent(focusOwner,
                                                  FocusEvent.FOCUS_GAINED);
                    accessBridge.debugString(" - about to call focusGained()");
                    AccessibleContext focusedAC = focusOwner.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(focusOwner));
                    accessBridge.debugString("   AC: " + focusedAC);
                    accessBridge.focusGained(e, focusedAC);
                }
            }
        }

        public void focusLost(FocusEvent e) {
            if (e != null && (javaEventMask & FOCUS_LOST_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    accessBridge.debugString(" - about to call focusLost()");
                    accessBridge.debugString("   AC: " + a.getAccessibleContext());
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.focusLost(e, context);
                }
            }
        }

        /**
         *  ------- caret event glue
         */
        public void caretUpdate(CaretEvent e) {
            if (e != null && (javaEventMask & CARET_UPATE_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.caretUpdate(e, context);
                }
            }
        }

    /**
     *  ------- mouse event glue
     */

        public void mouseClicked(MouseEvent e) {
            if (e != null && (javaEventMask & MOUSE_CLICKED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.mouseClicked(e, context);
                }
            }
        }

        public void mouseEntered(MouseEvent e) {
            if (e != null && (javaEventMask & MOUSE_ENTERED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.mouseEntered(e, context);
                }
            }
        }

        public void mouseExited(MouseEvent e) {
            if (e != null && (javaEventMask & MOUSE_EXITED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.mouseExited(e, context);
                }
            }
        }

        public void mousePressed(MouseEvent e) {
            if (e != null && (javaEventMask & MOUSE_PRESSED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.mousePressed(e, context);
                }
            }
        }

        public void mouseReleased(MouseEvent e) {
            if (e != null && (javaEventMask & MOUSE_RELEASED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.mouseReleased(e, context);
                }
            }
        }

        /**
         *  ------- menu event glue
         */
        public void menuCanceled(MenuEvent e) {
            if (e != null && (javaEventMask & MENU_CANCELED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.menuCanceled(e, context);
                }
            }
        }

        public void menuDeselected(MenuEvent e) {
            if (e != null && (javaEventMask & MENU_DESELECTED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.menuDeselected(e, context);
                }
            }
        }

        public void menuSelected(MenuEvent e) {
            if (e != null && (javaEventMask & MENU_SELECTED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.menuSelected(e, context);
                }
            }
        }

        public void popupMenuCanceled(PopupMenuEvent e) {
            if (e != null && (javaEventMask & POPUPMENU_CANCELED_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.popupMenuCanceled(e, context);
                }
            }
        }

        public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.popupMenuWillBecomeInvisible(e, context);
                }
            }
        }

        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_VISIBLE_EVENTS) != 0) {
                Accessible a = Translator.getAccessible(e.getSource());
                if (a != null) {
                    AccessibleContext context = a.getAccessibleContext();
                    InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
                    accessBridge.popupMenuWillBecomeVisible(e, context);
                }
            }
        }

    } // End of EventHandler Class

    // --------- Event Notification Registration methods

    /**
     *  Wrapper method around eventHandler.addJavaEventNotification()
     */
    private void addJavaEventNotification(final long type) {
        EventQueue.invokeLater(new Runnable() {
            public void run(){
                eventHandler.addJavaEventNotification(type);
            }
        });
    }

    /**
     *  Wrapper method around eventHandler.removeJavaEventNotification()
     */
    private void removeJavaEventNotification(final long type) {
        EventQueue.invokeLater(new Runnable() {
            public void run(){
                eventHandler.removeJavaEventNotification(type);
            }
        });
    }


    /**
     *  Wrapper method around eventHandler.addAccessibilityEventNotification()
     */
    private void addAccessibilityEventNotification(final long type) {
        EventQueue.invokeLater(new Runnable() {
            public void run(){
                eventHandler.addAccessibilityEventNotification(type);
            }
        });
    }

    /**
     *  Wrapper method around eventHandler.removeAccessibilityEventNotification()
     */
    private void removeAccessibilityEventNotification(final long type) {
        EventQueue.invokeLater(new Runnable() {
            public void run(){
                eventHandler.removeAccessibilityEventNotification(type);
            }
        });
    }

    /**
     ******************************************************
     * All AccessibleRoles
     *
     * We shouldn't have to do this since it requires us
     * to synchronize the allAccessibleRoles array when
     * the AccessibleRoles class interface changes. However,
     * there is no Accessibility API method to get all
     * AccessibleRoles
     ******************************************************
     */
    private AccessibleRole [] allAccessibleRoles = {
    /**
     * Object is used to alert the user about something.
     */
    AccessibleRole.ALERT,

    /**
     * The header for a column of data.
     */
    AccessibleRole.COLUMN_HEADER,

    /**
     * Object that can be drawn into and is used to trap
     * events.
     * @see #FRAME
     * @see #GLASS_PANE
     * @see #LAYERED_PANE
     */
    AccessibleRole.CANVAS,

    /**
     * A list of choices the user can select from.  Also optionally
     * allows the user to enter a choice of their own.
     */
    AccessibleRole.COMBO_BOX,

    /**
     * An iconified internal frame in a DESKTOP_PANE.
     * @see #DESKTOP_PANE
     * @see #INTERNAL_FRAME
     */
    AccessibleRole.DESKTOP_ICON,

    /**
     * A frame-like object that is clipped by a desktop pane.  The
     * desktop pane, internal frame, and desktop icon objects are
     * often used to create multiple document interfaces within an
     * application.
     * @see #DESKTOP_ICON
     * @see #DESKTOP_PANE
     * @see #FRAME
     */
    AccessibleRole.INTERNAL_FRAME,

    /**
     * A pane that supports internal frames and
     * iconified versions of those internal frames.
     * @see #DESKTOP_ICON
     * @see #INTERNAL_FRAME
     */
    AccessibleRole.DESKTOP_PANE,

    /**
     * A specialized pane whose primary use is inside a DIALOG
     * @see #DIALOG
     */
    AccessibleRole.OPTION_PANE,

    /**
     * A top level window with no title or border.
     * @see #FRAME
     * @see #DIALOG
     */
    AccessibleRole.WINDOW,

    /**
     * A top level window with a title bar, border, menu bar, etc.  It is
     * often used as the primary window for an application.
     * @see #DIALOG
     * @see #CANVAS
     * @see #WINDOW
     */
    AccessibleRole.FRAME,

    /**
     * A top level window with title bar and a border.  A dialog is similar
     * to a frame, but it has fewer properties and is often used as a
     * secondary window for an application.
     * @see #FRAME
     * @see #WINDOW
     */
    AccessibleRole.DIALOG,

    /**
     * A specialized dialog that lets the user choose a color.
     */
    AccessibleRole.COLOR_CHOOSER,


    /**
     * A pane that allows the user to navigate through
     * and select the contents of a directory.  May be used
     * by a file chooser.
     * @see #FILE_CHOOSER
     */
    AccessibleRole.DIRECTORY_PANE,

    /**
     * A specialized dialog that displays the files in the directory
     * and lets the user select a file, browse a different directory,
     * or specify a filename.  May use the directory pane to show the
     * contents of a directory.
     * @see #DIRECTORY_PANE
     */
    AccessibleRole.FILE_CHOOSER,

    /**
     * An object that fills up space in a user interface.  It is often
     * used in interfaces to tweak the spacing between components,
     * but serves no other purpose.
     */
    AccessibleRole.FILLER,

    /**
     * A hypertext anchor
     */
    // AccessibleRole.HYPERLINK,

    /**
     * A small fixed size picture, typically used to decorate components.
     */
    AccessibleRole.ICON,

    /**
     * An object used to present an icon or short string in an interface.
     */
    AccessibleRole.LABEL,

    /**
     * A specialized pane that has a glass pane and a layered pane as its
     * children.
     * @see #GLASS_PANE
     * @see #LAYERED_PANE
     */
    AccessibleRole.ROOT_PANE,

    /**
     * A pane that is guaranteed to be painted on top
     * of all panes beneath it.
     * @see #ROOT_PANE
     * @see #CANVAS
     */
    AccessibleRole.GLASS_PANE,

    /**
     * A specialized pane that allows its children to be drawn in layers,
     * providing a form of stacking order.  This is usually the pane that
     * holds the menu bar as well as the pane that contains most of the
     * visual components in a window.
     * @see #GLASS_PANE
     * @see #ROOT_PANE
     */
    AccessibleRole.LAYERED_PANE,

    /**
     * An object that presents a list of objects to the user and allows the
     * user to select one or more of them.  A list is usually contained
     * within a scroll pane.
     * @see #SCROLL_PANE
     * @see #LIST_ITEM
     */
    AccessibleRole.LIST,

    /**
     * An object that presents an element in a list.  A list is usually
     * contained within a scroll pane.
     * @see #SCROLL_PANE
     * @see #LIST
     */
    AccessibleRole.LIST_ITEM,

    /**
     * An object usually drawn at the top of the primary dialog box of
     * an application that contains a list of menus the user can choose
     * from.  For example, a menu bar might contain menus for "File,"
     * "Edit," and "Help."
     * @see #MENU
     * @see #POPUP_MENU
     * @see #LAYERED_PANE
     */
    AccessibleRole.MENU_BAR,

    /**
     * A temporary window that is usually used to offer the user a
     * list of choices, and then hides when the user selects one of
     * those choices.
     * @see #MENU
     * @see #MENU_ITEM
     */
    AccessibleRole.POPUP_MENU,

    /**
     * An object usually found inside a menu bar that contains a list
     * of actions the user can choose from.  A menu can have any object
     * as its children, but most often they are menu items, other menus,
     * or rudimentary objects such as radio buttons, check boxes, or
     * separators.  For example, an application may have an "Edit" menu
     * that contains menu items for "Cut" and "Paste."
     * @see #MENU_BAR
     * @see #MENU_ITEM
     * @see #SEPARATOR
     * @see #RADIO_BUTTON
     * @see #CHECK_BOX
     * @see #POPUP_MENU
     */
    AccessibleRole.MENU,

    /**
     * An object usually contained in a menu that presents an action
     * the user can choose.  For example, the "Cut" menu item in an
     * "Edit" menu would be an action the user can select to cut the
     * selected area of text in a document.
     * @see #MENU_BAR
     * @see #SEPARATOR
     * @see #POPUP_MENU
     */
    AccessibleRole.MENU_ITEM,

    /**
     * An object usually contained in a menu to provide a visual
     * and logical separation of the contents in a menu.  For example,
     * the "File" menu of an application might contain menu items for
     * "Open," "Close," and "Exit," and will place a separator between
     * "Close" and "Exit" menu items.
     * @see #MENU
     * @see #MENU_ITEM
     */
    AccessibleRole.SEPARATOR,

    /**
     * An object that presents a series of panels (or page tabs), one at a
     * time, through some mechanism provided by the object.  The most common
     * mechanism is a list of tabs at the top of the panel.  The children of
     * a page tab list are all page tabs.
     * @see #PAGE_TAB
     */
    AccessibleRole.PAGE_TAB_LIST,

    /**
     * An object that is a child of a page tab list.  Its sole child is
     * the panel that is to be presented to the user when the user
     * selects the page tab from the list of tabs in the page tab list.
     * @see #PAGE_TAB_LIST
     */
    AccessibleRole.PAGE_TAB,

    /**
     * A generic container that is often used to group objects.
     */
    AccessibleRole.PANEL,

    /**
     * An object used to indicate how much of a task has been completed.
     */
    AccessibleRole.PROGRESS_BAR,

    /**
     * A text object used for passwords, or other places where the
     * text contents is not shown visibly to the user
     */
    AccessibleRole.PASSWORD_TEXT,

    /**
     * An object the user can manipulate to tell the application to do
     * something.
     * @see #CHECK_BOX
     * @see #TOGGLE_BUTTON
     * @see #RADIO_BUTTON
     */
    AccessibleRole.PUSH_BUTTON,

    /**
     * A specialized push button that can be checked or unchecked, but
     * does not provide a separate indicator for the current state.
     * @see #PUSH_BUTTON
     * @see #CHECK_BOX
     * @see #RADIO_BUTTON
     */
    AccessibleRole.TOGGLE_BUTTON,

    /**
     * A choice that can be checked or unchecked and provides a
     * separate indicator for the current state.
     * @see #PUSH_BUTTON
     * @see #TOGGLE_BUTTON
     * @see #RADIO_BUTTON
     */
    AccessibleRole.CHECK_BOX,

    /**
     * A specialized check box that will cause other radio buttons in the
     * same group to become unchecked when this one is checked.
     * @see #PUSH_BUTTON
     * @see #TOGGLE_BUTTON
     * @see #CHECK_BOX
     */
    AccessibleRole.RADIO_BUTTON,

    /**
     * The header for a row of data.
     */
    AccessibleRole.ROW_HEADER,

    /**
     * An object that allows a user to incrementally view a large amount
     * of information.  Its children can include scroll bars and a viewport.
     * @see #SCROLL_BAR
     * @see #VIEWPORT
     */
    AccessibleRole.SCROLL_PANE,

    /**
     * An object usually used to allow a user to incrementally view a
     * large amount of data.  Usually used only by a scroll pane.
     * @see #SCROLL_PANE
     */
    AccessibleRole.SCROLL_BAR,

    /**
     * An object usually used in a scroll pane.  It represents the portion
     * of the entire data that the user can see.  As the user manipulates
     * the scroll bars, the contents of the viewport can change.
     * @see #SCROLL_PANE
     */
    AccessibleRole.VIEWPORT,

    /**
     * An object that allows the user to select from a bounded range.  For
     * example, a slider might be used to select a number between 0 and 100.
     */
    AccessibleRole.SLIDER,

    /**
     * A specialized panel that presents two other panels at the same time.
     * Between the two panels is a divider the user can manipulate to make
     * one panel larger and the other panel smaller.
     */
    AccessibleRole.SPLIT_PANE,

    /**
     * An object used to present information in terms of rows and columns.
     * An example might include a spreadsheet application.
     */
    AccessibleRole.TABLE,

    /**
     * An object that presents text to the user.  The text is usually
     * editable by the user as opposed to a label.
     * @see #LABEL
     */
    AccessibleRole.TEXT,

    /**
     * An object used to present hierarchical information to the user.
     * The individual nodes in the tree can be collapsed and expanded
     * to provide selective disclosure of the tree's contents.
     */
    AccessibleRole.TREE,

    /**
     * A bar or palette usually composed of push buttons or toggle buttons.
     * It is often used to provide the most frequently used functions for an
     * application.
     */
    AccessibleRole.TOOL_BAR,

    /**
     * An object that provides information about another object.  The
     * accessibleDescription property of the tool tip is often displayed
     * to the user in a small "help bubble" when the user causes the
     * mouse to hover over the object associated with the tool tip.
     */
    AccessibleRole.TOOL_TIP,

    /**
     * An AWT component, but nothing else is known about it.
     * @see #SWING_COMPONENT
     * @see #UNKNOWN
     */
    AccessibleRole.AWT_COMPONENT,

    /**
     * A Swing component, but nothing else is known about it.
     * @see #AWT_COMPONENT
     * @see #UNKNOWN
     */
    AccessibleRole.SWING_COMPONENT,

    /**
     * The object contains some Accessible information, but its role is
     * not known.
     * @see #AWT_COMPONENT
     * @see #SWING_COMPONENT
     */
    AccessibleRole.UNKNOWN,

    // These roles are available since JDK 1.4

    /**
     * A STATUS_BAR is an simple component that can contain
     * multiple labels of status information to the user.
     AccessibleRole.STATUS_BAR,

     /**
     * A DATE_EDITOR is a component that allows users to edit
     * java.util.Date and java.util.Time objects
     AccessibleRole.DATE_EDITOR,

     /**
     * A SPIN_BOX is a simple spinner component and its main use
     * is for simple numbers.
     AccessibleRole.SPIN_BOX,

     /**
     * A FONT_CHOOSER is a component that lets the user pick various
     * attributes for fonts.
     AccessibleRole.FONT_CHOOSER,

     /**
     * A GROUP_BOX is a simple container that contains a border
     * around it and contains components inside it.
     AccessibleRole.GROUP_BOX

     /**
     * Since JDK 1.5
     *
     * A text header

     AccessibleRole.HEADER,

     /**
     * A text footer

     AccessibleRole.FOOTER,

     /**
     * A text paragraph

     AccessibleRole.PARAGRAPH,

     /**
     * A ruler is an object used to measure distance

     AccessibleRole.RULER,

     /**
     * A role indicating the object acts as a formula for
     * calculating a value.  An example is a formula in
     * a spreadsheet cell.
     AccessibleRole.EDITBAR
    */
    };

    /**
     * This class implements accessibility support for the
     * <code>JTree</code> child.  It provides an implementation of the
     * Java Accessibility API appropriate to tree nodes.
     *
     * Copied from JTree.java to work around a JTree bug where
     * ActiveDescendent PropertyChangeEvents contain the wrong
     * parent.
     */
    /**
     * This class in invoked on the EDT as its part of ActiveDescendant,
     * hence the calls do not need to be specifically made on the EDT
     */
    private class AccessibleJTreeNode extends AccessibleContext
        implements Accessible, AccessibleComponent, AccessibleSelection,
                   AccessibleAction {

        private JTree tree = null;
        private TreeModel treeModel = null;
        private Object obj = null;
        private TreePath path = null;
        private Accessible accessibleParent = null;
        private int index = 0;
        private boolean isLeaf = false;

        /**
         *  Constructs an AccessibleJTreeNode
         */
        AccessibleJTreeNode(JTree t, TreePath p, Accessible ap) {
            tree = t;
            path = p;
            accessibleParent = ap;
            if (t != null)
                treeModel = t.getModel();
            if (p != null) {
                obj = p.getLastPathComponent();
                if (treeModel != null && obj != null) {
                    isLeaf = treeModel.isLeaf(obj);
                }
            }
            debugString("AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap);
        }

        private TreePath getChildTreePath(int i) {
            // Tree nodes can't be so complex that they have
            // two sets of children -> we're ignoring that case
            if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) {
                return null;
            } else {
                Object childObj = treeModel.getChild(obj, i);
                Object[] objPath = path.getPath();
                Object[] objChildPath = new Object[objPath.length+1];
                java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length);
                objChildPath[objChildPath.length-1] = childObj;
                return new TreePath(objChildPath);
            }
        }

        /**
         * Get the AccessibleContext associated with this tree node.
         * In the implementation of the Java Accessibility API for
         * this class, return this object, which is its own
         * AccessibleContext.
         *
         * @return this object
        */
        public AccessibleContext getAccessibleContext() {
            return this;
        }

        private AccessibleContext getCurrentAccessibleContext() {
            Component c = getCurrentComponent();
            if (c instanceof Accessible) {
               return (c.getAccessibleContext());
            } else {
                return null;
            }
        }

        private Component getCurrentComponent() {
            debugString("AccessibleJTreeNode: getCurrentComponent");
            // is the object visible?
            // if so, get row, selected, focus & leaf state,
            // and then get the renderer component and return it
            if (tree != null && tree.isVisible(path)) {
                TreeCellRenderer r = tree.getCellRenderer();
                if (r == null) {
                    debugString("  returning null 1");
                    return null;
                }
                TreeUI ui = tree.getUI();
                if (ui != null) {
                    int row = ui.getRowForPath(tree, path);
                    boolean selected = tree.isPathSelected(path);
                    boolean expanded = tree.isExpanded(path);
                    boolean hasFocus = false; // how to tell?? -PK
                    Component retval = r.getTreeCellRendererComponent(tree, obj,
                                                                      selected, expanded,
                                                                      isLeaf, row, hasFocus);
                    debugString("  returning = "+retval.getClass());
                    return retval;
                }
            }
            debugString("  returning null 2");
            return null;
        }

        // AccessibleContext methods

        /**
         * Get the accessible name of this object.
         *
         * @return the localized name of the object; null if this
         * object does not have a name
         */
        public String getAccessibleName() {
            debugString("AccessibleJTreeNode: getAccessibleName");
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                String name = ac.getAccessibleName();
                if ((name != null) && (!name.isEmpty())) {
                    String retval = ac.getAccessibleName();
                    debugString("    returning "+retval);
                    return retval;
                } else {
                    return null;
                }
            }
            if ((accessibleName != null) && (accessibleName.isEmpty())) {
                return accessibleName;
            } else {
                return null;
            }
        }

        /**
         * Set the localized accessible name of this object.
         *
         * @param s the new localized name of the object.
         */
        public void setAccessibleName(String s) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                ac.setAccessibleName(s);
            } else {
                super.setAccessibleName(s);
            }
        }

        //
        // *** should check tooltip text for desc. (needs MouseEvent)
        //
        /**
         * Get the accessible description of this object.
         *
         * @return the localized description of the object; null if
         * this object does not have a description
         */
        public String getAccessibleDescription() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                return ac.getAccessibleDescription();
            } else {
                return super.getAccessibleDescription();
            }
        }

        /**
         * Set the accessible description of this object.
         *
         * @param s the new localized description of the object
         */
        public void setAccessibleDescription(String s) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                ac.setAccessibleDescription(s);
            } else {
                super.setAccessibleDescription(s);
            }
        }

        /**
         * Get the role of this object.
         *
         * @return an instance of AccessibleRole describing the role of the object
         * @see AccessibleRole
         */
        public AccessibleRole getAccessibleRole() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                return ac.getAccessibleRole();
            } else {
                return AccessibleRole.UNKNOWN;
            }
        }

        /**
         * Get the state set of this object.
         *
         * @return an instance of AccessibleStateSet containing the
         * current state set of the object
         * @see AccessibleState
         */
        public AccessibleStateSet getAccessibleStateSet() {
            if (tree == null)
                return null;
            AccessibleContext ac = getCurrentAccessibleContext();
            AccessibleStateSet states;
            int row = tree.getUI().getRowForPath(tree,path);
            int lsr = tree.getLeadSelectionRow();
            if (ac != null) {
                states = ac.getAccessibleStateSet();
            } else {
                states = new AccessibleStateSet();
            }
            // need to test here, 'cause the underlying component
            // is a cellRenderer, which is never showing...
            if (isShowing()) {
                states.add(AccessibleState.SHOWING);
            } else if (states.contains(AccessibleState.SHOWING)) {
                states.remove(AccessibleState.SHOWING);
            }
            if (isVisible()) {
                states.add(AccessibleState.VISIBLE);
            } else if (states.contains(AccessibleState.VISIBLE)) {
                states.remove(AccessibleState.VISIBLE);
            }
            if (tree.isPathSelected(path)){
                states.add(AccessibleState.SELECTED);
            }
            if (lsr == row) {
                states.add(AccessibleState.ACTIVE);
            }
            if (!isLeaf) {
                states.add(AccessibleState.EXPANDABLE);
            }
            if (tree.isExpanded(path)) {
                states.add(AccessibleState.EXPANDED);
            } else {
                states.add(AccessibleState.COLLAPSED);
            }
            if (tree.isEditable()) {
                states.add(AccessibleState.EDITABLE);
            }
            return states;
        }

        /**
         * Get the Accessible parent of this object.
         *
         * @return the Accessible parent of this object; null if this
         * object does not have an Accessible parent
         */
        public Accessible getAccessibleParent() {
            // someone wants to know, so we need to create our parent
            // if we don't have one (hey, we're a talented kid!)
            if (accessibleParent == null && path != null) {
                Object[] objPath = path.getPath();
                if (objPath.length > 1) {
                    Object objParent = objPath[objPath.length-2];
                    if (treeModel != null) {
                        index = treeModel.getIndexOfChild(objParent, obj);
                    }
                    Object[] objParentPath = new Object[objPath.length-1];
                    java.lang.System.arraycopy(objPath, 0, objParentPath,
                                               0, objPath.length-1);
                    TreePath parentPath = new TreePath(objParentPath);
                    accessibleParent = new AccessibleJTreeNode(tree,
                                                               parentPath,
                                                               null);
                    this.setAccessibleParent(accessibleParent);
                } else if (treeModel != null) {
                    accessibleParent = tree; // we're the top!
                    index = 0; // we're an only child!
                    this.setAccessibleParent(accessibleParent);
                }
            }
            return accessibleParent;
        }

        /**
         * Get the index of this object in its accessible parent.
         *
         * @return the index of this object in its parent; -1 if this
         * object does not have an accessible parent.
         * @see #getAccessibleParent
         */
        public int getAccessibleIndexInParent() {
            // index is invalid 'till we have an accessibleParent...
            if (accessibleParent == null) {
                getAccessibleParent();
            }
            if (path != null) {
                Object[] objPath = path.getPath();
                if (objPath.length > 1) {
                    Object objParent = objPath[objPath.length-2];
                    if (treeModel != null) {
                        index = treeModel.getIndexOfChild(objParent, obj);
                    }
                }
            }
            return index;
        }

        /**
         * Returns the number of accessible children in the object.
         *
         * @return the number of accessible children in the object.
         */
        public int getAccessibleChildrenCount() {
            // Tree nodes can't be so complex that they have
            // two sets of children -> we're ignoring that case
            if (obj != null && treeModel != null) {
                return treeModel.getChildCount(obj);
            }
            return 0;
        }

        /**
         * Return the specified Accessible child of the object.
         *
         * @param i zero-based index of child
         * @return the Accessible child of the object
         */
        public Accessible getAccessibleChild(int i) {
            // Tree nodes can't be so complex that they have
            // two sets of children -> we're ignoring that case
            if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) {
                return null;
            } else {
                Object childObj = treeModel.getChild(obj, i);
                Object[] objPath = path.getPath();
                Object[] objChildPath = new Object[objPath.length+1];
                java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length);
                objChildPath[objChildPath.length-1] = childObj;
                TreePath childPath = new TreePath(objChildPath);
                return new AccessibleJTreeNode(tree, childPath, this);
            }
        }

        /**
         * Gets the locale of the component. If the component does not have
         * a locale, then the locale of its parent is returned.
         *
         * @return This component's locale. If this component does not have
         * a locale, the locale of its parent is returned.
         * @exception IllegalComponentStateException
         * If the Component does not have its own locale and has not yet
         * been added to a containment hierarchy such that the locale can be
         * determined from the containing parent.
         * @see #setLocale
         */
        public Locale getLocale() {
            if (tree == null)
                return null;
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                return ac.getLocale();
            } else {
                return tree.getLocale();
            }
        }

        /**
         * Add a PropertyChangeListener to the listener list.
         * The listener is registered for all properties.
         *
         * @param l  The PropertyChangeListener to be added
         */
        public void addPropertyChangeListener(PropertyChangeListener l) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                ac.addPropertyChangeListener(l);
            } else {
                super.addPropertyChangeListener(l);
            }
        }

        /**
         * Remove a PropertyChangeListener from the listener list.
         * This removes a PropertyChangeListener that was registered
         * for all properties.
         *
         * @param l  The PropertyChangeListener to be removed
         */
        public void removePropertyChangeListener(PropertyChangeListener l) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                ac.removePropertyChangeListener(l);
            } else {
                super.removePropertyChangeListener(l);
            }
        }

        /**
         * Get the AccessibleAction associated with this object.  In the
         * implementation of the Java Accessibility API for this class,
         * return this object, which is responsible for implementing the
         * AccessibleAction interface on behalf of itself.
         *
         * @return this object
         */
        public AccessibleAction getAccessibleAction() {
            return this;
        }

        /**
         * Get the AccessibleComponent associated with this object.  In the
         * implementation of the Java Accessibility API for this class,
         * return this object, which is responsible for implementing the
         * AccessibleComponent interface on behalf of itself.
         *
         * @return this object
         */
        public AccessibleComponent getAccessibleComponent() {
            return this; // to override getBounds()
        }

        /**
         * Get the AccessibleSelection associated with this object if one
         * exists.  Otherwise return null.
         *
         * @return the AccessibleSelection, or null
         */
        public AccessibleSelection getAccessibleSelection() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null && isLeaf) {
                return getCurrentAccessibleContext().getAccessibleSelection();
            } else {
                return this;
            }
        }

        /**
         * Get the AccessibleText associated with this object if one
         * exists.  Otherwise return null.
         *
         * @return the AccessibleText, or null
         */
        public AccessibleText getAccessibleText() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                return getCurrentAccessibleContext().getAccessibleText();
            } else {
                return null;
            }
        }

        /**
         * Get the AccessibleValue associated with this object if one
         * exists.  Otherwise return null.
         *
         * @return the AccessibleValue, or null
         */
        public AccessibleValue getAccessibleValue() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                return getCurrentAccessibleContext().getAccessibleValue();
            } else {
                return null;
            }
        }


            // AccessibleComponent methods

        /**
         * Get the background color of this object.
         *
         * @return the background color, if supported, of the object;
         * otherwise, null
         */
        public Color getBackground() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                return ((AccessibleComponent) ac).getBackground();
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    return c.getBackground();
                } else {
                    return null;
                }
            }
        }

        /**
         * Set the background color of this object.
         *
         * @param c the new Color for the background
         */
        public void setBackground(Color c) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).setBackground(c);
            } else {
                Component cp = getCurrentComponent();
                if (    cp != null) {
                    cp.setBackground(c);
                }
            }
        }


        /**
         * Get the foreground color of this object.
         *
         * @return the foreground color, if supported, of the object;
         * otherwise, null
         */
        public Color getForeground() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                return ((AccessibleComponent) ac).getForeground();
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    return c.getForeground();
                } else {
                    return null;
                }
            }
        }

        public void setForeground(Color c) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).setForeground(c);
            } else {
                Component cp = getCurrentComponent();
                if (cp != null) {
                    cp.setForeground(c);
                }
            }
        }

        public Cursor getCursor() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                return ((AccessibleComponent) ac).getCursor();
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    return c.getCursor();
                } else {
                    Accessible ap = getAccessibleParent();
                    if (ap instanceof AccessibleComponent) {
                        return ((AccessibleComponent) ap).getCursor();
                    } else {
                        return null;
                    }
                }
            }
        }

        public void setCursor(Cursor c) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).setCursor(c);
            } else {
                Component cp = getCurrentComponent();
                if (cp != null) {
                    cp.setCursor(c);
                }
            }
        }

        public Font getFont() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                return ((AccessibleComponent) ac).getFont();
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    return c.getFont();
                } else {
                    return null;
                }
            }
        }

        public void setFont(Font f) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).setFont(f);
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    c.setFont(f);
                }
            }
        }

        public FontMetrics getFontMetrics(Font f) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                return ((AccessibleComponent) ac).getFontMetrics(f);
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    return c.getFontMetrics(f);
                } else {
                    return null;
                }
            }
        }

        public boolean isEnabled() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                return ((AccessibleComponent) ac).isEnabled();
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    return c.isEnabled();
                } else {
                    return false;
                }
            }
        }

        public void setEnabled(boolean b) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).setEnabled(b);
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    c.setEnabled(b);
                }
            }
        }

        public boolean isVisible() {
            if (tree == null)
                return false;
            Rectangle pathBounds = tree.getPathBounds(path);
            Rectangle parentBounds = tree.getVisibleRect();
            if ( pathBounds != null && parentBounds != null &&
                 parentBounds.intersects(pathBounds) ) {
                return true;
            } else {
                return false;
            }
        }

        public void setVisible(boolean b) {
        }

        public boolean isShowing() {
            return (tree.isShowing() && isVisible());
        }

        public boolean contains(Point p) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                Rectangle r = ((AccessibleComponent) ac).getBounds();
                return r.contains(p);
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    Rectangle r = c.getBounds();
                    return r.contains(p);
                } else {
                    return getBounds().contains(p);
                }
            }
        }

        public Point getLocationOnScreen() {
            if (tree != null) {
                Point treeLocation = tree.getLocationOnScreen();
                Rectangle pathBounds = tree.getPathBounds(path);
                if (treeLocation != null && pathBounds != null) {
                    Point nodeLocation = new Point(pathBounds.x,
                                                   pathBounds.y);
                    nodeLocation.translate(treeLocation.x, treeLocation.y);
                    return nodeLocation;
                } else {
                    return null;
                }
            } else {
                return null;
            }
        }

        private Point getLocationInJTree() {
            Rectangle r = tree.getPathBounds(path);
            if (r != null) {
                return r.getLocation();
            } else {
                return null;
            }
        }

        public Point getLocation() {
            Rectangle r = getBounds();
            if (r != null) {
                return r.getLocation();
            } else {
                return null;
            }
        }

        public void setLocation(Point p) {
        }

        public Rectangle getBounds() {
            if (tree == null)
                return null;
            Rectangle r = tree.getPathBounds(path);
            Accessible parent = getAccessibleParent();
            if (parent instanceof AccessibleJTreeNode) {
                Point parentLoc = ((AccessibleJTreeNode) parent).getLocationInJTree();
                if (parentLoc != null && r != null) {
                    r.translate(-parentLoc.x, -parentLoc.y);
                } else {
                    return null;        // not visible!
                }
            }
            return r;
        }

        public void setBounds(Rectangle r) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).setBounds(r);
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    c.setBounds(r);
                }
            }
        }

        public Dimension getSize() {
            return getBounds().getSize();
        }

        public void setSize (Dimension d) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).setSize(d);
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    c.setSize(d);
                }
            }
        }

        /**
        * Returns the <code>Accessible</code> child, if one exists,
        * contained at the local coordinate <code>Point</code>.
        * Otherwise returns <code>null</code>.
        *
        * @param p point in local coordinates of this
        *    <code>Accessible</code>
        * @return the <code>Accessible</code>, if it exists,
        *    at the specified location; else <code>null</code>
        */
        public Accessible getAccessibleAt(Point p) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                return ((AccessibleComponent) ac).getAccessibleAt(p);
            } else {
                return null;
            }
        }

        public boolean isFocusTraversable() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                return ((AccessibleComponent) ac).isFocusTraversable();
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    return c.isFocusable();
                } else {
                    return false;
                }
            }
        }

        public void requestFocus() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).requestFocus();
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    c.requestFocus();
                }
            }
        }

        public void addFocusListener(FocusListener l) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).addFocusListener(l);
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    c.addFocusListener(l);
                }
            }
        }

        public void removeFocusListener(FocusListener l) {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac instanceof AccessibleComponent) {
                ((AccessibleComponent) ac).removeFocusListener(l);
            } else {
                Component c = getCurrentComponent();
                if (c != null) {
                    c.removeFocusListener(l);
                }
            }
        }

            // AccessibleSelection methods

        /**
         * Returns the number of items currently selected.
         * If no items are selected, the return value will be 0.
         *
         * @return the number of items currently selected.
         */
        public int getAccessibleSelectionCount() {
            int count = 0;
            int childCount = getAccessibleChildrenCount();
            for (int i = 0; i < childCount; i++) {
                TreePath childPath = getChildTreePath(i);
                if (tree.isPathSelected(childPath)) {
                    count++;
                }
            }
            return count;
        }

        /**
         * Returns an Accessible representing the specified selected item
         * in the object.  If there isn't a selection, or there are
         * fewer items selected than the integer passed in, the return
         * value will be null.
         *
         * @param i the zero-based index of selected items
         * @return an Accessible containing the selected item
         */
        public Accessible getAccessibleSelection(int i) {
            int childCount = getAccessibleChildrenCount();
            if (i < 0 || i >= childCount) {
                return null;        // out of range
            }
            int count = 0;
            for (int j = 0; j < childCount && i >= count; j++) {
                TreePath childPath = getChildTreePath(j);
                if (tree.isPathSelected(childPath)) {
                    if (count == i) {
                        return new AccessibleJTreeNode(tree, childPath, this);
                    } else {
                        count++;
                    }
                }
            }
            return null;
        }

        /**
         * Returns true if the current child of this object is selected.
         *
         * @param i the zero-based index of the child in this Accessible
         * object.
         * @see AccessibleContext#getAccessibleChild
         */
        public boolean isAccessibleChildSelected(int i) {
            int childCount = getAccessibleChildrenCount();
            if (i < 0 || i >= childCount) {
                return false;       // out of range
            } else {
                TreePath childPath = getChildTreePath(i);
                return tree.isPathSelected(childPath);
            }
        }

         /**
         * Adds the specified selected item in the object to the object's
         * selection.  If the object supports multiple selections,
         * the specified item is added to any existing selection, otherwise
         * it replaces any existing selection in the object.  If the
         * specified item is already selected, this method has no effect.
         *
         * @param i the zero-based index of selectable items
         */
        public void addAccessibleSelection(int i) {
            if (tree == null)
                return;
            TreeModel model = tree.getModel();
            if (model != null) {
                if (i >= 0 && i < getAccessibleChildrenCount()) {
                    TreePath path = getChildTreePath(i);
                    tree.addSelectionPath(path);
                }
            }
        }

        /**
         * Removes the specified selected item in the object from the
         * object's
         * selection.  If the specified item isn't currently selected, this
         * method has no effect.
         *
         * @param i the zero-based index of selectable items
         */
        public void removeAccessibleSelection(int i) {
            if (tree == null)
                return;
            TreeModel model = tree.getModel();
            if (model != null) {
                if (i >= 0 && i < getAccessibleChildrenCount()) {
                    TreePath path = getChildTreePath(i);
                    tree.removeSelectionPath(path);
                }
            }
        }

        /**
         * Clears the selection in the object, so that nothing in the
         * object is selected.
         */
        public void clearAccessibleSelection() {
            int childCount = getAccessibleChildrenCount();
            for (int i = 0; i < childCount; i++) {
                removeAccessibleSelection(i);
            }
        }

        /**
         * Causes every selected item in the object to be selected
         * if the object supports multiple selections.
         */
        public void selectAllAccessibleSelection() {
            if (tree == null)
                return;
            TreeModel model = tree.getModel();
            if (model != null) {
                int childCount = getAccessibleChildrenCount();
                TreePath path;
                for (int i = 0; i < childCount; i++) {
                    path = getChildTreePath(i);
                    tree.addSelectionPath(path);
                }
            }
        }

            // AccessibleAction methods

        /**
         * Returns the number of accessible actions available in this
         * tree node.  If this node is not a leaf, there is at least
         * one action (toggle expand), in addition to any available
         * on the object behind the TreeCellRenderer.
         *
         * @return the number of Actions in this object
         */
        public int getAccessibleActionCount() {
            AccessibleContext ac = getCurrentAccessibleContext();
            if (ac != null) {
                AccessibleAction aa = ac.getAccessibleAction();
                if (aa != null) {
                    return (aa.getAccessibleActionCount() + (isLeaf ? 0 : 1));
                }
            }
            return isLeaf ? 0 : 1;
        }

        /**
         * Return a description of the specified action of the tree node.
         * If this node is not a leaf, there is at least one action
         * description (toggle expand), in addition to any available
         * on the object behind the TreeCellRenderer.
         *
         * @param i zero-based index of the actions
         * @return a description of the action
         */
        public String getAccessibleActionDescription(int i) {
            if (i < 0 || i >= getAccessibleActionCount()) {
                return null;
            }
            AccessibleContext ac = getCurrentAccessibleContext();
            if (i == 0) {
                // TIGER - 4766636
                // return AccessibleAction.TOGGLE_EXPAND;
                return "toggle expand";
            } else if (ac != null) {
                AccessibleAction aa = ac.getAccessibleAction();
                if (aa != null) {
                    return aa.getAccessibleActionDescription(i - 1);
                }
            }
            return null;
        }

        /**
         * Perform the specified Action on the tree node.  If this node
         * is not a leaf, there is at least one action which can be
         * done (toggle expand), in addition to any available on the
         * object behind the TreeCellRenderer.
         *
         * @param i zero-based index of actions
         * @return true if the the action was performed; else false.
         */
        public boolean doAccessibleAction(int i) {
            if (i < 0 || i >= getAccessibleActionCount()) {
                return false;
            }
            AccessibleContext ac = getCurrentAccessibleContext();
            if (i == 0) {
                if (tree.isExpanded(path)) {
                    tree.collapsePath(path);
                } else {
                    tree.expandPath(path);
                }
                return true;
            } else if (ac != null) {
                AccessibleAction aa = ac.getAccessibleAction();
                if (aa != null) {
                    return aa.doAccessibleAction(i - 1);
                }
            }
            return false;
        }

    } // inner class AccessibleJTreeNode

    /**
     * A helper class to perform {@code Callable} objects on the event dispatch thread appropriate
     * for the provided {@code AccessibleContext}.
     */
    private static class InvocationUtils {

        /**
         * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Accessible}
         * and waits for it to finish blocking the caller thread.
         *
         * @param callable   the {@code Callable} to invoke
         * @param accessible the {@code Accessible} which would be used to find the right context
         *                   for the task execution
         * @param <T> type parameter for the result value
         *
         * @return the result of the {@code Callable} execution
         */
        public static <T> T invokeAndWait(final Callable<T> callable,
                                          final Accessible accessible) {
            if (accessible instanceof Component) {
                return invokeAndWait(callable, (Component)accessible);
            }
            if (accessible instanceof AccessibleContext) {
                // This case also covers the Translator
                return invokeAndWait(callable, (AccessibleContext)accessible);
            }
            throw new RuntimeException("Unmapped Accessible used to dispatch event: " + accessible);
        }

        /**
         * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Component}
         * and waits for it to finish blocking the caller thread.
         *
         * @param callable  the {@code Callable} to invoke
         * @param component the {@code Component} which would be used to find the right context
         *                  for the task execution
         * @param <T> type parameter for the result value
         *
         * @return the result of the {@code Callable} execution
         */
        public static <T> T invokeAndWait(final Callable<T> callable,
                                          final Component component) {
            return invokeAndWait(callable, SunToolkit.targetToAppContext(component));
        }

        /**
         * Invokes a {@code Callable} in the {@code AppContext} mapped to the given {@code AccessibleContext}
         * and waits for it to finish blocking the caller thread.
         *
         * @param callable the {@code Callable} to invoke
         * @param accessibleContext the {@code AccessibleContext} which would be used to determine the right
         *                          context for the task execution.
         * @param <T> type parameter for the result value
         *
         * @return the result of the {@code Callable} execution
         */
        public static <T> T invokeAndWait(final Callable<T> callable,
                                          final AccessibleContext accessibleContext) {
            AppContext targetContext = AWTAccessor.getAccessibleContextAccessor()
                    .getAppContext(accessibleContext);
            if (targetContext != null) {
                return invokeAndWait(callable, targetContext);
            } else {
                // Normally this should not happen, unmapped context provided and
                // the target AppContext is unknown.

                // Try to recover in case the context is a translator.
                if (accessibleContext instanceof Translator) {
                    Object source = ((Translator)accessibleContext).getSource();
                    if (source instanceof Component) {
                        return invokeAndWait(callable, (Component)source);
                    }
                }
            }
            throw new RuntimeException("Unmapped AccessibleContext used to dispatch event: " + accessibleContext);
        }

        private static <T> T invokeAndWait(final Callable<T> callable,
                                           final AppContext targetAppContext) {
            final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable);
            try {
                invokeAndWait(wrapper, targetAppContext);
                T result = wrapper.getResult();
                updateAppContextMap(result, targetAppContext);
                return result;
            } catch (final Exception e) {
                throw new RuntimeException(e);
            }
        }

        private static void invokeAndWait(final Runnable runnable,
                                        final AppContext appContext)
                throws InterruptedException, InvocationTargetException {

            EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext);
            Object lock = new Object();
            Toolkit source = Toolkit.getDefaultToolkit();
            InvocationEvent event =
                    new InvocationEvent(source, runnable, lock, true);
            synchronized (lock) {
                eq.postEvent(event);
                lock.wait();
            }

            Throwable eventThrowable = event.getThrowable();
            if (eventThrowable != null) {
                throw new InvocationTargetException(eventThrowable);
            }
        }

        /**
         * Maps the {@code AccessibleContext} to the {@code AppContext} which should be used
         * to dispatch events related to the {@code AccessibleContext}
         * @param accessibleContext the {@code AccessibleContext} for the mapping
         * @param targetContext the {@code AppContext} for the mapping
         */
        public static void registerAccessibleContext(final AccessibleContext accessibleContext,
                                                     final AppContext targetContext) {
            if (accessibleContext != null) {
                AWTAccessor.getAccessibleContextAccessor().setAppContext(accessibleContext, targetContext);
            }
        }

        private static <T> void updateAppContextMap(final T accessibleContext,
                                                    final AppContext targetContext) {
            if (accessibleContext instanceof AccessibleContext) {
                registerAccessibleContext((AccessibleContext)accessibleContext, targetContext);
            }
        }

        private static class CallableWrapper<T> implements Runnable {
            private final Callable<T> callable;
            private volatile T object;
            private Exception e;

            CallableWrapper(final Callable<T> callable) {
                this.callable = callable;
            }

            public void run() {
                try {
                    if (callable != null) {
                        object = callable.call();
                    }
                } catch (final Exception e) {
                    this.e = e;
                }
            }

            T getResult() throws Exception {
                if (e != null)
                    throw e;
                return object;
            }
        }
    }
}
