jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.cpp
changeset 29883 e02d168adbc6
child 32116 444f22a0ad84
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.cpp	Fri Mar 27 16:13:45 2015 -0500
@@ -0,0 +1,2799 @@
+/*
+ * 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.
+ */
+
+/*
+ * A DLL which is loaded by Java applications to handle communication
+ * between Java VMs purposes of Accessbility.
+ */
+
+#include "AccessBridgeDebug.h"
+#include "JavaAccessBridge.h"
+#include "com_sun_java_accessibility_AccessBridge.h" // programatically generated by JNI
+#include "accessBridgeResource.h"
+#include "accessBridgeCallbacks.h"
+#include "AccessBridgeMessages.h"
+
+
+#include <windows.h>
+#include <stdio.h>
+
+#include <jawt.h>
+#include <jawt_md.h>
+
+JavaAccessBridge *theJavaAccessBridge;
+HWND theDialogWindow;
+
+// re-entrance lock for receiving memory messages
+CRITICAL_SECTION receiveMemoryIPCLock;
+
+
+// unique broadcast msg. IDs gotten dymanically
+extern UINT theFromJavaHelloMsgID;
+extern UINT theFromWindowsHelloMsgID;
+
+
+// ---------------------------------------------------------------------------
+
+extern "C" {
+    /**
+     * DllMain - where Windows executables will load/unload us
+     *
+     */
+    BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) {
+
+        switch (fdwReason) {
+        case DLL_PROCESS_ATTACH:
+            InitializeCriticalSection(&receiveMemoryIPCLock);
+            theJavaAccessBridge = new JavaAccessBridge(hinstDll);
+            break;
+
+        case DLL_PROCESS_DETACH:        // A Windows executable unloaded us
+            if (theJavaAccessBridge != (JavaAccessBridge *) 0) {
+                delete theJavaAccessBridge;
+                DeleteCriticalSection(&receiveMemoryIPCLock);
+            }
+            break;
+        }
+        return TRUE;
+    }
+
+    /**
+     * Open a native window (and init the wrappers we'll be using)
+     *
+     */
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_runDLL(JNIEnv *env, jobject obj) {
+        PrintDebugString("\r\nJavaAccessBridge.DLL runDLL() called");
+        theJavaAccessBridge->javaRun(env, obj);
+    }
+
+#if 0 // SetDlgItemText has caused problems with JAWS
+    /**
+     * Append debug info to dialog
+     *
+     */
+    void AppendToCallInfo(char *s) {
+        char buffer[4096];
+
+        PrintDebugString(s);
+
+        GetDlgItemText(theDialogWindow, cCallInfo, buffer, sizeof(buffer));
+        if (strlen(buffer) < (sizeof(buffer) - strlen(s))) {
+            strncat(buffer, s, sizeof(buffer));
+            SetDlgItemText(theDialogWindow, cCallInfo, buffer);
+        } else {
+            SetDlgItemText(theDialogWindow, cCallInfo, s);
+        }
+    }
+#endif
+
+
+    /**
+     * Our window proc
+     *
+     */
+    BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) {
+        int command;
+        COPYDATASTRUCT *sentToUs;
+        char *package;
+        //DEBUG_CODE(char buffer[256]);
+
+        switch (message) {
+        case WM_INITDIALOG:
+            //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Initializing"));
+            break;
+
+        case WM_COMMAND:
+            command = LOWORD (wParam);
+            break;
+
+            // call from Java with data for us to deliver
+        case WM_COPYDATA:
+            if (theDialogWindow == (HWND) wParam) {
+                //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got WM_COPYDATA from ourselves"));
+            } else {
+                //DEBUG_CODE(sprintf(buffer, "Got WM_COPYDATA from HWND %p", wParam));
+                //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer));
+                sentToUs = (COPYDATASTRUCT *) lParam;
+                package = (char *) sentToUs->lpData;
+                theJavaAccessBridge->processPackage(package, sentToUs->cbData);
+            }
+            break;
+
+            // call from Java with data for us retrieve from memory mapped file and deliver
+        case AB_MESSAGE_WAITING:
+            // wParam == sourceHwnd
+            // lParam == buffer size in shared memory
+            if (theDialogWindow == (HWND) wParam) {
+                //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_MESSAGE_WAITING from ourselves"));
+            } else {
+                //DEBUG_CODE(sprintf(buffer, "Got AB_MESSAGE_WAITING from HWND %p", wParam));
+                //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer));
+                LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, lParam);
+            }
+            break;
+
+            // a JavaAccessBridge DLL is going away
+        case AB_DLL_GOING_AWAY:
+            // wParam == sourceHwnd
+            //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_DLL_GOING_AWAY message"));
+            theJavaAccessBridge->WindowsATDestroyed((HWND) wParam);
+            break;
+
+        default:
+            // the Windows AT is saying "hi"!
+            // wParam == sourceHwnc; lParam unused
+            if (message == theFromWindowsHelloMsgID) {
+                // A new Windows AT just said "hi";
+                // say "hi" back so it can mate up with us
+                // otherwise don't do anything (e.g. don't set up data structures yet)
+                theJavaAccessBridge->postHelloToWindowsDLLMsg((HWND) wParam);
+            }
+        }
+        return FALSE;
+    }
+
+}
+
+
+// -----------------------------
+
+
+/**
+ * Initialize the JavaAccessBridge
+ *
+ */
+JavaAccessBridge::JavaAccessBridge(HINSTANCE hInstance) {
+    windowsInstance = hInstance;
+    ATs = (AccessBridgeATInstance *) 0;
+    initBroadcastMessageIDs();          // get the unique to us broadcast msg. IDs
+}
+
+extern DWORD JavaBridgeThreadId;
+
+/**
+ * Destroy the JavaAccessBridge
+ *
+ */
+JavaAccessBridge::~JavaAccessBridge() {
+    // inform all other AccessBridges that we're going away
+
+    PrintDebugString("\r\nin JavaAccessBridge::~JavaAccessBridge()");
+
+    // Send a shutdown message for those applications like StarOffice that do
+    // send a shutdown message themselves.
+    javaShutdown(NULL, 0);
+
+    AccessBridgeATInstance *current = ATs;
+    while (current != (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  telling %p we're going away", current->winAccessBridgeWindow);
+                SendMessage(current->winAccessBridgeWindow,
+                    AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0);
+        current = current->nextATInstance;
+    }
+
+    PrintDebugString("  finished telling ATs about our demise");
+
+        if(JavaBridgeThreadId)
+                {
+                PostThreadMessage(JavaBridgeThreadId,WM_USER+1,0,0);
+                Sleep(100);
+                }
+
+    delete ATs;
+
+    PrintDebugString("  finished deleting ATs");
+    PrintDebugString("GOODBYE CRUEL WORLD...");
+}
+
+
+void
+JavaAccessBridge::javaRun(JNIEnv *env, jobject obj) {
+    MSG msg;
+
+    PrintDebugString("JavaAccessBridge::javaRun(%p, %p) called", env, obj);
+
+    if (env->GetJavaVM(&javaVM) != 0) {
+        return; // huh!?!?!
+    }
+    PrintDebugString("  -> javaVM = %p", javaVM);
+
+    if (javaVM->AttachCurrentThread((void **) &windowsThreadJNIEnv, NULL) != 0) {
+        return; // huh!?!?!
+    }
+    PrintDebugString("  -> windowsThreadJNIEnv = %p", windowsThreadJNIEnv);
+
+    javaThreadABObject = env->NewGlobalRef(obj);
+    windowsThreadABObject = windowsThreadJNIEnv->NewGlobalRef(obj);
+
+    // initialize the Java thread AccessBridge entry points
+    javaThreadEntryPoints = new AccessBridgeJavaEntryPoints(env, javaThreadABObject);
+    if (javaThreadEntryPoints->BuildJavaEntryPoints() == FALSE) {
+        return;         // couldn't build our entry points; let's get out of here!
+    }
+    PrintDebugString("  all Java thread entry points successfully found.");
+
+    // initialize the Windows thread AccessBridge entry points
+    windowsThreadEntryPoints = new AccessBridgeJavaEntryPoints(windowsThreadJNIEnv,
+                                                               windowsThreadABObject);
+    if (windowsThreadEntryPoints->BuildJavaEntryPoints() == FALSE) {
+        return;         // couldn't build our entry points; let's get out of here!
+    }
+    PrintDebugString("  all Windows thread entry points successfully found.");
+
+
+    // open our window
+    if (initWindow() == TRUE) {
+        PrintDebugString("  Window created.  HWND = %p", dialogWindow);
+
+        // post a broadcast msg.; let other AccessBridge DLLs know we exist
+        postHelloToWindowsDLLMsg(HWND_BROADCAST);
+
+        // do that message loop thing
+        while (GetMessage(&msg, NULL, 0, 0)) {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+    } else {
+        PrintDebugString("  FAILED TO CREATE WINDOW!!!");
+    }
+
+    javaVM->DetachCurrentThread();
+}
+
+/**
+ * Bring up our window; make a connection to the rest of the world
+ *
+ */
+BOOL
+JavaAccessBridge::initWindow() {
+    theDialogWindow = CreateDialog(windowsInstance,
+                                   "ACCESSBRIDGESTATUSWINDOW", NULL,
+                                   (DLGPROC) AccessBridgeDialogProc);
+
+    // If window could not be created, return "failure".
+    if (!theDialogWindow)
+        return FALSE;
+
+    dialogWindow = theDialogWindow;
+
+    // Make the window visible, update its client area, & return "success".
+    // DEBUG_CODE(ShowWindow (theDialogWindow, SW_SHOWNORMAL));
+    // DEBUG_CODE(UpdateWindow (theDialogWindow));
+
+    return TRUE;
+}
+
+
+
+// -----------------------
+
+
+/**
+ * postHelloToWindowsDLLMsg
+ *          - PostMessage(theFromJavaHelloMsgID) to let one or
+ *            all WindowDLLs we're here and have a vmID
+ *
+ *            destHwnd is either a single hwnd or HWND_BROADCAST
+ *              (former if a reply, latter if we're just born)
+ *            wParam is our HWND
+ *            lParam is our vmID
+ *
+ */
+void
+JavaAccessBridge::postHelloToWindowsDLLMsg(HWND destHwnd) {
+    PrintDebugString("\r\nin JavaAccessBridge::postHelloToWindowsDLLMsg");
+    PrintDebugString("  calling PostMessage(%p, %X, %p, %p)",
+                     destHwnd, theFromJavaHelloMsgID, dialogWindow, javaVM);
+    PostMessage(destHwnd, theFromJavaHelloMsgID, (WPARAM) dialogWindow, (LPARAM) dialogWindow);
+}
+
+
+// -----------------------
+
+/**
+ * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging
+ *                                with the Java AccessBridge DLL
+ *
+ */
+void
+JavaAccessBridge::sendPackage(char *buffer, int bufsize, HWND destHwnd) {
+    COPYDATASTRUCT toCopy;
+    toCopy.dwData = 0;          // 32-bits we could use for something...
+    toCopy.cbData = bufsize;
+    toCopy.lpData = buffer;
+
+    SendMessage(destHwnd, WM_COPYDATA, (WPARAM) dialogWindow, (LPARAM) &toCopy);
+}
+
+
+/**
+ * sendJavaEventPackage - walk through ATs, sending event messages to 'em
+ *
+ */
+void
+JavaAccessBridge::sendJavaEventPackage(char *buffer, int bufsize, long type) {
+
+    PrintDebugString("JavaAccessBridge::sendJavaEventPackage(), type = %X", type);
+
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+    }
+
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        ati->sendJavaEventPackage(buffer, bufsize, type);
+        ati = ati->nextATInstance;
+    }
+}
+
+/**
+ * sendAccessibilityEventPackage - walk through ATs, sending event messages to 'em
+ *
+ */
+void
+JavaAccessBridge::sendAccessibilityEventPackage(char *buffer, int bufsize, long type) {
+
+    PrintDebugString("JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type);
+
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+    }
+
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        ati->sendAccessibilityEventPackage(buffer, bufsize, type);
+        ati = ati->nextATInstance;
+    }
+}
+
+
+
+
+/**
+ * receiveMemoryPackage - uses Memory-Mapped files to do IPC messaging
+ *                        with the Java AccessBridge DLL, receiving the
+ *                        message from Java AccessBridge DLL by reading the
+ *                        contents of the shared memory mapped file that
+ *                        is used for Java-initiated messages
+ *
+ */
+BOOL
+JavaAccessBridge::receiveMemoryPackage(HWND srcWindow, long bufsize) {
+    char *IPCview;
+
+    PrintDebugString("\r\nJavaAccessBridge::receiveMemoryPackage(%p, %d)", srcWindow, bufsize);
+
+    // look-up the appropriate IPCview based on the srcHWND of the Windows AccessBridge DLL
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR! - ATs == 0 (shouldn't happen in receiveMemoryPackage()!");
+        return FALSE;
+    }
+    AccessBridgeATInstance *ati = ATs->findABATInstanceFromATHWND(srcWindow);
+    if (ati != (AccessBridgeATInstance *) 0) {
+        IPCview = (char *) ati->memoryMappedView;
+
+        // wait for the lock if someone else has it (re-entrancy)
+        EnterCriticalSection(&receiveMemoryIPCLock);
+        {
+            // set byte at end of buffer to indicate to caller that we have reached this point
+            IPCview[bufsize] = 1;
+
+            // process the package
+            processPackage(IPCview, bufsize);
+        }
+        // release re-entrance lock
+        LeaveCriticalSection(&receiveMemoryIPCLock);
+
+        return TRUE;
+
+    } else {
+        //DEBUG_CODE(AppendToCallInfo("ERROR receiving memory package: couldn't find srcWindow"));
+        PrintDebugString("ERROR receiving memory package: couldn't find srcWindow");
+        return FALSE;
+    }
+}
+
+/**
+ * processPackage - processes the output of SendMessage(WM_COPYDATA)
+ *                                      to do IPC messaging with the Windows AccessBridge DLL
+ *
+ */
+LRESULT
+JavaAccessBridge::processPackage(char *buffer, int bufsize) {
+    PrintDebugString("\r\nProcessing package sent from Windows, bufsize = %d:", bufsize);
+
+    PackageType *type = (PackageType *) buffer;
+    LRESULT returnVal = 0;
+    PrintDebugString("  PackageType = %X:", *type);
+    jobject rAC;
+
+    switch (*type) {
+
+
+    case cMemoryMappedFileCreatedPackage:
+        // Windows is telling us it created a memory mapped file for us to use
+        // in repsonding to various information querying packages (see below)
+        PrintDebugString("   type == cMemoryMappedFileCreatedPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage))) {
+            MemoryMappedFileCreatedPackage *pkg =
+                (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType));
+            returnVal = MemoryMappedFileCreated((HWND)ABLongToHandle(pkg->bridgeWindow), pkg->filename);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage));
+        }
+        break;
+
+        // ------------ information querying packages ------------------
+
+    case cReleaseJavaObjectPackage:
+        PrintDebugString("   type == cReleaseJavaObjectPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage))) {
+            ReleaseJavaObjectPackage *pkg =
+                (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType));
+            releaseJavaObject((jobject)pkg->object);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage));
+        }
+        break;
+
+    case cGetAccessBridgeVersionPackage:
+        PrintDebugString("   type == cGetAccessBridgeVersionPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage))) {
+            GetAccessBridgeVersionPackage *pkg =
+                (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getVersionInfo(&(pkg->rVersionInfo));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage));
+        }
+        break;
+
+    case cIsJavaWindowPackage:
+        PrintDebugString("   type == cIsJavaWindowPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(IsJavaWindowPackage))) {
+            IsJavaWindowPackage *pkg =
+                (IsJavaWindowPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult =
+                windowsThreadEntryPoints->isJavaWindow(pkg->window);
+            PrintDebugString("     -> returning result = %d", pkg->rResult);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(IsJavaWindowPackage));
+        }
+        break;
+
+    case cIsSameObjectPackage:
+        PrintDebugString("   type == cIsSameObjectPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(IsSameObjectPackage))) {
+            IsSameObjectPackage *pkg =
+                (IsSameObjectPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult =
+                windowsThreadEntryPoints->isSameObject((jobject)pkg->obj1, (jobject)pkg->obj2);
+            PrintDebugString("     -> returning result = %d", pkg->rResult);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(IsSameObjectPackage));
+        }
+        break;
+
+
+    case cGetAccessibleContextFromHWNDPackage:
+        PrintDebugString("   type == cGetAccessibleContextFromHWNDPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage))) {
+            GetAccessibleContextFromHWNDPackage *pkg =
+                (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType));
+            rAC = windowsThreadEntryPoints->getAccessibleContextFromHWND(pkg->window);
+            pkg->rAccessibleContext = (JOBJECT64)rAC;
+            pkg->rVMID = HandleToLong(dialogWindow);
+            PrintDebugString("     -> returning AC = %p, vmID = %X", rAC, pkg->rVMID);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage));
+        }
+        break;
+
+
+    case cGetHWNDFromAccessibleContextPackage:
+        PrintDebugString("   type == cGetHWNDFromAccessibleContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage))) {
+            GetHWNDFromAccessibleContextPackage *pkg =
+                (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType));
+            pkg->rHWND =
+                ABHandleToLong( windowsThreadEntryPoints->getHWNDFromAccessibleContext((jobject)pkg->accessibleContext) );
+            PrintDebugString("     -> returning HWND = %p", pkg->rHWND);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage));
+        }
+        break;
+
+
+        /* ===== utility methods ===== */
+
+    case cSetTextContentsPackage:
+        PrintDebugString("   type == cSetTextContentsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(SetTextContentsPackage))) {
+            SetTextContentsPackage *pkg =
+                (SetTextContentsPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult =
+                windowsThreadEntryPoints->setTextContents((jobject)pkg->accessibleContext, pkg->text);
+            PrintDebugString("     -> returning result = %d", pkg->rResult);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(SetTextContentsPackage));
+        }
+        break;
+
+    case cGetParentWithRolePackage:
+        if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRolePackage))) {
+            GetParentWithRolePackage *pkg =
+                (GetParentWithRolePackage *) (buffer + sizeof(PackageType));
+            rAC = windowsThreadEntryPoints->getParentWithRole((jobject)pkg->accessibleContext, pkg->role);
+            pkg->rAccessibleContext = (JOBJECT64)rAC;
+            PrintDebugString("   type == cGetParentWithRolePackage");
+            PrintDebugString("     pkg->vmID: %X", pkg->vmID);
+            PrintDebugString("     pkg->accessibleContext: %p", (jobject)pkg->accessibleContext);
+            PrintDebugString("     pkg->role: %ls", pkg->role);
+            PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetParentWithRolePackage));
+        }
+        break;
+
+    case cGetTopLevelObjectPackage:
+        PrintDebugString("   type == cGetTopLevelObjectPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetTopLevelObjectPackage))) {
+            GetTopLevelObjectPackage *pkg =
+                (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType));
+            rAC = windowsThreadEntryPoints->getTopLevelObject((jobject)pkg->accessibleContext);
+            pkg->rAccessibleContext = (JOBJECT64)rAC;
+            PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetTopLevelObjectPackage));
+        }
+        break;
+
+    case cGetParentWithRoleElseRootPackage:
+        PrintDebugString("   type == cGetParentWithRoleElseRootPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage))) {
+            GetParentWithRoleElseRootPackage *pkg =
+                (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType));
+            rAC = windowsThreadEntryPoints->getParentWithRoleElseRoot((jobject)pkg->accessibleContext, pkg->role);
+            pkg->rAccessibleContext = (JOBJECT64)rAC;
+            PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage));
+        }
+        break;
+
+    case cGetObjectDepthPackage:
+        PrintDebugString("   type == cGetObjectDepthPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetObjectDepthPackage))) {
+            GetObjectDepthPackage *pkg =
+                (GetObjectDepthPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult =
+                windowsThreadEntryPoints->getObjectDepth((jobject)pkg->accessibleContext);
+            PrintDebugString("     -> returning rResult = %d", pkg->rResult);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetObjectDepthPackage));
+        }
+        break;
+
+    case cGetActiveDescendentPackage:
+        PrintDebugString("   type == cGetActiveDescendentPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetActiveDescendentPackage))) {
+            GetActiveDescendentPackage *pkg =
+                (GetActiveDescendentPackage *) (buffer + sizeof(PackageType));
+            rAC = windowsThreadEntryPoints->getActiveDescendent((jobject)pkg->accessibleContext);
+            pkg->rAccessibleContext = (JOBJECT64)rAC;
+            PrintDebugString("     -> returning rAccessibleContext = %p", rAC);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetActiveDescendentPackage));
+        }
+        break;
+
+    case cGetAccessibleContextAtPackage:
+        PrintDebugString("   type == cGetAccessibleContextAtPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage))) {
+            GetAccessibleContextAtPackage *pkg =
+                (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType));
+            pkg->rAccessibleContext = (JOBJECT64)
+                windowsThreadEntryPoints->getAccessibleContextAt(pkg->x, pkg->y,
+                                                                 (jobject)pkg->AccessibleContext);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage));
+        }
+        break;
+
+    case cGetAccessibleContextWithFocusPackage:
+        PrintDebugString("   type == cGetAccessibleContextWithFocusPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage))) {
+            GetAccessibleContextWithFocusPackage *pkg =
+                (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType));
+            pkg->rAccessibleContext = (JOBJECT64)
+                windowsThreadEntryPoints->getAccessibleContextWithFocus();
+                        pkg->rVMID =  HandleToLong(dialogWindow);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage));
+        }
+        break;
+
+    case cGetAccessibleContextInfoPackage:
+        PrintDebugString("   type == cGetAccessibleContextInfoPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage))) {
+            GetAccessibleContextInfoPackage *pkg =
+                (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleContextInfo(
+                                                               (jobject)pkg->AccessibleContext, &(pkg->rAccessibleContextInfo));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage));
+        }
+        break;
+
+    case cGetAccessibleChildFromContextPackage:
+        PrintDebugString("   type == cGetAccessibleChildFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage))) {
+            GetAccessibleChildFromContextPackage *pkg =
+                (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType));
+            pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleChildFromContext(
+                                                                                              (jobject)pkg->AccessibleContext, pkg->childIndex);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage));
+        }
+        break;
+
+    case cGetAccessibleParentFromContextPackage:
+        PrintDebugString("   type == cGetAccessibleParentFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage))) {
+            GetAccessibleParentFromContextPackage *pkg =
+                (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType));
+            pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleParentFromContext(
+                                                                                               (jobject)pkg->AccessibleContext);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage));
+        }
+        break;
+
+        // ------------ begin AccessibleTable packages ------------------
+
+    case cGetAccessibleTableInfoPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableInfoPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage))) {
+            GetAccessibleTableInfoPackage *pkg =
+                (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTableInfo((jobject)pkg->accessibleContext,
+                                                             &(pkg->rTableInfo));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage));
+        }
+        break;
+
+    case cGetAccessibleTableCellInfoPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableCellInfoPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage))) {
+            GetAccessibleTableCellInfoPackage *pkg =
+                (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTableCellInfo((jobject)pkg->accessibleTable, pkg->row,
+                                                                 pkg->column, &(pkg->rTableCellInfo));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage));
+        }
+        break;
+
+    case cGetAccessibleTableRowHeaderPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableRowHeaderPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage))) {
+            GetAccessibleTableRowHeaderPackage *pkg =
+                (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTableRowHeader((jobject)pkg->accessibleContext,
+                                                                  &(pkg->rTableInfo));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage));
+        }
+        break;
+
+    case cGetAccessibleTableColumnHeaderPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableColumnHeaderPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage))) {
+            GetAccessibleTableColumnHeaderPackage *pkg =
+                (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTableColumnHeader((jobject)pkg->accessibleContext,
+                                                                     &(pkg->rTableInfo));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage));
+        }
+        break;
+
+
+    case cGetAccessibleTableRowDescriptionPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableRowDescriptionPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage))) {
+            GetAccessibleTableRowDescriptionPackage *pkg =
+                (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType));
+            pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableRowDescription(
+                                                                                                 (jobject)pkg->accessibleContext, pkg->row);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage));
+        }
+        break;
+
+    case cGetAccessibleTableColumnDescriptionPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableColumnDescriptionPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage))) {
+            GetAccessibleTableColumnDescriptionPackage *pkg =
+                (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType));
+            pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableColumnDescription(
+                                                                                                    (jobject)pkg->accessibleContext, pkg->column);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage));
+        }
+        break;
+
+    case cGetAccessibleTableColumnSelectionCountPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableColumnSelectionCountPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage))) {
+            GetAccessibleTableColumnSelectionCountPackage *pkg =
+                (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType));
+            pkg->rCount = windowsThreadEntryPoints->getAccessibleTableColumnSelectionCount(
+                                                                                           (jobject)pkg->accessibleTable);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage));
+        }
+        break;
+
+    case cGetAccessibleTableRowSelectionCountPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableRowSelectionCountPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage))) {
+            GetAccessibleTableRowSelectionCountPackage *pkg =
+                (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType));
+
+            pkg->rCount = windowsThreadEntryPoints->getAccessibleTableRowSelectionCount(
+                                                                                        (jobject)pkg->accessibleTable);
+
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage));
+        }
+        break;
+
+    case cIsAccessibleTableRowSelectedPackage:
+        PrintDebugString("   ##### type == cIsAccessibleTableRowSelectedPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage))) {
+            IsAccessibleTableRowSelectedPackage *pkg =
+                (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult = windowsThreadEntryPoints->isAccessibleTableRowSelected(
+                                                                                  (jobject)pkg->accessibleTable, pkg->row);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage));
+        }
+        break;
+
+    case cIsAccessibleTableColumnSelectedPackage:
+        PrintDebugString("   ##### type == cIsAccessibleTableColumnSelectedPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage))) {
+            IsAccessibleTableColumnSelectedPackage *pkg =
+                (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult = windowsThreadEntryPoints->isAccessibleTableColumnSelected(
+                                                                                     (jobject)pkg->accessibleTable, pkg->column);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage));
+        }
+        break;
+
+    case cGetAccessibleTableColumnSelectionsPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableColumnSelectionsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage))) {
+            GetAccessibleTableColumnSelectionsPackage *pkg =
+                (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType));
+            PrintDebugString("     ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count);
+            windowsThreadEntryPoints->getAccessibleTableColumnSelections(
+                                                                         (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections);
+
+            for (int i = 0; i < pkg->count; i++) {
+                PrintDebugString("     ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]);
+            }
+
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage));
+        }
+        break;
+
+
+    case cGetAccessibleTableRowSelectionsPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableRowSelectionsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage))) {
+            GetAccessibleTableRowSelectionsPackage *pkg =
+                (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTableRowSelections(
+                                                                      (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage));
+        }
+        break;
+
+    case cGetAccessibleTableRowPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableRowPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage))) {
+            GetAccessibleTableRowPackage *pkg =
+                (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType));
+            pkg->rRow = windowsThreadEntryPoints->getAccessibleTableRow(
+                                                                        (jobject)pkg->accessibleTable, pkg->index);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage));
+        }
+        break;
+
+    case cGetAccessibleTableColumnPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableColumnPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage))) {
+            GetAccessibleTableColumnPackage *pkg =
+                (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType));
+            pkg->rColumn = windowsThreadEntryPoints->getAccessibleTableColumn(
+                                                                              (jobject)pkg->accessibleTable, pkg->index);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage));
+        }
+        break;
+
+    case cGetAccessibleTableIndexPackage:
+        PrintDebugString("   ##### type == cGetAccessibleTableIndexPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage))) {
+            GetAccessibleTableIndexPackage *pkg =
+                (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType));
+            pkg->rIndex = windowsThreadEntryPoints->getAccessibleTableIndex(
+                                                                            (jobject)pkg->accessibleTable, pkg->row, pkg->column);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage));
+        }
+        break;
+
+        // ------------ end AccessibleTable packages ------------------
+
+
+        // ------------ begin AccessibleRelationSet packages ------------------
+
+    case cGetAccessibleRelationSetPackage:
+        PrintDebugString("   ##### type == cGetAccessibleRelationSetPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage))) {
+            GetAccessibleRelationSetPackage *pkg =
+                (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleRelationSet(
+                                                               (jobject)pkg->accessibleContext, &(pkg->rAccessibleRelationSetInfo));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage));
+        }
+        break;
+
+        // ------------ end AccessibleRelationSet packages ------------------
+
+        // ------------ begin AccessibleHypertext packages ------------------
+
+    case cGetAccessibleHypertextPackage:
+        PrintDebugString("   ##### type == cGetAccessibleHypertextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage))) {
+            GetAccessibleHypertextPackage *pkg =
+                (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleHypertext(
+                                                             (jobject)pkg->accessibleContext, &(pkg->rAccessibleHypertextInfo));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage));
+        }
+        break;
+
+    case cActivateAccessibleHyperlinkPackage:
+        PrintDebugString("   ##### type == cActivateAccessibleHyperlinkPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage))) {
+            ActivateAccessibleHyperlinkPackage *pkg =
+                (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult = windowsThreadEntryPoints->activateAccessibleHyperlink(
+                                                                                 (jobject)pkg->accessibleContext, (jobject)pkg->accessibleHyperlink);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage));
+        }
+        break;
+
+    case cGetAccessibleHyperlinkCountPackage:
+        PrintDebugString("   ##### type == cGetAccessibleHyperlinkCountPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage))) {
+            GetAccessibleHyperlinkCountPackage *pkg =
+                (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType));
+            pkg->rLinkCount = windowsThreadEntryPoints->getAccessibleHyperlinkCount(
+                                                                                    (jobject)pkg->accessibleContext);
+            PrintDebugString("   ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount);
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage));
+        }
+        break;
+
+    case cGetAccessibleHypertextExtPackage:
+        PrintDebugString("   ##### type == cGetAccessibleHypertextExtPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage))) {
+            GetAccessibleHypertextExtPackage *pkg =
+                (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType));
+            pkg->rSuccess = windowsThreadEntryPoints->getAccessibleHypertextExt(
+                                                                                (jobject)pkg->accessibleContext, pkg->startIndex, &(pkg->rAccessibleHypertextInfo));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage));
+        }
+        break;
+
+    case cGetAccessibleHypertextLinkIndexPackage:
+        PrintDebugString("   ##### type == cGetAccessibleHypertextLinkIndexPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage))) {
+            GetAccessibleHypertextLinkIndexPackage *pkg =
+                (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType));
+            pkg->rLinkIndex = windowsThreadEntryPoints->getAccessibleHypertextLinkIndex(
+                                                                                        (jobject)pkg->hypertext, pkg->charIndex);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage));
+        }
+        break;
+
+    case cGetAccessibleHyperlinkPackage:
+        PrintDebugString("   ##### type == cGetAccessibleHyperlinkPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage))) {
+            GetAccessibleHyperlinkPackage *pkg =
+                (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleHyperlink((jobject)pkg->hypertext, pkg->linkIndex,
+                                                             &(pkg->rAccessibleHyperlinkInfo));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage));
+        }
+        break;
+
+        // ------------ end AccessibleHypertext packages
+
+        // ------------ begin Accessible KeyBindings, Icons and Actions
+
+    case cGetAccessibleKeyBindingsPackage:
+        PrintDebugString("   ##### type == cGetAccessibleKeyBindingsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage))) {
+            GetAccessibleKeyBindingsPackage *pkg =
+                (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleKeyBindings (
+                                                                (jobject)pkg->accessibleContext, &(pkg->rAccessibleKeyBindings));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage));
+        }
+        break;
+
+    case cGetAccessibleIconsPackage:
+        PrintDebugString("   ##### type == cGetAccessibleIconsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleIconsPackage))) {
+            GetAccessibleIconsPackage *pkg =
+                (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleIcons (
+                                                          (jobject)pkg->accessibleContext, &(pkg->rAccessibleIcons));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleIconsPackage));
+        }
+        break;
+
+
+    case cGetAccessibleActionsPackage:
+        PrintDebugString("   ##### type == cGetAccessibleActionsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleActionsPackage))) {
+            GetAccessibleActionsPackage *pkg =
+                (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleActions (
+                                                            (jobject)pkg->accessibleContext, &(pkg->rAccessibleActions));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleActionsPackage));
+        }
+        break;
+
+    case cDoAccessibleActionsPackage:
+        PrintDebugString("   ##### type == cDoAccessibleActionsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(DoAccessibleActionsPackage))) {
+            DoAccessibleActionsPackage *pkg =
+                (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult =
+                windowsThreadEntryPoints->doAccessibleActions((jobject)pkg->accessibleContext, &(pkg->actionsToDo),
+                                                              &(pkg->failure));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(DoAccessibleActionsPackage));
+        }
+        break;
+
+        // ------------ begin addtional methods for Teton
+
+    case cGetVirtualAccessibleNamePackage:
+        PrintDebugString("   ##### type == GetVirtualAccessibleNamePackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage))) {
+            GetVirtualAccessibleNamePackage *pkg =
+                (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getVirtualAccessibleName ((const jobject)pkg->accessibleContext,
+                                                             pkg->rName,
+                                                             pkg->len);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage));
+        }
+        break;
+
+    case cRequestFocusPackage:
+        PrintDebugString("   ##### type == RequestFocusPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(RequestFocusPackage))) {
+            RequestFocusPackage *pkg =
+                (RequestFocusPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->requestFocus (
+                                                    (jobject)pkg->accessibleContext);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(RequestFocusPackage));
+        }
+        break;
+
+    case cSelectTextRangePackage:
+        PrintDebugString("   ##### type == SelectTextRangePackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(SelectTextRangePackage))) {
+            SelectTextRangePackage *pkg =
+                (SelectTextRangePackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->selectTextRange (
+                                                       (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(SelectTextRangePackage));
+        }
+        break;
+
+    case cGetTextAttributesInRangePackage:
+        PrintDebugString("   ##### type == GetTextAttributesInRangePackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage))) {
+            GetTextAttributesInRangePackage *pkg =
+                (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getTextAttributesInRange (
+                                                                (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex,
+                                                                (AccessibleTextAttributesInfo *)&(pkg->attributes),
+                                                                &(pkg->rLength));
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage));
+        }
+        break;
+
+
+    case cGetVisibleChildrenCountPackage:
+        PrintDebugString("   ##### type == GetVisibleChildrenCountPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage))) {
+            GetVisibleChildrenCountPackage *pkg =
+                (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType));
+            pkg->rChildrenCount = windowsThreadEntryPoints->getVisibleChildrenCount ((jobject)pkg->accessibleContext);
+
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage));
+        }
+        break;
+
+    case cGetVisibleChildrenPackage:
+        PrintDebugString("   ##### type == GetVisibleChildrenPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenPackage))) {
+            GetVisibleChildrenPackage *pkg =
+                (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType));
+            pkg->rSuccess = windowsThreadEntryPoints->getVisibleChildren ((jobject)pkg->accessibleContext,
+                                                                          pkg->startIndex,
+                                                                          &(pkg->rVisibleChildrenInfo));
+
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenPackage));
+        }
+        break;
+
+    case cSetCaretPositionPackage:
+        PrintDebugString("   ##### type == SetCaretPositionPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(SetCaretPositionPackage))) {
+            SetCaretPositionPackage *pkg =
+                (SetCaretPositionPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->setCaretPosition (
+                                                        (jobject)pkg->accessibleContext, pkg->position);
+            PrintDebugString("   ##### processing succeeded");
+        } else {
+            PrintDebugString("   ##### processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(SetCaretPositionPackage));
+        }
+        break;
+
+        // ------------ end additional methods for Teton
+
+        // ------------ end Accessible KeyBindings, Icons and Actions
+
+        // ------------ Accessible Text packages ------------------
+
+    case cGetAccessibleTextInfoPackage:
+        PrintDebugString("   type == cGetAccessibleTextInfoPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage))) {
+            GetAccessibleTextInfoPackage *pkg =
+                (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTextInfo((jobject)pkg->AccessibleContext,
+                                                            &(pkg->rTextInfo), pkg->x, pkg->y);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage));
+        }
+        break;
+
+    case cGetAccessibleTextItemsPackage:
+        PrintDebugString("   type == cGetAccessibleTextItemsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage))) {
+            GetAccessibleTextItemsPackage *pkg =
+                (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTextItems((jobject)pkg->AccessibleContext,
+                                                             &(pkg->rTextItemsInfo), pkg->index);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage));
+        }
+        break;
+
+    case cGetAccessibleTextSelectionInfoPackage:
+        PrintDebugString("   type == cGetAccessibleTextSelectionInfoPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage))) {
+            GetAccessibleTextSelectionInfoPackage *pkg =
+                (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTextSelectionInfo(
+                                                                     (jobject)pkg->AccessibleContext, &(pkg->rTextSelectionItemsInfo));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage));
+        }
+        break;
+
+    case cGetAccessibleTextAttributeInfoPackage:
+        PrintDebugString("   type == cGetAccessibleTextAttributeInfoPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage))) {
+            GetAccessibleTextAttributeInfoPackage *pkg =
+                (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTextAttributes(
+                                                                  (jobject)pkg->AccessibleContext, pkg->index, (AccessibleTextAttributesInfo *) &(pkg->rAttributeInfo));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage));
+        }
+        break;
+
+    case cGetAccessibleTextRectInfoPackage:
+        PrintDebugString("   type == cGetAccessibleTextRectInfoPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage))) {
+            GetAccessibleTextRectInfoPackage *pkg =
+                (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTextRect((jobject)pkg->AccessibleContext,
+                                                            &(pkg->rTextRectInfo), pkg->index);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage));
+        }
+        break;
+
+    case cGetCaretLocationPackage:
+        PrintDebugString("   type == cGetCaretLocationPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetCaretLocationPackage))) {
+            GetCaretLocationPackage *pkg =
+                (GetCaretLocationPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getCaretLocation((jobject)pkg->AccessibleContext,
+                                                            &(pkg->rTextRectInfo), pkg->index);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetCaretLocationPackage));
+        }
+        break;
+
+    case cGetAccessibleTextLineBoundsPackage:
+        PrintDebugString("   type == cGetAccessibleTextLineBoundsPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage))) {
+            GetAccessibleTextLineBoundsPackage *pkg =
+                (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTextLineBounds((jobject)pkg->AccessibleContext,
+                                                                  pkg->index, &(pkg->rLineStart), &(pkg->rLineEnd));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage));
+        }
+        break;
+
+    case cGetAccessibleTextRangePackage:
+        PrintDebugString("   type == cGetAccessibleTextRangePackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage))) {
+            GetAccessibleTextRangePackage *pkg =
+                (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getAccessibleTextRange((jobject)pkg->AccessibleContext,
+                                                             pkg->start, pkg->end, (wchar_t *) &(pkg->rText), (sizeof(pkg->rText) / sizeof(wchar_t)));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage));
+        }
+        break;
+
+
+        // ------------ Accessible Value packages ------------------
+
+    case cGetCurrentAccessibleValueFromContextPackage:
+        PrintDebugString("   type == cGetCurrentAccessibleValueFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage))) {
+            GetCurrentAccessibleValueFromContextPackage *pkg =
+                (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getCurrentAccessibleValueFromContext((jobject)pkg->AccessibleContext,
+                                                                           (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage));
+        }
+        break;
+
+    case cGetMaximumAccessibleValueFromContextPackage:
+        PrintDebugString("   type == cGetMaximumAccessibleValueFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage))) {
+            GetMaximumAccessibleValueFromContextPackage *pkg =
+                (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getMaximumAccessibleValueFromContext((jobject)pkg->AccessibleContext,
+                                                                           (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage));
+        }
+        break;
+
+    case cGetMinimumAccessibleValueFromContextPackage:
+        PrintDebugString("   type == cGetMinimumAccessibleValueFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage))) {
+            GetMinimumAccessibleValueFromContextPackage *pkg =
+                (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->getMinimumAccessibleValueFromContext((jobject)pkg->AccessibleContext,
+                                                                           (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t)));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage));
+        }
+        break;
+
+        // ------------ Accessible Selection packages ------------------
+
+    case cAddAccessibleSelectionFromContextPackage:
+        PrintDebugString("   type == cAddAccessibleSelectionFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage))) {
+            AddAccessibleSelectionFromContextPackage *pkg =
+                (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->addAccessibleSelectionFromContext((jobject)pkg->AccessibleContext,
+                                                                        pkg->index);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage));
+        }
+        break;
+
+    case cClearAccessibleSelectionFromContextPackage:
+        PrintDebugString("   type == cClearAccessibleSelectionFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage))) {
+            ClearAccessibleSelectionFromContextPackage *pkg =
+                (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->clearAccessibleSelectionFromContext((jobject)pkg->AccessibleContext);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage));
+        }
+        break;
+
+    case cGetAccessibleSelectionFromContextPackage:
+        PrintDebugString("   type == cGetAccessibleSelectionFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage))) {
+            GetAccessibleSelectionFromContextPackage *pkg =
+                (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
+            pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleSelectionFromContext(
+                                                                                                  (jobject)pkg->AccessibleContext, pkg->index);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage));
+        }
+        break;
+
+    case cGetAccessibleSelectionCountFromContextPackage:
+        PrintDebugString("   type == cGetAccessibleSelectionCountFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage))) {
+            GetAccessibleSelectionCountFromContextPackage *pkg =
+                (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType));
+            pkg->rCount = windowsThreadEntryPoints->getAccessibleSelectionCountFromContext(
+                                                                                           (jobject)pkg->AccessibleContext);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage));
+        }
+        break;
+
+    case cIsAccessibleChildSelectedFromContextPackage:
+        PrintDebugString("   type == cIsAccessibleChildSelectedFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage))) {
+            IsAccessibleChildSelectedFromContextPackage *pkg =
+                (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType));
+            pkg->rResult = windowsThreadEntryPoints->isAccessibleChildSelectedFromContext(
+                                                                                          (jobject)pkg->AccessibleContext, pkg->index);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage));
+        }
+        break;
+
+    case cRemoveAccessibleSelectionFromContextPackage:
+        PrintDebugString("   type == cRemoveAccessibleSelectionFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage))) {
+            RemoveAccessibleSelectionFromContextPackage *pkg =
+                (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->removeAccessibleSelectionFromContext((jobject)pkg->AccessibleContext,
+                                                                           pkg->index);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage));
+        }
+        break;
+
+    case cSelectAllAccessibleSelectionFromContextPackage:
+        PrintDebugString("   type == cSelectAllAccessibleSelectionFromContextPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage))) {
+            SelectAllAccessibleSelectionFromContextPackage *pkg =
+                (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType));
+            windowsThreadEntryPoints->selectAllAccessibleSelectionFromContext((jobject)pkg->AccessibleContext);
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage));
+        }
+        break;
+
+
+        // ------------ event notification management packages ------------------
+
+    case cAddJavaEventNotificationPackage:
+        PrintDebugString("   type = cAddJavaEventNotificationPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage))) {
+            AddJavaEventNotificationPackage *pkg =
+                (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
+            addJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ) );
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage));
+        }
+        break;
+
+    case cRemoveJavaEventNotificationPackage:
+        PrintDebugString("   type = cRemoveJavaEventNotificationPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage))) {
+            RemoveJavaEventNotificationPackage *pkg =
+                (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType));
+            removeJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage));
+        }
+        break;
+
+    case cAddAccessibilityEventNotificationPackage:
+        PrintDebugString("   type = cAddAccessibilityEventNotificationPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage))) {
+            AddAccessibilityEventNotificationPackage *pkg =
+                (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
+            addAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage));
+        }
+        break;
+
+    case cRemoveAccessibilityEventNotificationPackage:
+        PrintDebugString("   type = cRemoveAccessibilityEventNotificationPackage");
+        if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage))) {
+            RemoveAccessibilityEventNotificationPackage *pkg =
+                (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType));
+            removeAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow));
+        } else {
+            PrintDebugString("   processing FAILED!! -> bufsize = %d; expectation = %d",
+                             bufsize, sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage));
+        }
+        break;
+
+    default:
+        PrintDebugString("   processing FAILED!! -> don't know how to handle type = %X", *type);
+        returnVal = -1;
+        break;
+    }
+
+    PrintDebugString("   package processing completed");
+    return returnVal;
+}
+
+
+// -----------------------------
+
+
+/**
+ * MemoryMappedFileCreated
+ *          - WindowsDLL letting us know it's created a memory-mapped file
+ *            for IPC.  We need to open it and write a magic string into
+ *            it to let the WindowsDLL know all is OK.  Also we need to
+ *            set up our own data structures to communicate with the
+ *            WindowsDLL
+ *
+ */
+LRESULT
+JavaAccessBridge::MemoryMappedFileCreated(HWND ATBridgeDLLWindow, char *filename) {
+    PrintDebugString("  in MemoryMappedFileCreated(%p, %s)!", ATBridgeDLLWindow, filename);
+    AccessBridgeATInstance *newAT =
+        new AccessBridgeATInstance(dialogWindow, ATBridgeDLLWindow, filename, ATs);
+    PrintDebugString("    just created a new ATInstance = %p, old = %p", newAT, ATs);
+    ATs = newAT;
+
+    LRESULT returnVal = ATs->initiateIPC();
+    if (returnVal == 0) {
+        PrintDebugString("  Successfully initiated IPC with AT!!!");
+    } else {
+        PrintDebugString("  ERROR: Failed to initiate IPC with AT!!!");
+    }
+
+    return returnVal;
+}
+
+
+/**
+ * WindowsATDestroyed - lets the JavaABDLL know a Windows AT disappeared
+ *
+ */
+void
+JavaAccessBridge::WindowsATDestroyed(HWND ATBridgeDLLWindow) {
+    PrintDebugString("\r\nin JavaAccessBridge::WindowsATDestroyed(%p)", ATBridgeDLLWindow);
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! -> ATs == 0! (shouldn't happen here)");
+        return;
+    }
+
+    AccessBridgeATInstance *currentAT = ATs;
+    AccessBridgeATInstance *previousAT = ATs;
+    if (ATs->winAccessBridgeWindow == ATBridgeDLLWindow) {
+        ATs = ATs->nextATInstance;
+        // remove event notification for this AT
+        removeJavaEventNotification(currentAT->javaEventMask, ATBridgeDLLWindow);
+        removeAccessibilityEventNotification(currentAT->accessibilityEventMask, ATBridgeDLLWindow);
+        delete currentAT;
+        PrintDebugString("  data structures successfully removed");
+    } else {
+        while (currentAT != (AccessBridgeATInstance *) NULL) {
+            if (currentAT->winAccessBridgeWindow == ATBridgeDLLWindow) {
+                previousAT->nextATInstance = currentAT->nextATInstance;
+                delete currentAT;
+                PrintDebugString("  data structures successfully removed");
+                return;
+            } else {
+                previousAT = currentAT;
+                currentAT = currentAT->nextATInstance;
+            }
+        }
+        PrintDebugString("  ERROR!! couldn't find matching data structures!");
+    }
+}
+
+
+// -----------------------------
+
+
+/**
+ * releaseJavaObject - lets the JavaVM know it can release the Java Object
+ *
+ * Note: once you have made this call, the JavaVM will garbage collect
+ * the jobject you pass in.  If you later use that jobject in another
+ * call, you will cause all maner of havoc!
+ *
+ */
+void
+JavaAccessBridge::releaseJavaObject(jobject object) {
+    PrintDebugString("In JavaAccessBridge::releaseJavaObject");
+    PrintDebugString("  object X: %p", object);
+    if (windowsThreadJNIEnv != (JNIEnv *) 0) {
+        windowsThreadJNIEnv->DeleteGlobalRef(object);
+        PrintDebugString("  global reference deleted.", object);
+    } else {
+        PrintDebugString("  Error! windowsThreadJNIEnv == 0");
+    }
+}
+
+// -----------------------------
+
+/**
+ * addJavaEventNotification - this AT now wants this type of events
+ *
+ */
+void
+JavaAccessBridge::addJavaEventNotification(jlong type, HWND DLLwindow) {
+    // walk through list of ATs, find this one and add this type
+    // and, if we weren't listening for these before, ask Java for 'em
+    PrintDebugString("  adding Java event type %016I64X to HWND %p", type, DLLwindow);
+    AccessBridgeATInstance *ati = ATs;
+    long globalEventMask = 0;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->winAccessBridgeWindow == DLLwindow) {
+            ati->javaEventMask |= type;
+            PrintDebugString("  found HWND, javaEventMask now is %X", ati->javaEventMask);
+        } else {
+            globalEventMask |= ati->javaEventMask;
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  union of all Java AT event masks: %X", globalEventMask);
+    if (!(globalEventMask & type)) {
+        // no other ATs wanted this event;
+        // start getting them from Java
+        PrintDebugString("  no other AT wanted this Java event (so not registered); adding to AccessBridge.java");
+        windowsThreadEntryPoints->addJavaEventNotification(type);
+    }
+}
+
+/**
+ * removeJavaEventNotification - this AT no longer wants this type of events
+ *
+ */
+void
+JavaAccessBridge::removeJavaEventNotification(jlong type, HWND DLLwindow) {
+    // walk through list of ATs, find this one and remove this type
+    // and, if no other AT wants 'em either, tell Java we no longer want 'em
+    PrintDebugString("  removing Java event type %016I64X from HWND %p", type, DLLwindow);
+    AccessBridgeATInstance *ati = ATs;
+    long globalEventMask = 0;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->winAccessBridgeWindow == DLLwindow) {
+            ati->javaEventMask &= (0xFFFFFFFF - type);
+            PrintDebugString("  found HWND, javaEventMask now is %X", ati->javaEventMask);
+        } else {
+            globalEventMask |= ati->javaEventMask;
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  union of all Java AT event masks: %X", globalEventMask);
+    if (!(globalEventMask & type)) {
+        // no other ATs wanted this event;
+        // stop getting them from Java
+        PrintDebugString("  no other AT wanted this Java event (so can remove); removing from AccessBridge.java");
+        windowsThreadEntryPoints->removeJavaEventNotification(type);
+    }
+}
+
+
+/**
+ * addAccesibilityEventNotification - this AT now wants this type of events
+ *
+ */
+void
+JavaAccessBridge::addAccessibilityEventNotification(jlong type, HWND DLLwindow) {
+    // walk through list of ATs, find this one and add this type
+    // and, if we weren't listening for these before, ask Java for 'em
+    PrintDebugString("  adding Accesibility event type %016I64X to HWND %p", type, DLLwindow);
+    AccessBridgeATInstance *ati = ATs;
+    long globalEventMask = 0;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->winAccessBridgeWindow == DLLwindow) {
+            ati->accessibilityEventMask |= type;
+            PrintDebugString("  found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
+        } else {
+            globalEventMask |= ati->accessibilityEventMask;
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  union of all Accessibility AT event masks: %X", globalEventMask);
+    if (!(globalEventMask & type)) {
+        // no other ATs wanted this event;
+        // start getting them from Java
+        PrintDebugString("  no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java");
+        windowsThreadEntryPoints->addAccessibilityEventNotification(type);
+    }
+}
+
+/**
+ * removeAccesibilityEventNotification - this AT no longer wants this type of events
+ *
+ */
+void
+JavaAccessBridge::removeAccessibilityEventNotification(jlong type, HWND DLLwindow) {
+    // walk through list of ATs, find this one and remove this type
+    // and, if no other AT wants 'em either, tell Java we no longer want 'em
+    PrintDebugString("  removing Accesibility event type %016I64X from HWND %p", type, DLLwindow);
+    AccessBridgeATInstance *ati = ATs;
+    long globalEventMask = 0;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->winAccessBridgeWindow == DLLwindow) {
+            ati->accessibilityEventMask &= (0xFFFFFFFF - type);
+            PrintDebugString("  found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask);
+        } else {
+            globalEventMask |= ati->accessibilityEventMask;
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  union of all Accessibility AT event masks: %X", globalEventMask);
+    if (!(globalEventMask & type)) {
+        // no other ATs wanted this event;
+        // stop getting them from Java
+        PrintDebugString("  no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java");
+        windowsThreadEntryPoints->removeAccessibilityEventNotification(type);
+    }
+}
+
+
+
+
+/**
+ * firePropertyCaretChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyCaretChange(JNIEnv *env, jobject callingObj,
+                                          jobject event, jobject source,
+                                          jint oldValue, jint newValue) {
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)",
+                     env, callingObj, event,
+                     source, oldValue, newValue);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    char buffer[sizeof(PackageType) + sizeof(PropertyCaretChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyCaretChangePackage *pkg = (PropertyCaretChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyCaretChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            pkg->oldPosition = oldValue;
+            pkg->newPosition = newValue;
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyCaretChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyCaretChange event");
+}
+
+/**
+ * firePropertyDescriptionChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyDescriptionChange(JNIEnv *env, jobject callingObj,
+                                                jobject event, jobject source,
+                                                jstring oldValue, jstring newValue){
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)",
+                     env, callingObj, event,
+                     source, oldValue, newValue);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    const wchar_t *stringBytes;
+    char buffer[sizeof(PackageType) + sizeof(PropertyDescriptionChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyDescriptionChangePackage *pkg = (PropertyDescriptionChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyDescriptionChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            if (oldValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->oldDescription, stringBytes, (sizeof(pkg->oldDescription) / sizeof(wchar_t)));
+                env->ReleaseStringChars(oldValue, stringBytes);
+            } else {
+                wcsncpy(pkg->oldDescription, L"(null)", (sizeof(pkg->oldDescription) / sizeof(wchar_t)));
+            }
+
+            if (newValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
+                if (stringBytes == NULL) {
+                   if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->newDescription, stringBytes, (sizeof(pkg->newDescription) / sizeof(wchar_t)));
+                env->ReleaseStringChars(newValue, stringBytes);
+            } else {
+                wcsncpy(pkg->newDescription, L"(null)", (sizeof(pkg->newDescription) / sizeof(wchar_t)));
+            }
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyDescriptionChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyDescriptionChange event");
+}
+
+/**
+ * firePropertyNameChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyNameChange(JNIEnv *env, jobject callingObj,
+                                         jobject event, jobject source,
+                                         jstring oldValue, jstring newValue){
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)",
+                     env, callingObj, event,
+                     source, oldValue, newValue);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    const wchar_t *stringBytes;
+    char buffer[sizeof(PackageType) + sizeof(PropertyNameChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyNameChangePackage *pkg = (PropertyNameChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyNameChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyNameChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            if (oldValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->oldName, stringBytes, (sizeof(pkg->oldName) / sizeof(wchar_t)));
+                env->ReleaseStringChars(oldValue, stringBytes);
+            } else {
+                wcsncpy(pkg->oldName, L"(null)", (sizeof(pkg->oldName) / sizeof(wchar_t)));
+            }
+
+            if (newValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->newName, stringBytes, (sizeof(pkg->newName) / sizeof(wchar_t)));
+                env->ReleaseStringChars(newValue, stringBytes);
+            } else {
+                wcsncpy(pkg->newName, L"(null)", (sizeof(pkg->newName) / sizeof(wchar_t)));
+            }
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyNameChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyNameChange event");
+}
+
+
+/**
+ * firePropertySelectionChange
+ *
+ */
+void
+JavaAccessBridge::firePropertySelectionChange(JNIEnv *env, jobject callingObj,
+                                              jobject event, jobject source) {
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)",
+                     env, callingObj, event, source);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    char buffer[sizeof(PackageType) + sizeof(PropertySelectionChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertySelectionChangePackage *pkg = (PropertySelectionChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertySelectionChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertySelectionChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertySelectionChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertySelectionChange event");
+}
+
+
+/**
+ * firePropertyStateChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyStateChange(JNIEnv *env, jobject callingObj,
+                                          jobject event, jobject source,
+                                          jstring oldValue, jstring newValue){
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)",
+                     env, callingObj, event,
+                     source, oldValue, newValue);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    const wchar_t *stringBytes;
+    char buffer[sizeof(PackageType) + sizeof(PropertyStateChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyStateChangePackage *pkg = (PropertyStateChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyStateChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyStateChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            if (oldValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->oldState, stringBytes, (sizeof(pkg->oldState) / sizeof(wchar_t)));
+                env->ReleaseStringChars(oldValue, stringBytes);
+            } else {
+                wcsncpy(pkg->oldState, L"(null)", (sizeof(pkg->oldState) / sizeof(wchar_t)));
+            }
+
+            if (newValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->newState, stringBytes, (sizeof(pkg->newState) / sizeof(wchar_t)));
+                env->ReleaseStringChars(newValue, stringBytes);
+            } else {
+                wcsncpy(pkg->newState, L"(null)", (sizeof(pkg->newState) / sizeof(wchar_t)));
+            }
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyStateChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyStateChange event");
+}
+
+
+/**
+ * firePropertyTextChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyTextChange(JNIEnv *env, jobject callingObj,
+                                         jobject event, jobject source) {
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%p, %p, %p, %p)",
+                     env, callingObj, event, source);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    char buffer[sizeof(PackageType) + sizeof(PropertyTextChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyTextChangePackage *pkg = (PropertyTextChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyTextChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyTextChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTextChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyTextChange event");
+}
+
+
+/**
+ * firePropertyValueChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyValueChange(JNIEnv *env, jobject callingObj,
+                                          jobject event, jobject source,
+                                          jstring oldValue, jstring newValue){
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)",
+                     env, callingObj, event,
+                     source, oldValue, newValue);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    const wchar_t *stringBytes;
+    char buffer[sizeof(PackageType) + sizeof(PropertyValueChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyValueChangePackage *pkg = (PropertyValueChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyValueChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyValueChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            if (oldValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t)));
+                env->ReleaseStringChars(oldValue, stringBytes);
+            } else {
+                wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t)));
+            }
+
+            if (newValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t)));
+                env->ReleaseStringChars(newValue, stringBytes);
+            } else {
+                wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t)));
+            }
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyValueChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyValueChange event");
+}
+
+/**
+ * firePropertyVisibleDataChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj,
+                                                jobject event, jobject source) {
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)",
+                     env, callingObj, event, source);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    char buffer[sizeof(PackageType) + sizeof(PropertyVisibleDataChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyVisibleDataChangePackage *pkg = (PropertyVisibleDataChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyVisibleDataChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyVisibleDataChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyVisibleDataChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyVisibleDataChange event");
+}
+
+
+/**
+ * firePropertyChildChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyChildChange(JNIEnv *env, jobject callingObj,
+                                          jobject event, jobject source,
+                                          jobject oldValue, jobject newValue){
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)",
+                     env, callingObj, event,
+                     source, oldValue, newValue);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    char buffer[sizeof(PackageType) + sizeof(PropertyChildChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyChildChangePackage *pkg = (PropertyChildChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyChildChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyChildChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+            pkg->oldChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue);
+            pkg->newChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("  GlobalRef'd OldChildAC: %p", pkg->oldChildAccessibleContext);
+            PrintDebugString("  GlobalRef'd NewChildAC: %p", pkg->newChildAccessibleContext);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("  GlobalRef'd OldChildAC: %016I64X", pkg->oldChildAccessibleContext);
+            PrintDebugString("  GlobalRef'd NewChildAC: %016I64X", pkg->newChildAccessibleContext);
+#endif
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyChildChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyChildChange event");
+}
+
+
+/**
+ * firePropertyActiveDescendentChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyActiveDescendentChange(JNIEnv *env, jobject callingObj,
+                                                     jobject event, jobject source,
+                                                     jobject oldValue, jobject newValue){
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)",
+                     env, callingObj, event,
+                     source, oldValue, newValue);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    char buffer[sizeof(PackageType) + sizeof(PropertyActiveDescendentChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyActiveDescendentChangePackage *pkg = (PropertyActiveDescendentChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyActiveDescendentChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyActiveDescendentChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+            pkg->oldActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue);
+            pkg->newActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+            PrintDebugString("  GlobalRef'd OldActiveDescendentAC: %p", pkg->oldActiveDescendentAccessibleContext);
+            PrintDebugString("  GlobalRef'd NewActiveDescendentAC: %p", pkg->newActiveDescendentAccessibleContext);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+            PrintDebugString("  GlobalRef'd OldActiveDescendentAC: %016I64X", pkg->oldActiveDescendentAccessibleContext);
+            PrintDebugString("  GlobalRef'd NewActiveDescendentAC: %016I64X", pkg->newActiveDescendentAccessibleContext);
+#endif
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyActiveDescendentChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyActiveChange event");
+}
+
+/**
+ * firePropertyValueChange
+ *
+ */
+void
+JavaAccessBridge::firePropertyTableModelChange(JNIEnv *env, jobject callingObj,
+                                               jobject event, jobject source,
+                                               jstring oldValue, jstring newValue){
+
+    PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)",
+                     env, callingObj, event,
+                     source, oldValue, newValue);
+
+    // sanity check
+    if (ATs == (AccessBridgeATInstance *) 0) {
+        PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+        return;         // panic!
+    }
+
+    // common setup
+    const wchar_t *stringBytes;
+    char buffer[sizeof(PackageType) + sizeof(PropertyTableModelChangePackage)];
+    PackageType *type = (PackageType *) buffer;
+    PropertyTableModelChangePackage *pkg = (PropertyTableModelChangePackage *) (buffer + sizeof(PackageType));
+    *type = cPropertyTableModelChangePackage;
+    pkg->vmID = (long) dialogWindow;
+
+    // make new Global Refs and send events only to those ATs that want 'em
+    AccessBridgeATInstance *ati = ATs;
+    while (ati != (AccessBridgeATInstance *) 0) {
+        if (ati->accessibilityEventMask & cPropertyTableModelChangeEvent) {
+
+            PrintDebugString("  sending to AT");
+
+            // make new GlobalRefs for this AT
+            pkg->Event = (JOBJECT64)env->NewGlobalRef(event);
+            pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+            PrintDebugString("  GlobalRef'd Event: %p", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+            PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event);
+            PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+            if (oldValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t)));
+                env->ReleaseStringChars(oldValue, stringBytes);
+            } else {
+                wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t)));
+            }
+
+            if (newValue != (jstring) 0) {
+                stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0);
+                if (stringBytes == NULL) {
+                    if (!env->ExceptionCheck()) {
+                        jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                        if (cls != NULL) {
+                            env->ThrowNew(cls, NULL);
+                        }
+                    }
+                    return;
+                }
+                wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t)));
+                env->ReleaseStringChars(newValue, stringBytes);
+            } else {
+                wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t)));
+            }
+
+            ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTableModelChangeEvent);
+        }
+        ati = ati->nextATInstance;
+    }
+    PrintDebugString("  done with propertyTableModelChange event");
+}
+
+
+
+#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
+#define PRINT_GLOBALREFS() \
+    PrintDebugString("  GlobalRef'd Event: %p", pkg->Event); \
+    PrintDebugString("  GlobalRef'd Source: %p", pkg->AccessibleContextSource);
+#else // JOBJECT64 is jlong (64 bit)
+#define PRINT_GLOBALREFS() \
+    PrintDebugString("  GlobalRef'd Event: %016I64X", pkg->Event); \
+    PrintDebugString("  GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource);
+#endif
+
+#define FIRE_EVENT(function, packageStruct, packageConstant, eventConstant)             \
+    void JavaAccessBridge::function(JNIEnv *env, jobject callingObj,                    \
+                                    jobject eventObj, jobject source) {                 \
+                                                                                        \
+        PrintDebugString("\r\nFiring event id = %d(%p, %p, %p, %p); vmID = %X",         \
+                         eventConstant, env, callingObj, eventObj, source, javaVM);     \
+                                                                                        \
+        /* sanity check */                                                              \
+        if (ATs == (AccessBridgeATInstance *) 0) {                                      \
+            PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");           \
+            return;         /* panic! */                                                \
+        }                                                                               \
+                                                                                        \
+        /* common setup */                                                              \
+        char buffer[sizeof(PackageType) + sizeof(packageStruct)];                       \
+        PackageType *type = (PackageType *) buffer;                                     \
+        packageStruct *pkg = (packageStruct *) (buffer + sizeof(PackageType));          \
+        *type = packageConstant;                                                        \
+        pkg->vmID = (long) dialogWindow;                                                \
+                                                                                        \
+        /* make new Global Refs, send events only to those ATs that want 'em */         \
+        AccessBridgeATInstance *ati = ATs;                                              \
+        while (ati != (AccessBridgeATInstance *) 0) {                                   \
+            PrintDebugString("\r\njavaEventMask = %X eventConstant=%d pkg->vmID=%X",    \
+                             ati->javaEventMask, eventConstant, pkg->vmID );            \
+            if (ati->javaEventMask & eventConstant) {                                   \
+                                                                                        \
+                PrintDebugString("  sending to AT");                                    \
+                /* make new GlobalRefs for this AT */                                   \
+                pkg->Event = (JOBJECT64)env->NewGlobalRef(eventObj);                    \
+                pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source);    \
+                PRINT_GLOBALREFS()                                                      \
+                                                                                        \
+                ati->sendJavaEventPackage(buffer, sizeof(buffer), eventConstant);       \
+            }                                                                           \
+            ati = ati->nextATInstance;                                                  \
+        }                                                                               \
+        PrintDebugString("  done with firing AWT event");                               \
+    }
+
+    void JavaAccessBridge::javaShutdown(JNIEnv *env, jobject callingObj) {
+
+        PrintDebugString("\r\nFiring event id = %d(%p, %p); vmID = %X",
+                         cJavaShutdownEvent, env, callingObj, javaVM);
+
+        /* sanity check */
+        if (ATs == (AccessBridgeATInstance *) 0) {
+            PrintDebugString("  ERROR!! ATs == 0! (shouldn't happen here!)");
+            return;             /* panic! */
+        }
+
+        /* common setup */
+        char buffer[sizeof(PackageType) + sizeof(JavaShutdownPackage)];
+        PackageType *type = (PackageType *) buffer;
+        JavaShutdownPackage *pkg = (JavaShutdownPackage *) (buffer + sizeof(PackageType));
+        *type = cJavaShutdownPackage;
+        pkg->vmID = (long) dialogWindow;
+
+        /* make new Global Refs, send events only to those ATs that want 'em */
+        AccessBridgeATInstance *ati = ATs;
+        while (ati != (AccessBridgeATInstance *) 0) {
+            if (ati->javaEventMask & cJavaShutdownEvent) {
+                PrintDebugString("  sending to AT");
+                ati->sendJavaEventPackage(buffer, sizeof(buffer), cJavaShutdownEvent);
+            }
+            ati = ati->nextATInstance;
+        }
+        PrintDebugString("  done with firing AWT event");
+    }
+
+    FIRE_EVENT(fireFocusGained, FocusGainedPackage, cFocusGainedPackage, cFocusGainedEvent)
+    FIRE_EVENT(fireFocusLost, FocusLostPackage, cFocusLostPackage, cFocusLostEvent)
+    FIRE_EVENT(fireCaretUpdate, CaretUpdatePackage, cCaretUpdatePackage, cCaretUpdateEvent)
+    FIRE_EVENT(fireMouseClicked, MouseClickedPackage, cMouseClickedPackage, cMouseClickedEvent)
+    FIRE_EVENT(fireMouseEntered, MouseEnteredPackage, cMouseEnteredPackage, cMouseEnteredEvent)
+    FIRE_EVENT(fireMouseExited, MouseExitedPackage, cMouseExitedPackage, cMouseExitedEvent)
+    FIRE_EVENT(fireMousePressed, MousePressedPackage, cMousePressedPackage, cMousePressedEvent)
+    FIRE_EVENT(fireMouseReleased, MouseReleasedPackage, cMouseReleasedPackage, cMouseReleasedEvent)
+    FIRE_EVENT(fireMenuCanceled, MenuCanceledPackage, cMenuCanceledPackage, cMenuCanceledEvent)
+    FIRE_EVENT(fireMenuDeselected, MenuDeselectedPackage, cMenuDeselectedPackage, cMenuDeselectedEvent)
+    FIRE_EVENT(fireMenuSelected, MenuSelectedPackage, cMenuSelectedPackage, cMenuSelectedEvent)
+    FIRE_EVENT(firePopupMenuCanceled, PopupMenuCanceledPackage, cPopupMenuCanceledPackage, cPopupMenuCanceledEvent)
+    FIRE_EVENT(firePopupMenuWillBecomeInvisible, PopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisibleEvent)
+    FIRE_EVENT(firePopupMenuWillBecomeVisible, PopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisibleEvent)
+
+
+    // -----------------------------
+
+
+extern "C" {        // event stuff from AccessBridge.h, generated by JNI
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_sendDebugString(JNIEnv *env, jobject callingObj, jstring debugStr) {
+
+        const wchar_t *stringBytes;
+        stringBytes = (const wchar_t *) env->GetStringChars(debugStr, 0);
+        if (stringBytes == NULL) {
+            if (!env->ExceptionCheck()) {
+                jclass cls = env->FindClass("java/lang/OutOfMemoryError");
+                if (cls != NULL) {
+                    env->ThrowNew(cls, NULL);
+                }
+            }
+            return;
+        }
+        wPrintJavaDebugString(L"AccessBridge.java: %ls", stringBytes);
+        env->ReleaseStringChars(debugStr, stringBytes);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyCaretChange(JNIEnv *env, jobject callingObj,
+                                                                        jobject event, jobject source,
+                                                                        jint oldValue, jint newValue) {
+        theJavaAccessBridge->firePropertyCaretChange(env, callingObj,
+                                                        event, source,
+                                                        oldValue, newValue);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyDescriptionChange(JNIEnv *env, jobject callingObj,
+                                                                            jobject event, jobject source,
+                                                                            jstring oldValue, jstring newValue) {
+        theJavaAccessBridge->firePropertyDescriptionChange(env, callingObj,
+                                                            event, source,
+                                                            oldValue, newValue);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyNameChange(JNIEnv *env, jobject callingObj,
+                                                                    jobject event, jobject source,
+                                                                    jstring oldValue, jstring newValue) {
+        theJavaAccessBridge->firePropertyNameChange(env, callingObj,
+                                                    event, source,
+                                                    oldValue, newValue);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertySelectionChange(JNIEnv *env, jobject callingObj,
+                                                                            jobject event, jobject source) {
+        theJavaAccessBridge->firePropertySelectionChange(env, callingObj,
+                                                            event, source);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyStateChange(JNIEnv *env, jobject callingObj,
+                                                                        jobject event, jobject source,
+                                                                        jstring oldValue, jstring newValue) {
+        theJavaAccessBridge->firePropertyStateChange(env, callingObj,
+                                                        event, source,
+                                                        oldValue, newValue);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyTextChange(JNIEnv *env, jobject callingObj,
+                                                                    jobject event,  jobject source) {
+        theJavaAccessBridge->firePropertyTextChange(env, callingObj,
+                                                    event, source);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyValueChange(JNIEnv *env, jobject callingObj,
+                                                                        jobject event, jobject source,
+                                                                        jstring oldValue, jstring newValue) {
+        theJavaAccessBridge->firePropertyValueChange(env, callingObj,
+                                                        event, source,
+                                                        oldValue, newValue);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChange(JNIEnv *env, jobject callingObj,
+                                                                            jobject event,  jobject source) {
+        theJavaAccessBridge->firePropertyVisibleDataChange(env, callingObj,
+                                                            event, source);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyChildChange(JNIEnv *env, jobject callingObj,
+                                                                        jobject event, jobject source,
+                                                                        jobject oldValue, jobject newValue) {
+        theJavaAccessBridge->firePropertyChildChange(env, callingObj,
+                                                        event, source,
+                                                        oldValue, newValue);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentChange(JNIEnv *env, jobject callingObj,
+                                                                                jobject event,  jobject source,
+                                                                                jobject oldValue,
+                                                                                jobject newValue) {
+        theJavaAccessBridge->firePropertyActiveDescendentChange(env, callingObj,
+                                                                event, source,
+                                                                oldValue, newValue);
+    }
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(JNIEnv *env, jobject callingObj,
+                                                                            jobject event,  jobject source,
+                                                                            jstring oldValue, jstring newValue) {
+
+        theJavaAccessBridge->firePropertyTableModelChange(env, callingObj,
+                                                            event, source,
+                                                            oldValue, newValue);
+    }
+
+#define HANDLE_STANDARD_EVENT_FROM_JAVA(function, method) \
+    JNIEXPORT void JNICALL \
+    function(JNIEnv *env, jobject callingObj, jobject event, jobject source) { \
+        theJavaAccessBridge->method(env, callingObj, event, source); \
+    }
+
+
+    JNIEXPORT void JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_javaShutdown(JNIEnv *env, jobject callingObj) {
+        theJavaAccessBridge->javaShutdown(env, callingObj);
+    }
+
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusGained, fireFocusGained)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusLost, fireFocusLost)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_caretUpdate, fireCaretUpdate)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseClicked, fireMouseClicked)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseEntered, fireMouseEntered)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseExited, fireMouseExited)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mousePressed, fireMousePressed)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseReleased, fireMouseReleased)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuCanceled, fireMenuCanceled)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuDeselected, fireMenuDeselected)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuSelected, fireMenuSelected)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuCanceled, firePopupMenuCanceled)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeInvisible, firePopupMenuWillBecomeInvisible)
+    HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeVisible, firePopupMenuWillBecomeVisible)
+
+    /*
+     * Map a HWND to a Java component
+     *
+     * Class:     com_sun_java_accessibility_AccessBridge
+     * Method:    jawtGetComponentFromNativeWindowHandle
+     * Signature: (I)Ljava/awt/Component;
+     */
+    JNIEXPORT jobject JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_jawtGetComponentFromNativeWindowHandle
+        (JNIEnv *env, jobject callingObj, jint windowHandle) {
+
+    JAWT awt;
+    jboolean result;
+    jobject component = (jobject)0;
+
+    // Get the AWT
+    awt.version = JAWT_VERSION_1_4;
+    result = JAWT_GetAWT(env, &awt);
+    if (result == JNI_FALSE) {
+        return (jobject)0;
+    }
+
+    // Get the component
+    return awt.GetComponent(env, (void *)windowHandle);
+    }
+
+
+    /*
+     * Map a Java component to a HWND
+     *
+     * Class:     com_sun_java_accessibility_AccessBridge
+     * Method:    jawtGetNativeWindowHandleFromComponent
+     * Signature: (Ljava/awt/Component;)I
+     */
+    JNIEXPORT jint JNICALL
+    Java_com_sun_java_accessibility_AccessBridge_jawtGetNativeWindowHandleFromComponent
+        (JNIEnv *env, jobject callingObj, jobject component) {
+
+        JAWT awt;
+        JAWT_DrawingSurface* ds;
+        JAWT_DrawingSurfaceInfo* dsi;
+        JAWT_Win32DrawingSurfaceInfo* dsi_win;
+        jboolean result;
+        // jint lock;
+        jint windowHandle = -1;
+
+        // Get the AWT
+        awt.version = JAWT_VERSION_1_4;
+        result = JAWT_GetAWT(env, &awt);
+        if (result == JNI_FALSE) {
+            return -1;
+        }
+
+        // Get the drawing surface
+        ds = awt.GetDrawingSurface(env, component);
+        if (ds == NULL) {
+            return -1;
+        }
+
+        // Get the drawing surface info
+        dsi = ds->GetDrawingSurfaceInfo(ds);
+
+        // Get the platform-specific drawing info
+        dsi_win = (JAWT_Win32DrawingSurfaceInfo *)dsi->platformInfo;
+
+        // Get the window handle
+        windowHandle = (jint)dsi_win->hwnd;
+
+        // Free the drawing surface info
+        ds->FreeDrawingSurfaceInfo(dsi);
+
+        // Free the drawing surface
+        awt.FreeDrawingSurface(ds);
+
+        return windowHandle;
+    }
+
+}