8056925: Add jaccessinspector and jaccesswalker to the bin directory
authorptbrunet
Fri, 20 Nov 2015 17:54:58 -0600
changeset 34411 b46324665539
parent 34410 f64d80c2e4d7
child 34412 bed825be8cd8
8056925: Add jaccessinspector and jaccesswalker to the bin directory Summary: Add jaccessinspector, jaccesswalker to jdk.accessibility module; update launcher in make Reviewed-by: erikj, van, prr Contributed-by: peter.brunet@oracle.com
jdk/make/launcher/Launcher-jdk.accessibility.gmk
jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.cpp
jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.h
jdk/src/jdk.accessibility/windows/native/jaccessinspector/MessageHistory.cpp
jdk/src/jdk.accessibility/windows/native/jaccessinspector/MessageHistory.h
jdk/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.cpp
jdk/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.h
jdk/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorResource.h
jdk/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorWindow.rc
jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp
jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.h
jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerResource.h
jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerWindow.rc
jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp
jdk/src/jdk.accessibility/windows/native/toolscommon/AccessInfo.cpp
jdk/src/jdk.accessibility/windows/native/toolscommon/AccessInfo.h
--- a/jdk/make/launcher/Launcher-jdk.accessibility.gmk	Fri Nov 20 16:44:33 2015 +0400
+++ b/jdk/make/launcher/Launcher-jdk.accessibility.gmk	Fri Nov 20 17:54:58 2015 -0600
@@ -56,6 +56,77 @@
   ))
 
   TARGETS += $(BUILD_JABSWITCH)
+
+################################################################################
+# jaccessinspector
+
+  TOPDIR := $(JDK_TOPDIR)/src/jdk.accessibility/windows/native
+  TOOLS_CFLAGS := $(addprefix -I, \
+      $(TOPDIR)/include/bridge \
+      $(TOPDIR)/common \
+      $(TOPDIR)/toolscommon)
+
+  define SetupInspector
+  # Parameter 1 File name suffix
+  # Parameter 2 ACCESSBRIDGE_ARCH_ -D suffix
+
+    $$(eval $$(call SetupNativeCompilation, BUILD_JACCESSINSPECTOR$1, \
+      SRC := $(TOPDIR)/jaccessinspector $(TOPDIR)/common \
+          $(TOPDIR)/toolscommon $(TOPDIR)/include/bridge, \
+      CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 /EHsc, \
+      LDFLAGS := $$(LDFLAGS_JDKEXE) /STACK:655360 Advapi32.lib User32.lib, \
+      OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccessinspector$1, \
+      OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
+      PROGRAM := jaccessinspector$1, \
+      DEBUG_SYMBOLS := true, \
+      VERSIONINFO_RESOURCE := $(TOPDIR)/jaccessinspector/jaccessinspectorWindow.rc, \
+      RC_FLAGS := $$(RC_FLAGS) \
+          -D "JDK_FNAME=jaccessinspector$1.exe" \
+          -D "JDK_INTERNAL_NAME=jaccessinspector$1" \
+          -D "JDK_FTYPE=0x01L", \
+    ))
+
+    TARGETS += $$(BUILD_JACCESSINSPECTOR$1)
+
+  endef
+
+################################################################################
+# jaccesswalker
+
+  define SetupWalker
+  # Parameter 1 File name suffix
+  # Parameter 2 ACCESSBRIDGE_ARCH_ -D suffix
+
+    $$(eval $$(call SetupNativeCompilation,BUILD_JACCESSWALKER$1, \
+      SRC := $(TOPDIR)/jaccesswalker $(TOPDIR)/common \
+          $(TOPDIR)/toolscommon $(TOPDIR)/include/bridge, \
+      CFLAGS :== $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 /EHsc, \
+      LDFLAGS := $$(LDFLAGS_JDKEXE) /STACK:655360 Advapi32.lib Comctl32.lib Gdi32.lib User32.lib, \
+      OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccesswalker$1, \
+      OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
+      PROGRAM := jaccesswalker$1, \
+      DEBUG_SYMBOLS := true, \
+      VERSIONINFO_RESOURCE := $(TOPDIR)/jaccesswalker/jaccesswalkerWindow.rc, \
+      RC_FLAGS := $$(RC_FLAGS) \
+          -D "JDK_FNAME=jaccesswalker$1.exe" \
+          -D "JDK_INTERNAL_NAME=jaccesswalker$1" \
+          -D "JDK_FTYPE=0x01L", \
+   ))
+
+    TARGETS += $$(BUILD_JACCESSWALKER$1)
+
+  endef
+
+  ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
+    $(eval $(call SetupInspector,-32,32))
+    $(eval $(call SetupWalker,-32,32))
+    $(eval $(call SetupInspector,,LEGACY))
+    $(eval $(call SetupWalker,,LEGACY))
+  else
+    $(eval $(call SetupInspector,,64))
+    $(eval $(call SetupWalker,,64))
+  endif
+
 endif
 
 ################################################################################
--- a/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.cpp	Fri Nov 20 16:44:33 2015 +0400
+++ b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.cpp	Fri Nov 20 17:54:58 2015 -0600
@@ -36,6 +36,41 @@
 extern "C" {
 #endif
 
+/**
+ * print a GetLastError message
+ */
+char *printError(char *msg) {
+    LPVOID lpMsgBuf = NULL;
+    static char retbuf[256];
+
+    if (msg != NULL) {
+        strncpy((char *)retbuf, msg, sizeof(retbuf));
+        // if msg text is >= 256 ensure buffer is null terminated
+        retbuf[255] = '\0';
+    }
+    if (!FormatMessage(
+                       FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                       FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
+                       NULL,
+                       GetLastError(),
+                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                       (LPTSTR) &lpMsgBuf,
+                       0,
+                       NULL ))
+        {
+            PrintDebugString("  %s: FormatMessage failed", msg);
+        } else {
+            PrintDebugString("  %s: %s", msg, (char *)lpMsgBuf);
+        }
+    if (lpMsgBuf != NULL) {
+        strncat((char *)retbuf, ": ", sizeof(retbuf) - strlen(retbuf) - 1);
+        strncat((char *)retbuf, (char *)lpMsgBuf, sizeof(retbuf) - strlen(retbuf) - 1);
+    }
+    return (char *)retbuf;
+}
+
+
     /**
      * Send debugging info to the appropriate place
      */
--- a/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.h	Fri Nov 20 16:44:33 2015 +0400
+++ b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.h	Fri Nov 20 17:54:58 2015 -0600
@@ -49,6 +49,7 @@
 extern "C" {
 #endif
 
+    char *printError(char *msg);
     void PrintDebugString(char *msg, ...);
     void PrintJavaDebugString(char *msg, ...);
     void wPrintJavaDebugString(wchar_t *msg, ...);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccessinspector/MessageHistory.cpp	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+#include <windows.h>   // includes basic windows functionality
+#include <iterator>
+#include "MessageHistory.h"
+
+size_t MessageHistory::sm_MaxMessages = 1000;
+
+void MessageHistory::AddMessage(const char * message) {
+    if ( ( NULL == message ) || ( 0 == message [0] ) ) {
+        return;
+    }
+
+    if ( m_Messages.size() >= sm_MaxMessages ) {
+        // Remove the oldest message
+        m_Messages.pop_front();
+    }
+
+    m_Messages.push_back(std::string (message) );
+    m_CurrentPosition = m_Messages.end();
+    -- m_CurrentPosition;
+}
+
+const char * MessageHistory::GetFirstMessage() {
+    if ( m_Messages.empty() ) {
+        return "";
+    }
+
+    m_CurrentPosition = m_Messages.begin();
+    return (*m_CurrentPosition).c_str();
+}
+
+const char * MessageHistory::GetPreviousMessage() {
+    if ( m_Messages.empty() ) {
+        return "";
+    }
+
+    if ( m_CurrentPosition != m_Messages.begin() ) {
+        -- m_CurrentPosition;
+    }
+
+    return (*m_CurrentPosition).c_str();
+}
+
+const char * MessageHistory::GetNextMessage() {
+    if ( m_Messages.empty() ) {
+        return "";
+    }
+
+    ++ m_CurrentPosition;
+    if ( m_CurrentPosition == m_Messages.end() ) {
+        -- m_CurrentPosition;
+    }
+
+    return (*m_CurrentPosition).c_str();
+}
+
+const char * MessageHistory::GetLastMessage()
+{
+    if ( m_Messages.empty() ) {
+        return "";
+    }
+
+    m_CurrentPosition = m_Messages.end();
+    -- m_CurrentPosition;
+    return (*m_CurrentPosition).c_str();
+}
+
+BOOL MessageHistory::IsFirstMessage() {
+    if ( m_Messages.empty() ) {
+        return FALSE;
+    }
+    if ( m_CurrentPosition == m_Messages.begin() ) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+BOOL MessageHistory::IsLastMessage() {
+    if ( m_Messages.empty() ) {
+        return FALSE;
+    }
+    stringlist::const_iterator itTest = m_Messages.end();
+    -- itTest;
+    if ( itTest == m_CurrentPosition ) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+size_t MessageHistory::GetMessageCount() {
+    size_t ret_val = m_Messages.size();
+    return ret_val;
+}
+
+const char * MessageHistory::GetCurrentMessage() {
+    if ( m_Messages.empty() ) {
+        return "";
+    }
+
+    return (*m_CurrentPosition).c_str();
+}
+
+const char * MessageHistory::GetMessage(const size_t messageIndex) {
+    if ( m_Messages.empty() ) {
+        return "";
+    }
+
+    if ( messageIndex >= m_Messages.size() ) {
+        return "";
+    }
+
+    stringlist::const_iterator it = m_Messages.begin();
+    std::advance(it, messageIndex);
+    m_CurrentPosition = it;
+
+    return (*it).c_str();
+}
+
+size_t MessageHistory::GetCurrentMessageIndex() {
+    if ( m_Messages.empty() ) {
+        return 0;
+    }
+
+    stringlist::const_iterator itBegin = m_Messages.begin();
+    size_t ret_val = std::distance(itBegin, m_CurrentPosition);
+    return ret_val;
+}
+
+void MessageHistory::clear() {
+    m_Messages.clear();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccessinspector/MessageHistory.h	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#ifndef __MessageHistory_H__
+#define __MessageHistory_H__
+
+#include <list>
+#include <string>
+
+class MessageHistory
+{
+public:
+    static size_t sm_MaxMessages;
+private:
+    typedef std::list< std::string > stringlist;
+    stringlist m_Messages;
+    stringlist::const_iterator m_CurrentPosition;
+
+public:
+    void AddMessage(const char * message);
+    const char * GetFirstMessage();
+    const char * GetPreviousMessage();
+    const char * GetNextMessage();
+    const char * GetLastMessage();
+    const char * GetCurrentMessage();
+    const char * GetMessage(const size_t messageIndex);
+    size_t GetCurrentMessageIndex();
+    BOOL IsFirstMessage();
+    BOOL IsLastMessage();
+    size_t GetMessageCount();
+    void clear();
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.cpp	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,1716 @@
+/*
+ * 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 sample Assistive Technology which queries the JavaVM to get the Java
+ * Accessibility information available for a Java UI object, using the Java
+ * Access Bridge.
+ */
+
+#include <windows.h>  // includes basic windows functionality
+#include <jni.h>
+
+#include "jaccessinspectorResource.h"
+#include "AccessBridgeCalls.h"
+#include "AccessBridgeCallbacks.h"
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+
+#include "jaccessinspector.h"
+#include "AccessInfo.h"
+#include "MessageHistory.h"
+
+#define TIMER_ID 1
+#define DISPLAY_INFO_MESSAGE WM_USER+1
+#define DISPLAY_HWND_INFO_MESSAGE WM_USER+2
+
+HWND theDialogWindow;
+HWND theGoToDialogWindow;
+HINSTANCE theInstance;
+BOOL theAccessBridgeLoadedFlag;
+
+HHOOK prevKbdHook;
+HHOOK prevMouseHook;
+
+BOOL updateMouse;
+BOOL updateF1;
+BOOL updateF2;
+
+BOOL trackMouse;
+BOOL trackMouseExited;
+BOOL trackMouseClicked;
+BOOL trackMousePressed;
+BOOL trackMouseReleased;
+
+BOOL trackFocus;
+BOOL trackFocusLost;
+BOOL trackCaret;
+BOOL trackShutdown;
+
+BOOL trackMenuSelected;
+BOOL trackMenuDeselected;
+BOOL trackMenuCanceled;
+
+BOOL trackPopupVisible;
+BOOL trackPopupInvisible;
+BOOL trackPopupCanceled;
+
+//BOOL trackPropertyChange;
+
+BOOL trackPropertyNameChange;
+BOOL trackPropertyDescriptionChange;
+BOOL trackPropertyStateChange;
+BOOL trackPropertyValueChange;
+BOOL trackPropertySelectionChange;
+BOOL trackPropertyTextChange;
+BOOL trackPropertyCaretChange;
+BOOL trackPropertyVisibleDataChange;
+BOOL trackPropertyChildChange;
+BOOL trackPropertyActiveDescendentChange;
+BOOL trackPropertyTableModelChange;
+
+
+FILE *logfile = NULL;
+
+MessageHistory g_MessageHistory;
+
+/**
+ * WinMain
+ *
+ */
+int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd) {
+    MSG msg;
+
+    g_LogStringCallback = AddToMessageHistory;
+    theInstance = hInst;
+    theDialogWindow = NULL;
+    theGoToDialogWindow = NULL;
+
+    updateF1 = FALSE;
+    updateF2 = FALSE;
+    updateMouse = FALSE;
+
+    theAccessBridgeLoadedFlag = FALSE;
+
+    ReadActiveEventOptionsFromRegistry ();
+
+    if (InitWindow(hInst)) {
+        if (initializeAccessBridge() == TRUE) {
+            theAccessBridgeLoadedFlag = TRUE;
+            ApplyEventOptions(theDialogWindow);
+            EnableMessageNavButtons();
+            HACCEL hAccel =
+                ::LoadAccelerators (theInstance, MAKEINTRESOURCE(IDR_ACCELERATOR));
+
+            while (GetMessage(&msg, NULL, 0, 0)) {
+                if ( FALSE == TranslateAccelerator(theDialogWindow, hAccel, &msg) ) {
+                    if ( ( ( NULL == theDialogWindow ) ||
+                           ( FALSE == IsDialogMessage(theDialogWindow, &msg) ) ) &&
+                         ( ( NULL == theGoToDialogWindow ) ||
+                           ( FALSE == IsDialogMessage(theGoToDialogWindow, &msg) ) ) ) {
+                        TranslateMessage(&msg);
+                        DispatchMessage(&msg);
+                    }
+                }
+            }
+            if (theAccessBridgeLoadedFlag == TRUE) {
+                shutdownAccessBridge();
+            }
+            SaveActiveEventOptionsToRegistry ();
+        }
+    }
+    return(0);
+}
+
+char szAppName [] = "JACCESSINSPECTORWINDOW";
+
+/**
+ * Real(tm) MS-Windows window initialization
+ *
+ */
+BOOL InitWindow (HANDLE hInstance) {
+    theDialogWindow = CreateDialog((struct HINSTANCE__ *)hInstance,
+                                   szAppName,
+                                   NULL,
+                                   jaccessinspectorDialogProc);
+
+    // If window could not be created, return "failure".
+    if (!theDialogWindow)
+        return FALSE;
+
+    if (logfile == null) {
+        logfile = fopen(JACCESSINSPECTOR_LOG, "w"); // overwrite existing log file
+        logString(logfile, "Starting jaccessinspector.exe %s\n", getTimeAndDate());
+    }
+
+    // Make the window visible, update its client area, & return "success".
+    SetWindowText(theDialogWindow, "jaccessinspector");
+    ShowWindow(theDialogWindow, SW_SHOWNORMAL);
+    UpdateWindow(theDialogWindow);
+
+    return TRUE;
+}
+
+/**
+ * Display Accessible information about the object under the mouse
+ */
+void displayAccessibleInfo(long vmID, AccessibleContext ac, int x, int y) {
+    char buffer[HUGE_BUFSIZE];
+
+    getAccessibleInfo(vmID, ac, x, y, buffer, (int)(sizeof(buffer)));
+    displayAndLog(theDialogWindow, cjaccessinspectorText, logfile, (char *)buffer);
+}
+
+/**
+ * Display Java event info
+ */
+void displayJavaEvent(long vmID, AccessibleContext ac, char *announcement) {
+    char buffer[HUGE_BUFSIZE];
+    char *bufOffset;
+
+    strncpy(buffer, announcement, sizeof(buffer));
+
+    bufOffset = (char *)(buffer + strlen(buffer));
+    getAccessibleInfo( vmID, ac, -1, -1, bufOffset,
+                       (int)(sizeof(buffer) - strlen(buffer)) );
+    displayAndLog(theDialogWindow, cjaccessinspectorText, logfile, (char *)buffer);
+}
+
+
+/**
+ * Display Accessible propertyChange event info
+ */
+void displayAccessiblePropertyChange(long vmID, AccessibleContext ac,
+                                     char *announcement) {
+    char buffer[HUGE_BUFSIZE];
+    char *bufOffset;
+
+    strncpy(buffer, announcement, sizeof(buffer));
+
+    bufOffset = (char *) (buffer + strlen(buffer));
+    getAccessibleInfo( vmID, ac, -1, -1, bufOffset,
+                       (int)(sizeof(buffer) - strlen(buffer)) );
+    displayAndLog(theDialogWindow, cjaccessinspectorText, logfile, (char *)buffer);
+}
+
+
+/**
+ * Update display under mouse when it moves
+ */
+void echoMouseObject() {
+    long vmID;
+    AccessibleContext acParent;
+    AccessibleContext ac;
+    POINT p;
+    HWND hwnd;
+    RECT windowRect;
+
+    GetCursorPos(&p);
+    hwnd = WindowFromPoint(p);
+    if (GetAccessibleContextFromHWND(hwnd, &vmID, &acParent)) {
+        GetWindowRect(hwnd, &windowRect);
+        // send the point in global coordinates; Java will handle it!
+        if (GetAccessibleContextAt(vmID, acParent, (jint) p.x, (jint) p.y, &ac)) {
+            displayAccessibleInfo(vmID, ac, p.x, p.y);  // can handle null
+            ReleaseJavaObject(vmID, ac);
+        }
+    }
+}
+
+
+/**
+ * Update display under HWND the mouse is in
+ */
+void echoMouseHWNDObject() {
+    long vmID;
+    AccessibleContext ac;
+    POINT p;
+    HWND hwnd;
+
+    GetCursorPos(&p);
+    hwnd = WindowFromPoint(p);
+
+    if (GetAccessibleContextFromHWND(hwnd, &vmID, &ac)) {
+        displayAccessibleInfo(vmID, ac, 0, 0);  // can handle null
+        ReleaseJavaObject(vmID, ac);
+    }
+}
+
+/**
+ * Display Accessible information about the object that has focus in
+ * the topmost Java HWND
+ *
+ */
+void displayFocusedObject() {
+    HWND hWnd;
+    long vmID;
+    AccessibleContext ac;
+
+    hWnd = GetTopWindow(NULL);
+    while (hWnd != NULL) {
+        if (IsJavaWindow(hWnd)) {
+            if (GetAccessibleContextWithFocus(hWnd, &vmID, &ac) == TRUE) {
+                displayAccessibleInfo(vmID, ac, 0, 0);
+                ReleaseJavaObject(vmID, ac);
+            }
+            return;
+        } else {
+            hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
+        }
+    }
+}
+
+/*
+ * Handle notification of the Java application shutting down
+ */
+void HandleJavaShutdown(long vmID) {
+    char s[1024];
+    wsprintf(s, "Java VM 0x%X terminated\r\n\r\n", vmID);
+
+    displayJavaEvent(vmID, null, s); // intentially passing null AccessibleContext
+    displayAndLog(theDialogWindow, cjaccessinspectorText, logfile, (char *)s);
+}
+
+/**
+ * Handle a FocusGained event
+ */
+void HandleJavaFocusGained(long vmID, FocusEvent event, AccessibleContext ac) {
+
+    char s[1024];
+    wsprintf(s, "FocusGained\r\n\r\n");
+
+    if (ac != (AccessibleContext) 0) {
+        displayJavaEvent(vmID, ac, s);
+    }
+
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a FocusLost event
+ */
+void HandleJavaFocusLost(long vmID, FocusEvent event, AccessibleContext ac) {
+
+    // NOTE: calling GetAccessibleContextWithFocus() after a FocusLost event
+    //       would result in a null AccessibleContext being returned, since
+    //       at that point, no object has the focus.  If the topmost window
+    //       does not belong to a JavaVM, then no component within a JavaVM
+    //       will have the focus (and again, GetAccessibleContextWithFocus()
+    //       will return a null AccessibleContext).  You should always get
+    //       a FocusLost event when a window not belonging to a JavaVM becomes
+    //       topmost.
+
+    char s[1024];
+    wsprintf(s, "FocusLost\r\n\r\n");
+
+    if (ac != (AccessibleContext) 0) {
+        displayJavaEvent(vmID, ac, s);
+    }
+    /*
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    */
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a CaretUpdate event
+ */
+void HandleJavaCaretUpdate(long vmID, CaretEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a MouseClicked event
+ */
+void HandleMouseClicked(long vmID, MouseEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a MouseEntered event
+ */
+void HandleMouseEntered(long vmID, MouseEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a MouseExited event
+ */
+void HandleMouseExited(long vmID, MouseEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a MousePressed event
+ */
+void HandleMousePressed(long vmID, MouseEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a MouseReleased event
+ */
+void HandleMouseReleased(long vmID, MouseEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a MenuCanceled event
+ */
+void HandleMenuCanceled(long vmID, MenuEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);    // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a MenuDeselected event
+ */
+void HandleMenuDeselected(long vmID, MenuEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a MenuSelected event
+ */
+void HandleMenuSelected(long vmID, MenuEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a PopupMenuCanceled event
+ */
+void HandlePopupMenuCanceled(long vmID, MenuEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a PopupMenuWillBecomeInvisible event
+ */
+void HandlePopupMenuWillBecomeInvisible(long vmID, MenuEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a PopupMenuWillBecomeVisible event
+ */
+void HandlePopupMenuWillBecomeVisible(long vmID, MenuEvent event, AccessibleContext ac) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessibleInfo(vmID, ac, 0, 0);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+
+
+
+/**
+ * Handle a HandlePropertyNameChange event
+ */
+void HandlePropertyNameChange(long vmID, PropertyChangeEvent event, AccessibleContext ac,
+                              wchar_t *oldName, wchar_t *newName) {
+    char s[1024];
+    wsprintf(s, "Name changed event: old = %ls; new = %ls\r\n\r\n", oldName, newName);
+
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, ac, s);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertyDescriptionChange event
+ */
+void HandlePropertyDescriptionChange( long vmID,
+                                      PropertyChangeEvent event,
+                                      AccessibleContext ac,
+                                      wchar_t *oldDescription,
+                                      wchar_t *newDescription ) {
+    char s[1024];
+    wsprintf( s, "Description changed event: old = %ls; new = %ls\r\n\r\n",
+              oldDescription, newDescription );
+
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, ac, s);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertyStateChange event
+ */
+void HandlePropertyStateChange( long vmID, PropertyChangeEvent event,
+                                AccessibleContext ac,
+                                wchar_t *oldState, wchar_t *newState ) {
+    char s[1024];
+    wsprintf( s, "State changed event: old = %ls; new = %ls\r\n\r\n",
+              oldState, newState );
+
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, ac, s);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertyValueChange event
+ */
+void HandlePropertyValueChange( long vmID, PropertyChangeEvent event,
+                                AccessibleContext ac,
+                                wchar_t *oldValue, wchar_t *newValue ) {
+    char s[1024];
+    wsprintf( s, "Value changed event: old = %ls; new = %ls\r\n\r\n",
+              oldValue, newValue );
+
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, ac, s);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertySelectionChange event
+ */
+void HandlePropertySelectionChange( long vmID, PropertyChangeEvent event,
+                                    AccessibleContext ac ) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange( vmID, ac,
+                                         "Selection changed event\r\n\r\n" );
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertyTextChange event
+ */
+void HandlePropertyTextChange( long vmID, PropertyChangeEvent event,
+                               AccessibleContext ac ) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, ac, "Text changed event\r\n\r\n");
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertyCaretChange event
+ */
+void HandlePropertyCaretChange( long vmID, PropertyChangeEvent event,
+                                AccessibleContext ac,
+                                int oldPosition, int newPosition ) {
+    char s[1024];
+
+    wsprintf( s, "Caret changed event: oldPosition = %d; newPosition = %d\r\n\r\n",
+              oldPosition, newPosition );
+
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, ac, s);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertyVisibleDataChange event
+ */
+void HandlePropertyVisibleDataChange( long vmID, PropertyChangeEvent event,
+                                      AccessibleContext ac ) {
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange( vmID, ac,
+                                         "VisibleData changed event\r\n\r\n" );
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertyChildChange event
+ */
+void HandlePropertyChildChange( long vmID, PropertyChangeEvent event,
+                                AccessibleContext ac,
+                                JOBJECT64 oldChild, JOBJECT64 newChild ) {
+    char buffer[HUGE_BUFSIZE];
+    char *bufOffset;
+
+    sprintf( buffer,
+             "Child property changed event:\r\n=======================\r\n\r\n" );
+
+    if (oldChild != 0) {
+        strncat(buffer, "Old Accessible Child info:\r\n\r\n", sizeof(buffer));
+        bufOffset = (char *) (buffer + strlen(buffer));
+        getAccessibleInfo( vmID, oldChild, 0, 0, bufOffset,
+                           (int)(sizeof(buffer) - strlen(buffer)) );
+        strncat(buffer, "\r\n\r\n", sizeof(buffer));
+    }
+
+    if (newChild != 0) {
+        strncat(buffer, "New Accessible Child info:\r\n\r\n", sizeof(buffer));
+        bufOffset = (char *) (buffer + strlen(buffer));
+        getAccessibleInfo( vmID, newChild, 0, 0, bufOffset,
+                          (int)(sizeof(buffer) - strlen(buffer)) );
+        strncat(buffer, "\r\n\r\n", sizeof(buffer));
+    }
+
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, ac, buffer);
+    }
+
+    ReleaseJavaObject(vmID, ac);        // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, oldChild);  // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, newChild);  // must always release, to stave off memory leaks
+}
+
+/**
+ * Handle a HandlePropertyActiveDescendentChange event
+ */
+void HandlePropertyActiveDescendentChange( long vmID, PropertyChangeEvent event,
+                                           AccessibleContext ac,
+                                           JOBJECT64 oldActiveDescendent,
+                                           JOBJECT64 newActiveDescendent ) {
+    char buffer[HUGE_BUFSIZE];
+
+    sprintf( buffer,
+             "ActiveDescendent property changed event:\r\n=======================\r\n\r\n" );
+
+#ifdef _notdef
+    char *bufOffset;
+    if (oldActiveDescendent != 0) {
+        strncat(buffer, "Old Accessible ActiveDescendent info:\r\n\r\n", sizeof(buffer));
+        bufOffset = (char *) (buffer + strlen(buffer));
+        getAccessibleInfo( vmID, oldActiveDescendent, 0, 0, bufOffset,
+                           (int)(sizeof(buffer) - strlen(buffer)) );
+        strncat(buffer, "\r\n\r\n", sizeof(buffer));
+    }
+
+    if (newActiveDescendent != 0) {
+        strncat( buffer, "New Accessible ActiveDescendent info:\r\n\r\n",
+                 sizeof(buffer) );
+        bufOffset = (char *) (buffer + strlen(buffer));
+        getAccessibleInfo( vmID, newActiveDescendent, 0, 0, bufOffset,
+                           (int)(sizeof(buffer) - strlen(buffer)) );
+        strncat(buffer, "\r\n\r\n", sizeof(buffer));
+    }
+#endif _notdef
+
+    if (newActiveDescendent != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, newActiveDescendent, buffer);
+    }
+
+    ReleaseJavaObject(vmID, ac);  // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, oldActiveDescendent);  // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, newActiveDescendent);  // must always release, to stave off memory leaks
+}
+
+
+/**
+ * Handle a HandlePropertyTableModelChange event
+ */
+void HandlePropertyTableModelChange( long vmID, PropertyChangeEvent event,
+                                     AccessibleContext ac,
+                                     wchar_t *oldValue, wchar_t *newValue ) {
+
+    char s[1024];
+    wsprintf( s, "Table Model Change: old = %ls; new = %ls\r\n\r\n",
+              oldValue, newValue );
+
+    if (ac != (AccessibleContext) 0) {
+        displayAccessiblePropertyChange(vmID, ac, s);
+    }
+    ReleaseJavaObject(vmID, ac);     // must always release, to stave off memory leaks
+    ReleaseJavaObject(vmID, event);  // must always release, to stave off memory leaks
+}
+
+
+
+#define DOWN_UP_FLAG 1<<31
+
+void CALLBACK TimerProc(HWND hWnd, UINT uTimerMsg, UINT uTimerID, DWORD dwTime) {
+    // when mouse settles from movement
+    KillTimer(hWnd, uTimerID);
+    if (updateMouse == TRUE) {
+        PostMessage(theDialogWindow, DISPLAY_INFO_MESSAGE, 0, 0);
+    }
+}
+
+LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
+    // on mouse-up of F1
+    if (code < 0) {
+        CallNextHookEx(prevKbdHook, code, wParam, lParam);
+    } else if (wParam == VK_F1 && lParam & DOWN_UP_FLAG && updateF1) {
+        PostMessage(theDialogWindow, DISPLAY_INFO_MESSAGE, wParam, lParam);
+    } else if (wParam == VK_F2 && lParam & DOWN_UP_FLAG && updateF2) {
+        PostMessage(theDialogWindow, DISPLAY_HWND_INFO_MESSAGE, wParam, lParam);
+    }
+    return 0;
+}
+
+LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam) {
+    // when mouse settles from movement
+    if (code < 0) {
+        CallNextHookEx(prevMouseHook, code, wParam, lParam);
+    } else {
+        // reset the timer every time the mouse moves
+        KillTimer(theDialogWindow, TIMER_ID);
+        SetTimer(theDialogWindow, TIMER_ID, 1000, (TIMERPROC)TimerProc);
+    }
+    return 0;
+}
+
+void exitjaccessinspector(HWND hWnd) {
+    EndDialog(hWnd, TRUE);
+    PostQuitMessage (0);
+}
+
+#define INSTALL_EVENT_LISTENER(toggleVal, setFP, handler)   \
+    if (toggleVal) {                                        \
+        setFP(handler);                                     \
+    }
+
+void reinstallEventListeners() {
+    INSTALL_EVENT_LISTENER(trackMouse, SetMouseEntered, HandleMouseEntered);
+    INSTALL_EVENT_LISTENER(trackMouseExited, SetMouseExited, HandleMouseExited);
+    INSTALL_EVENT_LISTENER(trackMouseClicked, SetMouseClicked, HandleMouseClicked);
+    INSTALL_EVENT_LISTENER(trackMousePressed, SetMousePressed, HandleMousePressed);
+    INSTALL_EVENT_LISTENER(trackMouseReleased, SetMouseReleased, HandleMouseReleased);
+    INSTALL_EVENT_LISTENER(trackShutdown, SetJavaShutdown, HandleJavaShutdown);
+    INSTALL_EVENT_LISTENER(trackFocus, SetFocusGained, HandleJavaFocusGained);
+    INSTALL_EVENT_LISTENER(trackFocusLost, SetFocusLost, HandleJavaFocusLost);
+    INSTALL_EVENT_LISTENER(trackCaret, SetCaretUpdate, HandleJavaCaretUpdate);
+
+    INSTALL_EVENT_LISTENER(trackMenuSelected, SetMenuSelected, HandleMenuSelected);
+    INSTALL_EVENT_LISTENER(trackMenuDeselected, SetMenuDeselected, HandleMenuDeselected);
+    INSTALL_EVENT_LISTENER(trackMenuCanceled, SetMenuCanceled, HandleMenuCanceled);
+
+    INSTALL_EVENT_LISTENER( trackPopupVisible, SetPopupMenuWillBecomeVisible,
+                            HandlePopupMenuWillBecomeVisible );
+    INSTALL_EVENT_LISTENER( trackPopupInvisible, SetPopupMenuWillBecomeInvisible,
+                            HandlePopupMenuWillBecomeInvisible );
+    INSTALL_EVENT_LISTENER( trackPopupCanceled, SetPopupMenuCanceled,
+                            HandlePopupMenuCanceled );
+
+    INSTALL_EVENT_LISTENER( trackPropertyNameChange, SetPropertyNameChange,
+                            HandlePropertyNameChange);
+    INSTALL_EVENT_LISTENER( trackPropertyDescriptionChange,
+                            SetPropertyDescriptionChange,
+                            HandlePropertyDescriptionChange );
+    INSTALL_EVENT_LISTENER( trackPropertyStateChange, SetPropertyStateChange,
+                            HandlePropertyStateChange );
+    INSTALL_EVENT_LISTENER( trackPropertyValueChange, SetPropertyValueChange,
+                            HandlePropertyValueChange );
+    INSTALL_EVENT_LISTENER( trackPropertySelectionChange,
+                            SetPropertySelectionChange,
+                            HandlePropertySelectionChange );
+    INSTALL_EVENT_LISTENER( trackPropertyTextChange, SetPropertyTextChange,
+                            HandlePropertyTextChange );
+    INSTALL_EVENT_LISTENER( trackPropertyCaretChange, SetPropertyCaretChange,
+                            HandlePropertyCaretChange );
+    INSTALL_EVENT_LISTENER( trackPropertyVisibleDataChange,
+                            SetPropertyVisibleDataChange,
+                            HandlePropertyVisibleDataChange );
+    INSTALL_EVENT_LISTENER( trackPropertyChildChange, SetPropertyChildChange,
+                            HandlePropertyChildChange );
+    INSTALL_EVENT_LISTENER( trackPropertyActiveDescendentChange,
+                            SetPropertyActiveDescendentChange,
+                            HandlePropertyActiveDescendentChange );
+    INSTALL_EVENT_LISTENER( trackPropertyTableModelChange,
+                            SetPropertyTableModelChange,
+                            HandlePropertyTableModelChange );
+}
+
+
+#define TRACK_EVENT_TOGGLE(menuItem, toggleVal, setFP, handler) \
+    case menuItem:                                              \
+        menu = GetMenu(hWnd);                                   \
+        if (toggleVal) {                                        \
+            toggleVal = FALSE;                                  \
+            CheckMenuItem(menu, menuItem,                       \
+                          MF_BYCOMMAND | MF_UNCHECKED);         \
+            setFP(NULL);                                        \
+        } else {                                                \
+            toggleVal = TRUE;                                   \
+            CheckMenuItem(menu, menuItem,                       \
+                          MF_BYCOMMAND | MF_CHECKED);           \
+            setFP(handler);                                     \
+        }                                                       \
+        MaybeCheckMonitorTheSameEventsAsJAWS(menu);             \
+        MaybeCheckMonitorAllEvents(menu);                       \
+        return TRUE
+
+INT_PTR CALLBACK jaccessinspectorDialogProc( HWND hWnd, UINT message,
+                                             WPARAM wParam, LPARAM lParam ) {
+    const int minWindowWidth = 540;
+    const int minWindowHeight = 300;
+    static int titleBarHeight = ::GetSystemMetrics(SM_CYSIZE);
+    static int menuBarHeight = ::GetSystemMetrics(SM_CYMENU);
+    static int borderHeight = ::GetSystemMetrics(SM_CYBORDER);
+    static int borderWidth = ::GetSystemMetrics(SM_CXBORDER);
+    static int verticalScrollBarWidth = ::GetSystemMetrics(SM_CXVSCROLL);
+    int command;
+    short width, height;
+    HWND dlgItem;
+    RECT dlgItemRect;
+    RECT dialogBoxRect;
+    LONG lT;
+    HMENU menu;
+    DWORD lastError = 0;
+
+    switch (message) {
+
+    case WM_CREATE:
+        return 0;
+
+    case WM_INITDIALOG:
+        CheckMenuItem(GetMenu(hWnd), cAccessBridgeDLLLoaded, MF_BYCOMMAND | MF_CHECKED);
+        return TRUE;
+
+    case WM_CLOSE:
+        exitjaccessinspector(hWnd);
+        return TRUE;
+
+    case WM_SIZE:
+        width = LOWORD(lParam);
+        height = HIWORD(lParam);
+        dlgItem = GetDlgItem(theDialogWindow, cjaccessinspectorText);
+        ::GetWindowRect(dlgItem, &dlgItemRect);
+        ::GetWindowRect(theDialogWindow, &dialogBoxRect);
+        lT = dlgItemRect.top - dialogBoxRect.top - titleBarHeight -
+             menuBarHeight + (borderHeight * 4);
+        SetWindowPos( dlgItem, NULL, 0, 0,
+                      width - (borderWidth * 2) - verticalScrollBarWidth,
+                      height - lT, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+        return FALSE;  // let windows finish handling this
+
+    case WM_GETMINMAXINFO:
+        {
+            LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
+            lpMMI->ptMinTrackSize.x = minWindowWidth;
+            lpMMI->ptMinTrackSize.y = minWindowHeight;
+            return TRUE;
+        }
+        break;
+
+    case WM_COMMAND:
+        command = LOWORD(wParam);
+
+        switch(command) {
+        case cAccessBridgeDLLLoaded:    // toggle; unload or load AccessBridge
+            if (theAccessBridgeLoadedFlag) {
+                shutdownAccessBridge();
+                theAccessBridgeLoadedFlag = FALSE;
+                CheckMenuItem( GetMenu(hWnd), cAccessBridgeDLLLoaded,
+                               MF_BYCOMMAND | MF_UNCHECKED );
+            } else {
+                theAccessBridgeLoadedFlag = initializeAccessBridge();
+                if (theAccessBridgeLoadedFlag) {
+                    CheckMenuItem( GetMenu(hWnd), cAccessBridgeDLLLoaded,
+                                   MF_BYCOMMAND | MF_CHECKED );
+                    reinstallEventListeners();
+                }
+            }
+            return TRUE;
+
+        case cExitMenuItem:
+            exitjaccessinspector(hWnd);
+            return TRUE;
+
+        TRACK_EVENT_TOGGLE( cTrackMouseMenuItem, trackMouse, SetMouseEntered,
+                            HandleMouseEntered );
+        TRACK_EVENT_TOGGLE( cTrackMouseExitedMenuItem, trackMouseExited,
+                            SetMouseExited, HandleMouseExited );
+        TRACK_EVENT_TOGGLE( cTrackMouseClickedMenuItem, trackMouseClicked,
+                            SetMouseClicked, HandleMouseClicked );
+        TRACK_EVENT_TOGGLE( cTrackMousePressedMenuItem, trackMousePressed,
+                            SetMousePressed, HandleMousePressed );
+        TRACK_EVENT_TOGGLE( cTrackMouseReleasedMenuItem, trackMouseReleased,
+                            SetMouseReleased, HandleMouseReleased );
+        TRACK_EVENT_TOGGLE( cTrackShutdownMenuItem, trackShutdown,
+                            SetJavaShutdown, HandleJavaShutdown );
+        TRACK_EVENT_TOGGLE( cTrackFocusMenuItem, trackFocus, SetFocusGained,
+                            HandleJavaFocusGained );
+        TRACK_EVENT_TOGGLE( cTrackFocusLostMenuItem, trackFocusLost,
+                            SetFocusLost, HandleJavaFocusLost );
+        TRACK_EVENT_TOGGLE( cTrackCaretMenuItem, trackCaret, SetCaretUpdate,
+                            HandleJavaCaretUpdate );
+
+        TRACK_EVENT_TOGGLE( cTrackMenuSelectedMenuItem, trackMenuSelected,
+                            SetMenuSelected, HandleMenuSelected );
+        TRACK_EVENT_TOGGLE( cTrackMenuDeselectedMenuItem, trackMenuDeselected,
+                            SetMenuDeselected, HandleMenuDeselected );
+        TRACK_EVENT_TOGGLE( cTrackMenuCanceledItem, trackMenuCanceled,
+                            SetMenuCanceled, HandleMenuCanceled );
+
+        TRACK_EVENT_TOGGLE( cTrackPopupBecomeVisibleMenuItem, trackPopupVisible,
+                            SetPopupMenuWillBecomeVisible,
+                            HandlePopupMenuWillBecomeVisible );
+        TRACK_EVENT_TOGGLE( cTrackPopupBecomeInvisibleMenuItem,
+                            trackPopupInvisible,
+                            SetPopupMenuWillBecomeInvisible,
+                            HandlePopupMenuWillBecomeInvisible );
+        TRACK_EVENT_TOGGLE( cTrackPopupCanceledItem, trackPopupCanceled,
+                            SetPopupMenuCanceled, HandlePopupMenuCanceled );
+
+        TRACK_EVENT_TOGGLE( cTrackPropertyNameItem, trackPropertyNameChange,
+                            SetPropertyNameChange, HandlePropertyNameChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyDescriptionItem,
+                            trackPropertyDescriptionChange,
+                            SetPropertyDescriptionChange,
+                            HandlePropertyDescriptionChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyStateItem, trackPropertyStateChange,
+                            SetPropertyStateChange, HandlePropertyStateChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyValueItem, trackPropertyValueChange,
+                            SetPropertyValueChange, HandlePropertyValueChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertySelectionItem,
+                            trackPropertySelectionChange,
+                            SetPropertySelectionChange,
+                            HandlePropertySelectionChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyTextItem, trackPropertyTextChange,
+                            SetPropertyTextChange, HandlePropertyTextChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyCaretItem, trackPropertyCaretChange,
+                            SetPropertyCaretChange, HandlePropertyCaretChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyVisibleDataItem,
+                            trackPropertyVisibleDataChange,
+                            SetPropertyVisibleDataChange,
+                            HandlePropertyVisibleDataChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyChildItem, trackPropertyChildChange,
+                            SetPropertyChildChange, HandlePropertyChildChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyActiveDescendentItem,
+                            trackPropertyActiveDescendentChange,
+                            SetPropertyActiveDescendentChange,
+                            HandlePropertyActiveDescendentChange );
+        TRACK_EVENT_TOGGLE( cTrackPropertyTableModelChangeItem,
+                            trackPropertyTableModelChange,
+                            SetPropertyTableModelChange,
+                            HandlePropertyTableModelChange );
+
+        case cUpdateFromMouseMenuItem:
+            menu = GetMenu(hWnd);
+            if (updateMouse) {
+                updateMouse = FALSE;
+                CheckMenuItem( menu, cUpdateFromMouseMenuItem,
+                               MF_BYCOMMAND | MF_UNCHECKED );
+                UnhookWindowsHookEx((HHOOK)MouseProc);
+                KillTimer(hWnd, TIMER_ID);
+            } else {
+                updateMouse = TRUE;
+                CheckMenuItem( menu, cUpdateFromMouseMenuItem,
+                               MF_BYCOMMAND | MF_CHECKED );
+                prevMouseHook = SetWindowsHookEx( WH_MOUSE, MouseProc,
+                                                  theInstance,
+                                                  ::GetCurrentThreadId() );
+                if (! prevMouseHook) {
+                    lastError = ::GetLastError();
+                }
+            }
+            return TRUE;
+
+        case cUpdateWithF1Item:
+            menu = GetMenu(hWnd);
+            if (updateF1) {
+                updateF1 = FALSE;
+                CheckMenuItem( menu, cUpdateWithF1Item,
+                               MF_BYCOMMAND | MFS_UNCHECKED );
+                UnhookWindowsHookEx((HHOOK)KeyboardProc);
+            } else {
+                updateF1 = TRUE;
+                CheckMenuItem( menu, cUpdateWithF1Item,
+                               MF_BYCOMMAND | MFS_CHECKED );
+                prevKbdHook = SetWindowsHookEx( WH_KEYBOARD, KeyboardProc,
+                                                theInstance,
+                                                ::GetCurrentThreadId() );
+                if (! prevKbdHook) {
+                    lastError = ::GetLastError();
+                }
+            }
+            return TRUE;
+
+        case cUpdateWithF2Item:
+            menu = GetMenu(hWnd);
+            if (updateF2) {
+                updateF2 = FALSE;
+                CheckMenuItem( menu, cUpdateWithF2Item,
+                               MF_BYCOMMAND | MFS_UNCHECKED );
+                UnhookWindowsHookEx((HHOOK)KeyboardProc);
+            } else {
+                updateF2 = TRUE;
+                CheckMenuItem(menu, cUpdateWithF2Item,
+                              MF_BYCOMMAND | MFS_CHECKED);
+                prevKbdHook = SetWindowsHookEx( WH_KEYBOARD, KeyboardProc,
+                                                theInstance, ::GetCurrentThreadId() );
+                if (! prevKbdHook) {
+                    lastError = ::GetLastError();
+                }
+            }
+            return TRUE;
+
+        case cMonitorTheSameEventsAsJAWS:
+            /*
+            Causes jaccessinspetor to monitor the same events as JAWS.  Useful
+            when testing to determine if a bug is specific to JAWS or if it can
+            be reproduced in jaccessinspector as well.
+            */
+            trackMouse = FALSE;
+            trackMouseExited = FALSE;
+            trackMouseClicked = FALSE;
+            trackMousePressed = FALSE;
+            trackMouseReleased = FALSE;
+            trackFocus = TRUE;
+            trackFocusLost = TRUE;
+            trackCaret = FALSE;
+            trackShutdown = FALSE;
+
+            trackMenuSelected = FALSE;
+            trackMenuDeselected = FALSE;
+            trackMenuCanceled = FALSE;
+
+            trackPopupVisible = FALSE;
+            trackPopupInvisible = FALSE;
+            trackPopupCanceled = FALSE;
+
+            trackPropertyNameChange = TRUE;
+            trackPropertyDescriptionChange = TRUE;
+            trackPropertyStateChange = TRUE;
+            trackPropertyValueChange = TRUE;
+            trackPropertySelectionChange = TRUE;
+            trackPropertyTextChange = TRUE;
+            trackPropertyCaretChange = TRUE;
+            trackPropertyVisibleDataChange = FALSE;
+            trackPropertyChildChange = TRUE;
+            trackPropertyActiveDescendentChange = TRUE;
+            trackPropertyTableModelChange = FALSE;
+
+            ApplyEventOptions(hWnd);
+
+            return TRUE;
+
+        case cMonitorAllEvents:
+            /*
+            Causes jaccessinspector to monitor all Java Events and all
+            Accessibility Events.
+            */
+            trackMouse = TRUE;
+            trackMouseExited = TRUE;
+            trackMouseClicked = TRUE;
+            trackMousePressed = TRUE;
+            trackMouseReleased = TRUE;
+            trackFocus = TRUE;
+            trackFocusLost = TRUE;
+            trackCaret = TRUE;
+            trackShutdown = TRUE;
+
+            trackMenuSelected = TRUE;
+            trackMenuDeselected = TRUE;
+            trackMenuCanceled = TRUE;
+
+            trackPopupVisible = TRUE;
+            trackPopupInvisible = TRUE;
+            trackPopupCanceled = TRUE;
+
+            trackPropertyNameChange = TRUE;
+            trackPropertyDescriptionChange = TRUE;
+            trackPropertyStateChange = TRUE;
+            trackPropertyValueChange = TRUE;
+            trackPropertySelectionChange = TRUE;
+            trackPropertyTextChange = TRUE;
+            trackPropertyCaretChange = TRUE;
+            trackPropertyVisibleDataChange = TRUE;
+            trackPropertyChildChange = TRUE;
+            trackPropertyActiveDescendentChange = TRUE;
+            trackPropertyTableModelChange = TRUE;
+
+            ApplyEventOptions(hWnd);
+
+            return TRUE;
+
+        case cFirstMessage:
+            {
+                const char * messageText = g_MessageHistory.GetFirstMessage ();
+                if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {
+                    ::SetDlgItemText( theDialogWindow, cjaccessinspectorText,
+                                      messageText );
+                }
+                EnableMessageNavButtons();
+                UpdateMessageNumber();
+                return TRUE;
+            }
+            break;
+
+        case cPreviousMessage:
+            {
+                const char * messageText = g_MessageHistory.GetPreviousMessage ();
+                if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {
+                    ::SetDlgItemText( theDialogWindow, cjaccessinspectorText,
+                                      messageText );
+                }
+                EnableMessageNavButtons();
+                UpdateMessageNumber();
+                return TRUE;
+            }
+            break;
+
+        case cNextMessage:
+            {
+                const char * messageText = g_MessageHistory.GetNextMessage ();
+                if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {
+                    ::SetDlgItemText( theDialogWindow, cjaccessinspectorText,
+                                      messageText );
+                }
+                EnableMessageNavButtons();
+                UpdateMessageNumber();
+                return TRUE;
+            }
+            break;
+
+        case cLastMessage:
+            {
+                const char * messageText = g_MessageHistory.GetLastMessage();
+                if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {
+                    ::SetDlgItemText( theDialogWindow, cjaccessinspectorText,
+                                      messageText );
+                }
+                EnableMessageNavButtons();
+                UpdateMessageNumber();
+                return TRUE;
+            }
+            break;
+
+        case cResetAllEvents:
+            trackMouse = FALSE;
+            trackMouseExited = FALSE;
+            trackMouseClicked = FALSE;
+            trackMousePressed = FALSE;
+            trackMouseReleased = FALSE;
+            trackFocus = FALSE;
+            trackFocusLost = FALSE;
+            trackCaret = FALSE;
+            trackShutdown = FALSE;
+
+            trackMenuSelected = FALSE;
+            trackMenuDeselected = FALSE;
+            trackMenuCanceled = FALSE;
+
+            trackPopupVisible = FALSE;
+            trackPopupInvisible = FALSE;
+            trackPopupCanceled = FALSE;
+
+            trackPropertyNameChange = FALSE;
+            trackPropertyDescriptionChange = FALSE;
+            trackPropertyStateChange = FALSE;
+            trackPropertyValueChange = FALSE;
+            trackPropertySelectionChange = FALSE;
+            trackPropertyTextChange = FALSE;
+            trackPropertyCaretChange = FALSE;
+            trackPropertyVisibleDataChange = FALSE;
+            trackPropertyChildChange = FALSE;
+            trackPropertyActiveDescendentChange = FALSE;
+            trackPropertyTableModelChange = FALSE;
+
+            ApplyEventOptions(hWnd);
+
+            return TRUE;
+
+        case cGoToMessage:
+            InitGoToMessageDialogBox(theInstance);
+            break;
+
+        case cClearMessageHistory:
+            g_MessageHistory.clear();
+            ::SetDlgItemText(theDialogWindow, cjaccessinspectorText, NULL);
+            EnableMessageNavButtons();
+            UpdateMessageNumber();
+            break;
+        }
+        break;
+
+    case DISPLAY_INFO_MESSAGE:
+        echoMouseObject();
+        return TRUE;
+
+    case DISPLAY_HWND_INFO_MESSAGE:
+        echoMouseHWNDObject();
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+#define SaveOptionToRegistry(optionVar) { \
+    SetValue = RegSetValueEx( hKey, #optionVar, 0, REG_DWORD, \
+                              (LPBYTE)(&optionVar), sizeof(DWORD)); \
+    if ( ERROR_SUCCESS != SetValue ) { \
+        ++ failureCount; \
+    } \
+}
+
+BOOL SaveActiveEventOptionsToRegistry() {
+    LONG CreateKey = ERROR_SUCCESS;
+    HKEY hKey = NULL;
+    DWORD Disposition = 0;
+
+    CreateKey = ::RegCreateKeyEx( HKEY_CURRENT_USER,
+                                  jaccessinspectorOptionsRegistryKey, 0, 0, 0,
+                                  KEY_READ|KEY_WRITE, 0, &hKey, &Disposition );
+    if ( ( ERROR_SUCCESS != CreateKey ) || ( NULL == hKey ) ) {
+        return FALSE;
+    }
+
+    LONG SetValue = ERROR_SUCCESS;
+    unsigned long failureCount = 0;
+
+    SaveOptionToRegistry(trackMouse);
+    SaveOptionToRegistry(trackMouseExited);
+    SaveOptionToRegistry(trackMouseClicked);
+    SaveOptionToRegistry(trackMousePressed);
+    SaveOptionToRegistry(trackMouseReleased);
+    SaveOptionToRegistry(trackShutdown);
+    SaveOptionToRegistry(trackFocus);
+    SaveOptionToRegistry(trackFocusLost);
+    SaveOptionToRegistry(trackCaret);
+    SaveOptionToRegistry(trackMenuSelected);
+    SaveOptionToRegistry(trackMenuDeselected);
+    SaveOptionToRegistry(trackMenuCanceled);
+    SaveOptionToRegistry(trackPopupVisible);
+    SaveOptionToRegistry(trackPopupInvisible);
+    SaveOptionToRegistry(trackPopupCanceled);
+    SaveOptionToRegistry(trackPropertyNameChange);
+    SaveOptionToRegistry(trackPropertyDescriptionChange);
+    SaveOptionToRegistry(trackPropertyStateChange);
+    SaveOptionToRegistry(trackPropertyValueChange);
+    SaveOptionToRegistry(trackPropertySelectionChange);
+    SaveOptionToRegistry(trackPropertyTextChange);
+    SaveOptionToRegistry(trackPropertyCaretChange);
+    SaveOptionToRegistry(trackPropertyVisibleDataChange);
+    SaveOptionToRegistry(trackPropertyChildChange);
+    SaveOptionToRegistry(trackPropertyActiveDescendentChange);
+    SaveOptionToRegistry(trackPropertyTableModelChange);
+
+    ::RegFlushKey(hKey);
+    ::RegCloseKey(hKey);
+
+    if ( 0 == failureCount ) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+#define ReadOptionFromRegistry(optionVar) { \
+    Type = Value = 0; \
+    ValueSize = sizeof(DWORD); \
+    QueryValue = ::RegQueryValueEx( hKey, #optionVar, NULL, &Type, \
+                                   (LPBYTE)(&Value), &ValueSize); \
+    if ( ( ERROR_SUCCESS == QueryValue ) && ( REG_DWORD == Type ) ) { \
+        optionVar = static_cast<BOOL>(Value); \
+    } else { \
+        ++ failureCount; \
+    } \
+}
+
+BOOL ReadActiveEventOptionsFromRegistry() {
+
+    trackMouse = FALSE;
+    trackMouseExited = FALSE;
+    trackMouseClicked = FALSE;
+    trackMousePressed = FALSE;
+    trackMouseReleased = FALSE;
+
+    trackShutdown = FALSE;
+    trackFocus = FALSE;
+    trackFocusLost = FALSE;
+    trackCaret = FALSE;
+    trackMenuSelected = FALSE;
+    trackMenuDeselected = FALSE;
+    trackMenuCanceled = FALSE;
+    trackPopupVisible = FALSE;
+    trackPopupInvisible = FALSE;
+    trackPopupCanceled = FALSE;
+
+    trackPropertyNameChange = FALSE;
+    trackPropertyDescriptionChange = FALSE;
+    trackPropertyStateChange = FALSE;
+    trackPropertyValueChange = FALSE;
+    trackPropertySelectionChange = FALSE;
+    trackPropertyTextChange = FALSE;
+    trackPropertyCaretChange = FALSE;
+    trackPropertyVisibleDataChange = FALSE;
+    trackPropertyChildChange = FALSE;
+    trackPropertyActiveDescendentChange = FALSE;
+    trackPropertyTableModelChange = FALSE;
+
+    LONG OpenKey = ERROR_SUCCESS;
+    HKEY hKey = NULL;
+    OpenKey = ::RegOpenKeyEx( HKEY_CURRENT_USER,
+                              jaccessinspectorOptionsRegistryKey, 0,
+                              KEY_READ, &hKey );
+    if ( ( ERROR_SUCCESS != OpenKey ) || ( NULL == hKey ) ) {
+        return FALSE;
+    }
+
+    LONG QueryValue = ERROR_SUCCESS;
+    unsigned long failureCount = 0;
+    DWORD Type, Value, ValueSize;
+
+    ReadOptionFromRegistry(trackMouse);
+    ReadOptionFromRegistry(trackMouseExited);
+    ReadOptionFromRegistry(trackMouseClicked);
+    ReadOptionFromRegistry(trackMousePressed);
+    ReadOptionFromRegistry(trackMouseReleased);
+    ReadOptionFromRegistry(trackShutdown);
+    ReadOptionFromRegistry(trackFocus);
+    ReadOptionFromRegistry(trackFocusLost);
+    ReadOptionFromRegistry(trackCaret);
+    ReadOptionFromRegistry(trackMenuSelected);
+    ReadOptionFromRegistry(trackMenuDeselected);
+    ReadOptionFromRegistry(trackMenuCanceled);
+    ReadOptionFromRegistry(trackPopupVisible);
+    ReadOptionFromRegistry(trackPopupInvisible);
+    ReadOptionFromRegistry(trackPopupCanceled);
+    ReadOptionFromRegistry(trackPropertyNameChange);
+    ReadOptionFromRegistry(trackPropertyDescriptionChange);
+    ReadOptionFromRegistry(trackPropertyStateChange);
+    ReadOptionFromRegistry(trackPropertyValueChange);
+    ReadOptionFromRegistry(trackPropertySelectionChange);
+    ReadOptionFromRegistry(trackPropertyTextChange);
+    ReadOptionFromRegistry(trackPropertyCaretChange);
+    ReadOptionFromRegistry(trackPropertyVisibleDataChange);
+    ReadOptionFromRegistry(trackPropertyChildChange);
+    ReadOptionFromRegistry(trackPropertyActiveDescendentChange);
+    ReadOptionFromRegistry(trackPropertyTableModelChange);
+
+    ::RegCloseKey(hKey);
+
+    if ( 0 == failureCount ) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+#define APPLY_EVENT_OPTION(menuItem, optionVar, setFP, handler) \
+{ \
+    if ( optionVar ) { \
+        ::CheckMenuItem(menu, menuItem, MF_BYCOMMAND | MF_CHECKED); \
+        setFP (handler); \
+    } else { \
+        ::CheckMenuItem(menu, menuItem, MF_BYCOMMAND | MF_UNCHECKED); \
+        setFP (NULL); \
+    } \
+}
+
+void ApplyEventOptions (HWND hWnd) {
+
+    HMENU menu = ::GetMenu (hWnd);
+    APPLY_EVENT_OPTION( cTrackMouseMenuItem, trackMouse, SetMouseEntered,
+                        HandleMouseEntered );
+    APPLY_EVENT_OPTION( cTrackMouseExitedMenuItem, trackMouseExited,
+                        SetMouseExited, HandleMouseExited );
+    APPLY_EVENT_OPTION( cTrackMouseClickedMenuItem, trackMouseClicked,
+                        SetMouseClicked, HandleMouseClicked );
+    APPLY_EVENT_OPTION( cTrackMousePressedMenuItem, trackMousePressed,
+                        SetMousePressed, HandleMousePressed );
+    APPLY_EVENT_OPTION( cTrackMouseReleasedMenuItem, trackMouseReleased,
+                        SetMouseReleased, HandleMouseReleased );
+
+    APPLY_EVENT_OPTION( cTrackShutdownMenuItem, trackShutdown, SetJavaShutdown,
+                        HandleJavaShutdown );
+    APPLY_EVENT_OPTION( cTrackFocusMenuItem, trackFocus, SetFocusGained,
+                        HandleJavaFocusGained );
+    APPLY_EVENT_OPTION( cTrackFocusLostMenuItem, trackFocusLost, SetFocusLost,
+                        HandleJavaFocusLost );
+    APPLY_EVENT_OPTION( cTrackCaretMenuItem, trackCaret, SetCaretUpdate,
+                        HandleJavaCaretUpdate );
+
+    APPLY_EVENT_OPTION( cTrackMenuSelectedMenuItem, trackMenuSelected,
+                        SetMenuSelected, HandleMenuSelected );
+    APPLY_EVENT_OPTION( cTrackMenuDeselectedMenuItem, trackMenuDeselected,
+                        SetMenuDeselected, HandleMenuDeselected );
+    APPLY_EVENT_OPTION( cTrackMenuCanceledItem, trackMenuCanceled,
+                        SetMenuCanceled, HandleMenuCanceled );
+
+    APPLY_EVENT_OPTION( cTrackPopupBecomeVisibleMenuItem, trackPopupVisible,
+                        SetPopupMenuWillBecomeVisible,
+                        HandlePopupMenuWillBecomeVisible );
+    APPLY_EVENT_OPTION( cTrackPopupBecomeInvisibleMenuItem, trackPopupInvisible,
+                        SetPopupMenuWillBecomeInvisible,
+                        HandlePopupMenuWillBecomeInvisible );
+    APPLY_EVENT_OPTION( cTrackPopupCanceledItem, trackPopupCanceled,
+                        SetPopupMenuCanceled, HandlePopupMenuCanceled );
+
+    APPLY_EVENT_OPTION( cTrackPropertyNameItem, trackPropertyNameChange,
+                        SetPropertyNameChange, HandlePropertyNameChange );
+    APPLY_EVENT_OPTION( cTrackPropertyDescriptionItem,
+                        trackPropertyDescriptionChange,
+                        SetPropertyDescriptionChange,
+                        HandlePropertyDescriptionChange );
+    APPLY_EVENT_OPTION( cTrackPropertyStateItem, trackPropertyStateChange,
+                        SetPropertyStateChange, HandlePropertyStateChange );
+    APPLY_EVENT_OPTION( cTrackPropertyValueItem, trackPropertyValueChange,
+                        SetPropertyValueChange, HandlePropertyValueChange );
+    APPLY_EVENT_OPTION( cTrackPropertySelectionItem,
+                        trackPropertySelectionChange,
+                        SetPropertySelectionChange,
+                        HandlePropertySelectionChange);
+    APPLY_EVENT_OPTION( cTrackPropertyTextItem, trackPropertyTextChange,
+                        SetPropertyTextChange, HandlePropertyTextChange );
+    APPLY_EVENT_OPTION( cTrackPropertyCaretItem, trackPropertyCaretChange,
+                        SetPropertyCaretChange, HandlePropertyCaretChange );
+    APPLY_EVENT_OPTION( cTrackPropertyVisibleDataItem,
+                        trackPropertyVisibleDataChange,
+                        SetPropertyVisibleDataChange,
+                        HandlePropertyVisibleDataChange );
+    APPLY_EVENT_OPTION( cTrackPropertyChildItem, trackPropertyChildChange,
+                        SetPropertyChildChange, HandlePropertyChildChange );
+    APPLY_EVENT_OPTION( cTrackPropertyActiveDescendentItem,
+                        trackPropertyActiveDescendentChange,
+                        SetPropertyActiveDescendentChange,
+                        HandlePropertyActiveDescendentChange );
+    APPLY_EVENT_OPTION( cTrackPropertyTableModelChangeItem,
+                        trackPropertyTableModelChange,
+                        SetPropertyTableModelChange,
+                        HandlePropertyTableModelChange );
+
+    MaybeCheckMonitorTheSameEventsAsJAWS(menu);
+    MaybeCheckMonitorAllEvents(menu);
+}
+
+BOOL EnableDlgItem(HWND hDlg, int nIDDlgItem, BOOL bEnable) {
+    HWND dlgItem = ::GetDlgItem(hDlg, nIDDlgItem);
+    if ( NULL == dlgItem ) {
+        return FALSE;
+    }
+    return ::EnableWindow (dlgItem, bEnable);
+}
+
+void EnableMessageNavButtons() {
+    HWND FocusWindow = ::GetFocus();
+    int FocusCtrlID = ::GetDlgCtrlID(FocusWindow);
+    BOOL DisabledFocusWindow = FALSE;
+    if ( 0 == g_MessageHistory.GetMessageCount () ) {
+        EnableDlgItem(theDialogWindow, cFirstMessage, FALSE);
+        EnableDlgItem(theDialogWindow, cPreviousMessage, FALSE);
+        EnableDlgItem(theDialogWindow, cMessageNumber, FALSE);
+        EnableDlgItem(theDialogWindow, cNextMessage, FALSE);
+        EnableDlgItem(theDialogWindow, cLastMessage, FALSE);
+    } else if ( g_MessageHistory.IsFirstMessage () ) {
+        EnableDlgItem(theDialogWindow, cFirstMessage, FALSE);
+        EnableDlgItem(theDialogWindow, cPreviousMessage, FALSE);
+        EnableDlgItem(theDialogWindow, cMessageNumber, TRUE);
+        EnableDlgItem(theDialogWindow, cNextMessage, TRUE);
+        EnableDlgItem(theDialogWindow, cLastMessage, TRUE);
+        if ( ( cFirstMessage == FocusCtrlID ) ||
+             ( cPreviousMessage == FocusCtrlID ) ) {
+            DisabledFocusWindow = TRUE;
+        }
+    } else if ( g_MessageHistory.IsLastMessage () ) {
+        EnableDlgItem(theDialogWindow, cFirstMessage, TRUE);
+        EnableDlgItem(theDialogWindow, cPreviousMessage, TRUE);
+        EnableDlgItem(theDialogWindow, cMessageNumber, TRUE);
+        EnableDlgItem(theDialogWindow, cNextMessage, FALSE);
+        EnableDlgItem(theDialogWindow, cLastMessage, FALSE);
+
+        if ( ( cNextMessage == FocusCtrlID ) ||
+             ( cLastMessage == FocusCtrlID ) ) {
+            DisabledFocusWindow = TRUE;
+        }
+    } else {
+        EnableDlgItem(theDialogWindow, cFirstMessage, TRUE);
+        EnableDlgItem(theDialogWindow, cPreviousMessage, TRUE);
+        EnableDlgItem(theDialogWindow, cMessageNumber, TRUE);
+        EnableDlgItem(theDialogWindow, cNextMessage, TRUE);
+        EnableDlgItem(theDialogWindow, cLastMessage, TRUE);
+    }
+
+    if ( DisabledFocusWindow ) {
+        /*
+        We just disabled the window that had the focus.  Set focus to the
+        cjaccessinspectorText window.  Otherwise it will no longer be possible
+        to tab through the controls in jaccessinspector.
+        */
+        HWND jaccessinspectorText =
+            ::GetDlgItem(theDialogWindow, cjaccessinspectorText);
+        if ( jaccessinspectorText ) {
+            ::SetFocus(jaccessinspectorText);
+        }
+    }
+}
+
+void WINAPI AddToMessageHistory(const char * message) {
+    g_MessageHistory.AddMessage(message);
+    EnableMessageNavButtons();
+    UpdateMessageNumber();
+}
+
+BOOL UpdateMessageNumber () {
+    HWND dlgItem = ::GetDlgItem(theDialogWindow, cMessageNumber);
+    if ( NULL == dlgItem ) {
+        return FALSE;
+    }
+
+    size_t messageCount = g_MessageHistory.GetMessageCount();
+    size_t messageNumber = g_MessageHistory.GetCurrentMessageIndex() + 1;
+    char text [32] = {0};
+    if ( 0 != messageCount ) {
+        ::_snprintf(text, sizeof(text), "%d of %d", messageNumber, messageCount);
+    }
+    return ::SetWindowText(dlgItem, text);
+}
+
+INT_PTR CALLBACK GoToMessageDialogProc( HWND hDlg, UINT message, WPARAM wParam,
+                                        LPARAM lParam ) {
+    BOOL ret_val = FALSE;
+    switch ( message ) {
+    case WM_INITDIALOG:
+        {
+            /*
+            This code to center the Go To Message dialog box in the
+            jaccessinspector window was taken from
+            <http://msdn.microsoft.com/en-us/library/ms644996(VS.85).aspx>.
+            */
+            HWND hwndOwner = NULL;
+            RECT rcOwner = { 0, 0, 0, 0 };
+            RECT rc = { 0, 0, 0, 0 };
+            RECT rcDlg = { 0, 0, 0, 0 };
+
+            // Get the owner window and dialog box rectangles.
+            if ( NULL == (hwndOwner = GetParent(hDlg)) ) {
+                hwndOwner = GetDesktopWindow();
+            }
+
+            GetWindowRect(hwndOwner, &rcOwner);
+            GetWindowRect(hDlg, &rcDlg);
+            CopyRect(&rc, &rcOwner);
+
+            // Offset the owner and dialog box rectangles so that right and
+            // bottom values represent the width and height, and then offset
+            // the owner again to discard space taken up by the dialog box.
+            OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
+            OffsetRect(&rc, -rc.left, -rc.top);
+            OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
+
+            // The new position is the sum of half the remaining space and the
+            // owner's original position.
+            SetWindowPos (hDlg,
+                HWND_TOP,
+                rcOwner.left + (rc.right / 2),
+                rcOwner.top + (rc.bottom / 2),
+                0, 0,  // Ignores size arguments.
+                SWP_NOSIZE);
+        }
+        break;
+
+    case WM_COMMAND:
+        switch ( LOWORD (wParam) ) {
+        case IDOK:
+            {
+                size_t GoToMessageNumber = 0;
+                BOOL Translated = FALSE;
+                GoToMessageNumber = GetDlgItemInt( hDlg, IDC_MESSAGE_NUMBER_EDIT,
+                                                   &Translated, FALSE );
+                EndDialog (hDlg, IDOK);
+                theGoToDialogWindow = NULL;
+
+                if ( ( Translated ) && ( GoToMessageNumber > 0 ) ) {
+                    const char * messageText = NULL;
+                    if ( (GoToMessageNumber - 1) <
+                         g_MessageHistory.GetMessageCount() ) {
+                        messageText =
+                            g_MessageHistory.GetMessage(GoToMessageNumber - 1);
+                    } else if ( (GoToMessageNumber - 1) >=
+                                g_MessageHistory.GetMessageCount() ) {
+                        messageText = g_MessageHistory.GetLastMessage();
+                    }
+                    if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {
+                        ::SetDlgItemText( theDialogWindow, cjaccessinspectorText,
+                                          messageText );
+                    }
+                    EnableMessageNavButtons();
+                    UpdateMessageNumber();
+                }
+            }
+            break;
+        case IDCANCEL:
+            EndDialog(hDlg, IDCANCEL);
+            theGoToDialogWindow = NULL;
+            break;
+        }
+        break;
+    }
+    return ret_val;
+}
+
+BOOL InitGoToMessageDialogBox (HANDLE hInstance) {
+    theGoToDialogWindow = CreateDialog (
+        (struct HINSTANCE__ *)hInstance, MAKEINTRESOURCE(IDD_GO_TO_MESSAGE),
+        theDialogWindow, GoToMessageDialogProc);
+
+    if ( NULL == theGoToDialogWindow ) {
+        return FALSE;
+    }
+
+    ShowWindow (theGoToDialogWindow, SW_SHOW);
+    return TRUE;
+}
+
+BOOL ShouldCheckMonitorTheSameEventsAsJAWS () {
+    if (
+        ( FALSE == trackMouse )
+        && ( FALSE == trackMouseExited )
+        && ( FALSE == trackMouseClicked )
+        && ( FALSE == trackMousePressed )
+        && ( FALSE == trackMouseReleased )
+        && ( TRUE == trackFocus )
+        && ( TRUE == trackFocusLost )
+        && ( FALSE == trackCaret )
+        && ( FALSE == trackShutdown )
+        && ( FALSE == trackMenuSelected )
+        && ( FALSE == trackMenuDeselected )
+        && ( FALSE == trackMenuCanceled )
+        && ( FALSE == trackPopupVisible )
+        && ( FALSE == trackPopupInvisible )
+        && ( FALSE == trackPopupCanceled )
+        && ( TRUE == trackPropertyNameChange )
+        && ( TRUE == trackPropertyDescriptionChange )
+        && ( TRUE == trackPropertyStateChange )
+        && ( TRUE == trackPropertyValueChange )
+        && ( TRUE == trackPropertySelectionChange )
+        && ( TRUE == trackPropertyTextChange )
+        && ( TRUE == trackPropertyCaretChange )
+        && ( FALSE == trackPropertyVisibleDataChange )
+        && ( TRUE == trackPropertyChildChange )
+        && ( TRUE == trackPropertyActiveDescendentChange )
+        && ( FALSE == trackPropertyTableModelChange )
+        )
+    {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+void MaybeCheckMonitorTheSameEventsAsJAWS(HMENU menu) {
+    UINT uCheck = MF_BYCOMMAND | MF_UNCHECKED;
+    if ( ShouldCheckMonitorTheSameEventsAsJAWS() ) {
+        uCheck = MF_BYCOMMAND | MF_CHECKED;
+    }
+    ::CheckMenuItem(menu, cMonitorTheSameEventsAsJAWS, uCheck);
+}
+
+BOOL ShouldCheckMonitorAllEvents() {
+    if (
+        ( TRUE == trackMouse )
+        && ( TRUE == trackMouseExited )
+        && ( TRUE == trackMouseClicked )
+        && ( TRUE == trackMousePressed )
+        && ( TRUE == trackMouseReleased )
+        && ( TRUE == trackFocus )
+        && ( TRUE == trackFocusLost )
+        && ( TRUE == trackCaret )
+        && ( TRUE == trackShutdown )
+        && ( TRUE == trackMenuSelected )
+        && ( TRUE == trackMenuDeselected )
+        && ( TRUE == trackMenuCanceled )
+        && ( TRUE == trackPopupVisible )
+        && ( TRUE == trackPopupInvisible )
+        && ( TRUE == trackPopupCanceled )
+        && ( TRUE == trackPropertyNameChange )
+        && ( TRUE == trackPropertyDescriptionChange )
+        && ( TRUE == trackPropertyStateChange )
+        && ( TRUE == trackPropertyValueChange )
+        && ( TRUE == trackPropertySelectionChange )
+        && ( TRUE == trackPropertyTextChange )
+        && ( TRUE == trackPropertyCaretChange )
+        && ( TRUE == trackPropertyVisibleDataChange )
+        && ( TRUE == trackPropertyChildChange )
+        && ( TRUE == trackPropertyActiveDescendentChange )
+        && ( TRUE == trackPropertyTableModelChange )
+        )
+    {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+void MaybeCheckMonitorAllEvents(HMENU menu) {
+    UINT uCheck = MF_BYCOMMAND | MF_UNCHECKED;
+    if ( ShouldCheckMonitorAllEvents() ) {
+        uCheck = MF_BYCOMMAND | MF_CHECKED;
+    }
+    ::CheckMenuItem(menu, cMonitorAllEvents, uCheck);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.h	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+#define JACCESSINSPECTOR_LOG "jaccessinspector.log"
+
+void CALLBACK TimerProc(HWND hWnd, UINT uTimerMsg, UINT uTimerID, DWORD dwTime);
+LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam);
+
+BOOL InitWindow(HANDLE hInstance);
+INT_PTR CALLBACK jaccessinspectorDialogProc( HWND hDlg, UINT message,
+                                             WPARAM wParam, LPARAM lParam );
+
+void HandleJavaPropertyChange( long vmID, PropertyChangeEvent event,
+                               AccessibleContext ac,
+                               wchar_t *name, wchar_t *oldValue,
+                               wchar_t *newValue );
+
+void HandleJavaShutdown(long vmID);
+void HandleJavaFocusGained(long vmID, FocusEvent event, AccessibleContext ac);
+void HandleJavaFocusLost(long vmID, FocusEvent event, AccessibleContext ac);
+
+void HandleJavaCaretUpdate(long vmID, CaretEvent event, AccessibleContext ac);
+
+void HandleMouseClicked(long vmID, MouseEvent event, AccessibleContext ac);
+void HandleMouseEntered(long vmID, MouseEvent event, AccessibleContext ac);
+void HandleMouseExited(long vmID, MouseEvent event, AccessibleContext ac);
+void HandleMousePressed(long vmID, MouseEvent event, AccessibleContext ac);
+void HandleMouseReleased(long vmID, MouseEvent event, AccessibleContext ac);
+
+void HandleMenuCanceled(long vmID, MenuEvent event, AccessibleContext ac);
+void HandleMenuDeselected(long vmID, MenuEvent event, AccessibleContext ac);
+void HandleMenuSelected(long vmID, MenuEvent event, AccessibleContext ac);
+void HandlePopupMenuCanceled(long vmID, MenuEvent event, AccessibleContext ac);
+void HandlePopupMenuWillBecomeInvisible( long vmID, MenuEvent event,
+                                         AccessibleContext ac );
+void HandlePopupMenuWillBecomeVisible( long vmID, MenuEvent event,
+                                       AccessibleContext ac );
+
+void HandlePropertyNameChange( long vmID, PropertyChangeEvent event,
+                               AccessibleContext ac,
+                               wchar_t *oldName, wchar_t *newName);
+void HandlePropertyDescriptionChange( long vmID, PropertyChangeEvent event,
+                                      AccessibleContext ac,
+                                      wchar_t *oldDescription,
+                                      wchar_t *newDescription );
+void HandlePropertyStateChange( long vmID, PropertyChangeEvent event,
+                                AccessibleContext ac,
+                                wchar_t *oldState, wchar_t *newState );
+void HandlePropertyValueChange( long vmID, PropertyChangeEvent event,
+                                AccessibleContext ac,
+                                wchar_t *oldValue, wchar_t *newValue );
+void HandlePropertySelectionChange( long vmID, PropertyChangeEvent event,
+                                    AccessibleContext ac );
+void HandlePropertyTextChange( long vmID, PropertyChangeEvent event,
+                               AccessibleContext ac );
+void HandlePropertyCaretChange( long vmID, PropertyChangeEvent event,
+                                AccessibleContext ac,
+                                int oldPosition, int newPosition );
+void HandlePropertyVisibleDataChange( long vmID, PropertyChangeEvent event,
+                                      AccessibleContext ac );
+void HandlePropertyChildChange( long vmID, PropertyChangeEvent event,
+                                AccessibleContext ac,
+                                jobject oldChild, jobject newChild );
+void HandlePropertyActiveDescendentChange(long vmID, PropertyChangeEvent event,
+                                          AccessibleContext ac,
+                                          jobject oldActiveDescendent,
+                                          jobject newActiveDescendent);
+
+void HandlePropertyTableModelChange( long vmID, PropertyChangeEvent event,
+                                     AccessibleContext ac,
+                                     wchar_t *oldValue, wchar_t *newValue );
+
+char *getAccessibleInfo( long vmID, AccessibleContext ac,
+                         int x, int y, char *buffer, int bufsize );
+
+char *getTimeAndDate();
+void displayAndLogText(char *buffer, ...);
+
+const char * const jaccessinspectorOptionsRegistryKey =
+    "Software\\JavaSoft\\Java Development Kit\\jaccessinspector";
+BOOL SaveActiveEventOptionsToRegistry();
+BOOL ReadActiveEventOptionsFromRegistry();
+void ApplyEventOptions(HWND hWnd);
+BOOL EnableDlgItem(HWND hDlg, int nIDDlgItem, BOOL bEnable);
+void EnableMessageNavButtons();
+void WINAPI AddToMessageHistory(const char * message);
+BOOL UpdateMessageNumber();
+INT_PTR CALLBACK GoToMessageDialogProc( HWND hDlg, UINT message, WPARAM wParam,
+                                        LPARAM lParam );
+BOOL InitGoToMessageDialogBox(HANDLE hInstance);
+BOOL ShouldCheckMonitorTheSameEventsAsJAWS();
+void MaybeCheckMonitorTheSameEventsAsJAWS(HMENU menu);
+BOOL ShouldCheckMonitorAllEvents();
+void MaybeCheckMonitorAllEvents(HMENU menu);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorResource.h	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+#define IDR_ACCELERATOR                 102
+#define IDD_GO_TO_MESSAGE               103
+#define cjaccessinspectorText           1001
+#define cFirstMessage                   1029
+#define cPreviousMessage                1030
+#define cNextMessage                    1031
+#define cLastMessage                    1032
+#define cMessageNumber                  1033
+#define IDC_MESSAGE_NUMBER_EDIT         1034
+#define cFerretMenus                    10000
+#define cFileMenu                       10100
+#define cAccessBridgeDLLLoaded          10101
+#define cExitMenuItem                   10102
+#define cJavaEventsMenu                 10200
+#define cTrackMouseMenuItem             10201
+#define cTrackFocusMenuItem             10203
+#define cTrackCaretMenuItem             10204
+#define cTrackMenuSelectedMenuItem      10205
+#define cTrackMenuDeselectedMenuItem    10206
+#define cTrackMenuCanceledItem          10207
+#define cTrackPopupBecomeVisibleMenuItem 10208
+#define cTrackPopupBecomeInvisibleMenuItem 10209
+#define cTrackPopupCanceledItem         10210
+#define cUpdateSettingsMenu             10300
+#define cUpdateWithF1Item               10301
+#define cUpdateWithF2Item               10302
+#define cUpdateFromMouseMenuItem        10304
+#define cAccessibilityEventsMenu        10400
+#define cTrackPropertyNameItem          10401
+#define cTrackPropertyDescriptionItem   10402
+#define cTrackPropertyStateItem         10403
+#define cTrackPropertyValueItem         10404
+#define cTrackPropertySelectionItem     10405
+#define cTrackPropertyTextItem          10406
+#define cTrackPropertyCaretItem         10407
+#define cTrackPropertyVisibleDataItem   10408
+#define cTrackPropertyChildItem         10409
+#define cTrackPropertyActiveDescendentItem 10410
+#define cTrackPropertyTableModelChangeItem 10411
+#define cTrackShutdownMenuItem          10412
+#define cMonitorTheSameEventsAsJAWS     10413
+#define cTrackFocusLostMenuItem         10414
+#define cTrackMouseExitedMenuItem       10415
+#define cTrackMouseClickedMenuItem      10416
+#define cTrackMousePressedMenuItem      10417
+#define cTrackMouseReleasedMenuItem     10418
+#define cResetAllEvents                 10419
+#define cGoToMessage                    10420
+#define cClearMessageHistory            10421
+#define cMonitorAllEvents               10422
+#define IDC_STATIC                      -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        104
+#define _APS_NEXT_COMMAND_VALUE         10423
+#define _APS_NEXT_CONTROL_VALUE         1035
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorWindow.rc	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,249 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "jaccessinspectorResource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+JACCESSINSPECTORWINDOW DIALOG  160, 78, 354, 214
+STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+CAPTION "jaccessinspector"
+MENU cjaccessinspectorMenus
+FONT 8, "MS Sans Serif"
+BEGIN
+    EDITTEXT        cjaccessinspectorText,4,24,340,184,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL
+    PUSHBUTTON      "&First Message",cFirstMessage,4,4,60,14
+    PUSHBUTTON      "&Previous Message",cPreviousMessage,70,4,60,14
+    EDITTEXT        cMessageNumber,134,4,80,14,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY
+    PUSHBUTTON      "&Next Message",cNextMessage,218,4,60,14
+    PUSHBUTTON      "&Last Message",cLastMessage,284,4,60,14
+END
+
+IDD_GO_TO_MESSAGE DIALOGEX 0, 0, 186, 66
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
+CAPTION "Go To Message"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    LTEXT           "Message Number:",IDC_STATIC,14,14,64,8
+    EDITTEXT        IDC_MESSAGE_NUMBER_EDIT,80,14,90,14,ES_AUTOHSCROLL | ES_NUMBER
+    DEFPUSHBUTTON   "OK",IDOK,35,45,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,101,45,50,14
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+    "jaccessinspectorResource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+    "JACCESSINSPECTORWINDOW", DIALOG
+    BEGIN
+        LEFTMARGIN, 4
+        RIGHTMARGIN, 347
+    END
+
+    IDD_GO_TO_MESSAGE, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 179
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 59
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+cjaccessinspectorMenus MENU
+BEGIN
+    POPUP "File"
+    BEGIN
+        MENUITEM "AccessBridge DLL Loaded",     cAccessBridgeDLLLoaded
+        MENUITEM "Exit",                        cExitMenuItem
+    END
+    POPUP "UpdateSettings"
+    BEGIN
+        MENUITEM "Update from Mouse",           cUpdateFromMouseMenuItem
+        MENUITEM "Update with F2 (mouse HWND)", cUpdateWithF2Item
+        MENUITEM "Update with F1 (mouse point)", cUpdateWithF1Item
+    END
+    POPUP "JavaEvents"
+    BEGIN
+        MENUITEM "Track Java Shutdown Events",  cTrackShutdownMenuItem
+        MENUITEM SEPARATOR
+        MENUITEM "Track Mouse Entered Events",  cTrackMouseMenuItem
+        MENUITEM "Track Mouse Exited Events",   cTrackMouseExitedMenuItem
+        MENUITEM "Track Mouse Clicked Events",  cTrackMouseClickedMenuItem
+        MENUITEM "Track Mouse Pressed Events",  cTrackMousePressedMenuItem
+        MENUITEM "Track Mouse Released Events", cTrackMouseReleasedMenuItem
+        MENUITEM SEPARATOR
+        MENUITEM "Track Focus Gained Events",   cTrackFocusMenuItem
+        MENUITEM "Track Focus Lost Events",     cTrackFocusLostMenuItem
+        MENUITEM "Track Caret Events",          cTrackCaretMenuItem
+        MENUITEM SEPARATOR
+        MENUITEM "Track Menu Selected Events",  cTrackMenuSelectedMenuItem
+        MENUITEM "Track Menu Deselected Events", cTrackMenuDeselectedMenuItem
+        MENUITEM "Track Menu Canceled Events",  cTrackMenuCanceledItem
+        MENUITEM "Track Popup Visible Events",  cTrackPopupBecomeVisibleMenuItem
+        MENUITEM "Track Popup Inviible Events", cTrackPopupBecomeInvisibleMenuItem
+        MENUITEM "Track Popup Canceled Events", cTrackPopupCanceledItem
+    END
+    POPUP "AccessibilityEvents"
+    BEGIN
+        MENUITEM "Track Name Property Events",  cTrackPropertyNameItem
+        MENUITEM "Track Description Property Events", cTrackPropertyDescriptionItem
+        MENUITEM "Track State Property Events", cTrackPropertyStateItem
+        MENUITEM "Track Value Property Events", cTrackPropertyValueItem
+        MENUITEM "Track Selection Property Events", cTrackPropertySelectionItem
+        MENUITEM "Track Text Property Events",  cTrackPropertyTextItem
+        MENUITEM "Track Caret Property Events", cTrackPropertyCaretItem
+        MENUITEM "Track Visible Data Property Events", cTrackPropertyVisibleDataItem
+        MENUITEM "Track Child Property Events", cTrackPropertyChildItem
+        MENUITEM "Track Active Descendent Property Events", cTrackPropertyActiveDescendentItem
+        MENUITEM "Track Table Model Change Property Events", cTrackPropertyTableModelChangeItem
+    END
+    POPUP "&Options"
+    BEGIN
+        MENUITEM "&Monitor the same events as JAWS", cMonitorTheSameEventsAsJAWS
+        MENUITEM "Monitor &All Events",         cMonitorAllEvents
+        MENUITEM "&Reset All Events",           cResetAllEvents
+        MENUITEM "&Go To Message",              cGoToMessage
+        MENUITEM "&Clear Message History",      cClearMessageHistory
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+// Need 2 defines so macro argument to XSTR will get expanded before quoting.
+#define XSTR(x) STR(x)
+#define STR(x)  #x
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION    JDK_FVER
+ PRODUCTVERSION JDK_FVER
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only
+ FILEOS 0x4L
+ // FILETYPE should be 0x1 for .exe and 0x2 for .dll
+ FILETYPE JDK_FTYPE
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "000004b0"
+        BEGIN
+            VALUE "CompanyName",      XSTR(JDK_COMPANY)       "\0"
+            VALUE "FileDescription",  XSTR(JDK_COMPONENT)     "\0"
+            VALUE "FileVersion",      XSTR(JDK_VER)           "\0"
+            VALUE "Full Version",     XSTR(JDK_BUILD_ID)      "\0"
+            VALUE "InternalName",     XSTR(JDK_INTERNAL_NAME) "\0"
+            VALUE "LegalCopyright",   XSTR(JDK_COPYRIGHT)     "\0"
+            VALUE "OriginalFilename", XSTR(JDK_FNAME)         "\0"
+            VALUE "ProductName",      XSTR(JDK_NAME)          "\0"
+            VALUE "ProductVersion",   XSTR(JDK_VER)           "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x0, 1200
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_ACCELERATOR ACCELERATORS
+BEGIN
+    VK_HOME,        cFirstMessage,          VIRTKEY, CONTROL, ALT, NOINVERT
+    "G",            cGoToMessage,           VIRTKEY, CONTROL, NOINVERT
+    VK_END,         cLastMessage,           VIRTKEY, CONTROL, ALT, NOINVERT
+    VK_NEXT,        cNextMessage,           VIRTKEY, CONTROL, NOINVERT
+    VK_PRIOR,       cPreviousMessage,       VIRTKEY, CONTROL, NOINVERT
+    "X",            cClearMessageHistory,   VIRTKEY, CONTROL, NOINVERT
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,648 @@
+/*
+ * 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.
+ */
+
+#include "jaccesswalker.h"
+#include "AccessInfo.h"
+
+HWND ourHwnd;
+HWND topLevelWindow;
+int depth = -1;
+FILE *logfile;
+HMENU popupMenu;
+
+char theJaccesswalkerClassName[] = "JaccesswalkerWin";
+char theAccessInfoClassName[] = "AccessInfoWin";
+
+HWND theJaccesswalkerWindow;
+HWND theTreeControlWindow;
+HINSTANCE theInstance;
+Jaccesswalker *theJaccesswalker;
+AccessibleNode *theSelectedNode;
+AccessibleNode *thePopupNode;
+AccessibleContext theSelectedAccessibleContext;
+HWND hwndTV;    // handle of tree-view control
+
+int APIENTRY WinMain(HINSTANCE hInstance,
+                     HINSTANCE hPrevInstance,
+                     LPSTR     lpCmdLine,
+                     int       nCmdShow)
+{
+
+    if (logfile == null) {
+        logfile = fopen(JACCESSWALKER_LOG, "w"); // overwrite existing log file
+        logString(logfile, "Starting jaccesswalker.exe %s\n", getTimeAndDate());
+    }
+
+    theInstance = hInstance;
+
+    // start Jaccesswalker
+    theJaccesswalker = new Jaccesswalker(nCmdShow);
+
+    return 0;
+}
+
+Jaccesswalker::Jaccesswalker(int nCmdShow) {
+
+    HWND hwnd;
+    static char szAppName[] = "jaccesswalker";
+    static char szMenuName[] = "JACCESSWALKERMENU";
+    MSG msg;
+    WNDCLASSEX wc;
+
+    // jaccesswalker window
+    wc.cbSize = sizeof(wc);
+    wc.style = CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc = WinProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = theInstance;
+    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+    wc.hCursor = LoadCursor(NULL, IDI_APPLICATION);
+    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+    wc.lpszMenuName = szMenuName;
+    wc.lpszClassName = szAppName;
+    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+
+    RegisterClassEx(&wc);
+
+    // AccessInfo Window
+    wc.cbSize = sizeof(WNDCLASSEX);
+
+    wc.hInstance = theInstance;
+    wc.lpszClassName = theAccessInfoClassName;
+    wc.lpfnWndProc = (WNDPROC)AccessInfoWindowProc;
+    wc.style = 0;
+
+    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+
+    wc.lpszMenuName = "";
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+
+    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+
+    RegisterClassEx(&wc);
+
+    // create the jaccesswalker window
+    hwnd = CreateWindow(szAppName,
+                        szAppName,
+                        WS_OVERLAPPEDWINDOW,
+                        CW_USEDEFAULT,
+                        CW_USEDEFAULT,
+                        CW_USEDEFAULT,
+                        CW_USEDEFAULT,
+                        NULL,
+                        NULL,
+                        theInstance,
+                        NULL);
+
+    ourHwnd = hwnd;
+
+    /* Initialize the common controls. */
+    INITCOMMONCONTROLSEX cc;
+    cc.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    cc.dwICC = ICC_TREEVIEW_CLASSES;
+    InitCommonControlsEx(&cc);
+
+    ShowWindow(hwnd, nCmdShow);
+
+    UpdateWindow(hwnd);
+
+    BOOL result = initializeAccessBridge();
+    if (result != FALSE) {
+        while (GetMessage(&msg, NULL, 0, 0)) {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+        shutdownAccessBridge();
+    }
+}
+
+/*
+ * the jaccesswalker window proc
+ */
+LRESULT CALLBACK WinProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
+
+    int command;
+    short width, height;
+
+    switch(iMsg) {
+
+    case WM_CREATE:
+        // create the accessibility tree view
+        theTreeControlWindow = CreateATreeView(hwnd);
+
+        // load the popup menu
+        popupMenu = LoadMenu(theInstance, "PopupMenu");
+        popupMenu = GetSubMenu(popupMenu, 0);
+        break;
+
+    case WM_CLOSE:
+        EndDialog(hwnd, TRUE);
+        PostQuitMessage (0);
+        break;
+
+    case WM_SIZE:
+        width = LOWORD(lParam);
+        height = HIWORD(lParam);
+        SetWindowPos(theTreeControlWindow, NULL, 0, 0, width, height, 0);
+        return FALSE;  // let windows finish handling this
+
+    case WM_COMMAND:
+        command = LOWORD(wParam);
+        switch(command) {
+
+        case cExitMenuItem:
+            EndDialog(hwnd, TRUE);
+            PostQuitMessage (0);
+            break;
+
+        case cRefreshTreeItem:
+            // update the accessibility tree
+            theJaccesswalker->buildAccessibilityTree();
+            break;
+
+        case cAPIMenuItem:
+            // open a new window with the Accessibility API in it for the
+            // selected element in the tree
+            if (theSelectedNode != (AccessibleNode *) 0) {
+                theSelectedNode->displayAPIWindow();
+            }
+            break;
+
+        case cAPIPopupItem:
+            // open a new window with the Accessibility API in it for the
+            // element in the tree adjacent to the popup menu
+            if (thePopupNode != (AccessibleNode *) 0) {
+                thePopupNode->displayAPIWindow();
+            }
+            break;
+
+        }
+        break;
+
+    case WM_NOTIFY:  // receive tree messages
+
+        NMTREEVIEW *nmptr = (LPNMTREEVIEW) lParam;
+        switch (nmptr->hdr.code) {
+
+        case TVN_SELCHANGED:
+            // get the selected tree node
+            theSelectedNode = (AccessibleNode *) nmptr->itemNew.lParam;
+            break;
+
+        case NM_RCLICK:
+
+            // display a popup menu over the tree node
+            POINT p;
+            GetCursorPos(&p);
+            TrackPopupMenu(popupMenu, 0, p.x, p.y, 0, hwnd, NULL);
+
+            // get the tree node under the popup menu
+            TVHITTESTINFO hitinfo;
+            ScreenToClient(theTreeControlWindow, &p);
+            hitinfo.pt = p;
+            HTREEITEM node = TreeView_HitTest(theTreeControlWindow, &hitinfo);
+
+            if (node != null) {
+                TVITEMEX tvItem;
+                tvItem.hItem = node;
+                if (TreeView_GetItem(hwndTV, &tvItem) == TRUE) {
+                    thePopupNode = (AccessibleNode *)tvItem.lParam;
+                }
+            }
+            break;
+        }
+    }
+    return DefWindowProc(hwnd, iMsg, wParam, lParam);
+}
+
+/*
+ * Accessibility information window proc
+ */
+LRESULT CALLBACK AccessInfoWindowProc(HWND hWnd, UINT message,
+                                    UINT wParam, LONG lParam) {
+    short width, height;
+    HWND dlgItem;
+
+    switch (message) {
+    case WM_CREATE:
+        RECT rcClient;    // dimensions of client area
+        HWND hwndEdit;    // handle of tree-view control
+
+        // Get the dimensions of the parent window's client area,
+        // and create the edit control.
+        GetClientRect(hWnd, &rcClient);
+        hwndEdit = CreateWindow("Edit",
+                                "",
+                                WS_VISIBLE | WS_TABSTOP | WS_CHILD |
+                                ES_MULTILINE | ES_AUTOVSCROLL |
+                                ES_READONLY | WS_VSCROLL,
+                                0, 0, rcClient.right, rcClient.bottom,
+                                hWnd,
+                                (HMENU) cAccessInfoText,
+                                theInstance,
+                                NULL);
+        break;
+
+    case WM_CLOSE:
+        DestroyWindow(hWnd);
+        break;
+
+    case WM_SIZE:
+        width = LOWORD(lParam);
+        height = HIWORD(lParam);
+        dlgItem = GetDlgItem(hWnd, cAccessInfoText);
+        SetWindowPos(dlgItem, NULL, 0, 0, width, height, 0);
+        return FALSE;  // let windows finish handling this
+        break;
+
+    default:
+        return DefWindowProc(hWnd, message, wParam, lParam);
+    }
+
+    return 0;
+}
+
+/**
+ * Build a tree (and the treeview control) of all accessible Java components
+ *
+ */
+void Jaccesswalker::buildAccessibilityTree() {
+    TreeView_DeleteAllItems (theTreeControlWindow);
+    // have MS-Windows call EnumWndProc() with all of the top-level windows
+    EnumWindows((WNDENUMPROC) EnumWndProc, NULL);
+}
+
+/**
+ * Create (and display) the accessible component nodes of a parent AccessibleContext
+ *
+ */
+BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam) {
+    if (IsJavaWindow(hwnd)) {
+        long vmID;
+        AccessibleContext ac;
+        if (GetAccessibleContextFromHWND(hwnd, &vmID, &ac) == TRUE) {
+            theJaccesswalker->addComponentNodes(vmID, ac, (AccessibleNode *) NULL,
+                                         hwnd, TVI_ROOT, theTreeControlWindow);
+        }
+        topLevelWindow = hwnd;
+    } else {
+        char szClass [MAX_PATH] = {0};
+        ::GetClassNameA(hwnd, szClass, sizeof(szClass) - 1);
+        if ( ( 0 == ::strcmp(szClass, "IEFrame") )
+             || ( 0 == ::strcmp(szClass, "MozillaUIWindowClass") ) ) {
+            EnumChildWindows(hwnd, (WNDENUMPROC) EnumChildProc, NULL);
+        }
+    }
+    return TRUE;
+}
+
+/*
+Detects whether or not the specified Java window is one from which no useable
+information can be obtained.
+
+This function tests for various scenarios I have seen in Java applets where the
+Java applet had no meaningful accessible information.  It does not detect all
+scenarios, just the most common ones.
+*/
+BOOL IsInaccessibleJavaWindow(const HWND hwnd)
+{
+    BOOL ret_val ( FALSE );
+    {
+        BOOL bT ( FALSE );
+        long vmIdWindow ( 0 );
+        AccessibleContext acWindow ( 0 );
+        bT = GetAccessibleContextFromHWND(hwnd, &vmIdWindow, &acWindow);
+        if ( ( bT ) && ( 0 != vmIdWindow ) && ( 0 != acWindow ) ) {
+            AccessibleContextInfo infoWindow = {0};
+            bT = GetAccessibleContextInfo(vmIdWindow, acWindow, &infoWindow);
+            if ( ( bT )
+                 && ( 0 == infoWindow.name [0] )
+                 && ( 0 == infoWindow.description [0] )
+                 && ( 0 == ::wcscmp(infoWindow.role_en_US, L"frame") ) ) {
+                if ( 0 == infoWindow.childrenCount ) {
+                    ret_val = TRUE;
+                } else if ( 1 == infoWindow.childrenCount ) {
+                    AccessibleContext acChild ( 0 );
+                    acChild =
+                        GetAccessibleChildFromContext(vmIdWindow, acWindow, 0);
+                    if ( NULL != acChild ) {
+                        AccessibleContextInfo infoChild = {0};
+                        bT = GetAccessibleContextInfo( vmIdWindow, acChild,
+                                                       &infoChild );
+                        if ( ( bT )
+                             && ( 0 == infoChild.name [0] )
+                             && ( 0 == infoChild.description [0] )
+                             && ( 0 == ::wcscmp(infoChild.role_en_US, L"panel") )
+                             && ( 1 == infoChild.childrenCount ) ) {
+                            AccessibleContext acChild1 ( 0 );
+                            acChild1 = GetAccessibleChildFromContext( vmIdWindow,
+                                                                      acChild, 0);
+                            if ( NULL != acChild1 ) {
+                                AccessibleContextInfo infoChild1 = {0};
+                                bT = GetAccessibleContextInfo( vmIdWindow,
+                                                               acChild1, &infoChild1 );
+                                if ( ( bT )
+                                     && ( 0 == infoChild1.name [0] )
+                                     && ( 0 == infoChild1.description [0] )
+                                     && ( 0 == ::wcscmp(infoChild1.role_en_US, L"frame") )
+                                     && ( 0 == infoChild1.childrenCount ) ) {
+                                    ret_val = TRUE;
+                                } else if ( ( bT )
+                                            && ( 0 == infoChild1.name [0] )
+                                            && ( 0 == infoChild1.description [0] )
+                                            && ( 0 == ::wcscmp( infoChild1.role_en_US,
+                                                                L"panel") )
+                                            && ( 1 == infoChild1.childrenCount ) ) {
+                                    AccessibleContext acChild2 ( 0 );
+                                    acChild2 = GetAccessibleChildFromContext(
+                                                    vmIdWindow, acChild1, 0 );
+                                    if ( NULL != acChild2 ) {
+                                        AccessibleContextInfo infoChild2 = {0};
+                                        bT = GetAccessibleContextInfo(
+                                                vmIdWindow, acChild2, &infoChild2 );
+                                        if ( ( bT )
+                                             && ( 0 == infoChild2.name [0] )
+                                             && ( 0 == infoChild2.description [0] )
+                                             && ( 0 == ::wcscmp( infoChild2.role_en_US,
+                                                                 L"frame") )
+                                             && ( 0 == infoChild2.childrenCount ) ) {
+                                            ret_val = TRUE;
+                                        }
+                                    }
+                                }
+                            }
+                        } else if ( ( bT )
+                                    && ( 0 == infoChild.name [0] )
+                                    && ( 0 == infoChild.description [0] )
+                                    && ( 0 == ::wcscmp( infoChild.role_en_US,
+                                                        L"canvas") )
+                                    && ( 0 == infoChild.childrenCount ) ) {
+                            ret_val = TRUE;
+                        }
+                    }
+                }
+            } else if ( ( bT )
+                        && ( 0 == infoWindow.name [0] )
+                        && ( 0 == infoWindow.description [0] )
+                        && ( 0 == ::wcscmp(infoWindow.role_en_US, L"panel") ) ) {
+                if ( 1 == infoWindow.childrenCount ) {
+                    AccessibleContext acChild ( 0 );
+                    acChild = GetAccessibleChildFromContext( vmIdWindow,
+                                                             acWindow, 0 );
+                    if ( NULL != acChild ) {
+                        AccessibleContextInfo infoChild = {0};
+                        bT = GetAccessibleContextInfo( vmIdWindow,
+                                                       acChild, &infoChild );
+                        if ( ( bT )
+                             && ( 0 == infoChild.name [0] )
+                             && ( 0 == infoChild.description [0] )
+                             && ( 0 == ::wcscmp(infoChild.role_en_US, L"frame") )
+                             && ( 0 == infoChild.childrenCount ) ) {
+                                ret_val = TRUE;
+                        } else if ( ( bT )
+                                    && ( 0 == infoChild.name [0] )
+                                    && ( 0 == infoChild.description [0] )
+                                    && ( 0 == ::wcscmp( infoChild.role_en_US,
+                                                        L"panel") )
+                                    && ( 1 == infoChild.childrenCount ) ) {
+                            AccessibleContext acChild1 ( 0 );
+                            acChild1 = GetAccessibleChildFromContext( vmIdWindow,
+                                                                      acChild, 0);
+                            if ( NULL != acChild1 ) {
+                                AccessibleContextInfo infoChild1 = {0};
+                                bT = GetAccessibleContextInfo( vmIdWindow,
+                                                               acChild1,
+                                                               &infoChild1 );
+                                if ( ( bT )
+                                     && ( 0 == infoChild1.name [0] )
+                                     && ( 0 == infoChild1.description [0] )
+                                     && ( 0 == ::wcscmp( infoChild1.role_en_US,
+                                                         L"frame") )
+                                     && ( 0 == infoChild1.childrenCount ) ) {
+                                    ret_val = TRUE;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } else if ( FALSE == bT ) {
+            ret_val = TRUE;
+        }
+    }
+    return ret_val;
+}
+
+BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
+{
+    if ( ( IsJavaWindow(hwnd) )
+         && ( FALSE == IsInaccessibleJavaWindow(hwnd) ) ) {
+        long vmID ( 0 );
+        AccessibleContext ac ( 0 );
+        if ( TRUE == GetAccessibleContextFromHWND(hwnd, &vmID, &ac) ) {
+            theJaccesswalker->addComponentNodes(
+                vmID, ac, (AccessibleNode *) NULL,
+                hwnd, TVI_ROOT, theTreeControlWindow);
+        }
+        topLevelWindow = hwnd;
+    } else {
+        EnumChildWindows(hwnd, (WNDENUMPROC) EnumChildProc, NULL);
+    }
+    return TRUE;
+}
+
+// CreateATreeView - creates a tree-view control.
+// Returns the handle of the new control if successful or NULL
+//     otherwise.
+// hwndParent - handle of the control's parent window
+HWND CreateATreeView(HWND hwndParent) {
+    RECT rcClient;  // dimensions of client area
+
+    // Get the dimensions of the parent window's client area, and create
+    // the tree-view control.
+    GetClientRect(hwndParent, &rcClient);
+    hwndTV = CreateWindow(WC_TREEVIEW,
+                          "",
+                          WS_VISIBLE | WS_TABSTOP | WS_CHILD |
+                          TVS_HASLINES | TVS_HASBUTTONS |
+                          TVS_LINESATROOT,
+                          0, 0, rcClient.right, rcClient.bottom,
+                          hwndParent,
+                          (HMENU) cTreeControl,
+                          theInstance,
+                          NULL);
+
+    return hwndTV;
+}
+
+/**
+ * Create (and display) the accessible component nodes of a parent AccessibleContext
+ *
+ */
+void Jaccesswalker::addComponentNodes(long vmID, AccessibleContext context,
+                                    AccessibleNode *parent, HWND hwnd,
+                                    HTREEITEM treeNodeParent, HWND treeWnd) {
+
+    AccessibleNode *newNode = new AccessibleNode( vmID, context, parent, hwnd,
+                                                  treeNodeParent );
+
+    AccessibleContextInfo info;
+    if (GetAccessibleContextInfo(vmID, context, &info) != FALSE) {
+        char s[LINE_BUFSIZE];
+
+        wsprintf(s, "%ls", info.name);
+        newNode->setAccessibleName(s);
+        wsprintf(s, "%ls", info.role);
+        newNode->setAccessibleRole(s);
+
+        wsprintf(s, "%ls [%ls]", info.name, info.role);
+
+        TVITEM tvi;
+        tvi.mask = TVIF_PARAM | TVIF_TEXT;
+        tvi.pszText = (char *) s; // Accessible name and role
+        tvi.cchTextMax = (int)strlen(s);
+        tvi.lParam = (long) newNode; // Accessibility information
+
+        TVINSERTSTRUCT tvis;
+        tvis.hParent = treeNodeParent;
+        tvis.hInsertAfter = TVI_LAST;
+        tvis.item = tvi;
+
+        HTREEITEM treeNodeItem = TreeView_InsertItem(treeWnd, &tvis);
+
+        for (int i = 0; i < info.childrenCount; i++) {
+            addComponentNodes(vmID, GetAccessibleChildFromContext(vmID, context, i),
+                              newNode, hwnd, treeNodeItem, treeWnd);
+        }
+    } else {
+        char s[LINE_BUFSIZE];
+        sprintf( s,
+            "ERROR calling GetAccessibleContextInfo; vmID = %X, context = %X",
+            vmID, context );
+
+        TVITEM tvi;
+        tvi.mask = TVIF_PARAM | TVIF_TEXT;  // text and lParam are only valid parts
+        tvi.pszText = (char *) s;
+        tvi.cchTextMax = (int)strlen(s);
+        tvi.lParam = (long) newNode;
+
+        TVINSERTSTRUCT tvis;
+        tvis.hParent = treeNodeParent;
+        tvis.hInsertAfter = TVI_LAST;  // make tree in order given
+        tvis.item = tvi;
+
+        HTREEITEM treeNodeItem = TreeView_InsertItem(treeWnd, &tvis);
+    }
+}
+
+// -----------------------------
+
+/**
+ * Create an AccessibleNode
+ *
+ */
+AccessibleNode::AccessibleNode(long JavaVMID, AccessibleContext context,
+                               AccessibleNode *parent, HWND hwnd,
+                               HTREEITEM parentTreeNodeItem) {
+    vmID = JavaVMID;
+    ac = context;
+    parentNode = parent;
+    baseHWND = hwnd;
+    treeNodeParent = parentTreeNodeItem;
+
+    // setting accessibleName and accessibleRole not done here,
+    // in order to minimize calls to the AccessBridge
+    // (since such a call is needed to enumerate children)
+}
+
+/**
+ * Destroy an AccessibleNode
+ *
+ */
+AccessibleNode::~AccessibleNode() {
+    ReleaseJavaObject(vmID, ac);
+}
+
+/**
+ * Set the accessibleName string
+ *
+ */
+void AccessibleNode::setAccessibleName(char *name) {
+    strncpy(accessibleName, name, MAX_STRING_SIZE);
+}
+
+/**
+ * Set the accessibleRole string
+ *
+ */
+void AccessibleNode::setAccessibleRole(char *role) {
+    strncpy(accessibleRole, role, SHORT_STRING_SIZE);
+}
+
+
+
+
+
+
+
+/**
+ * Create an API window to show off the info for this AccessibleContext
+ */
+BOOL AccessibleNode::displayAPIWindow() {
+
+    HWND apiWindow = CreateWindow(theAccessInfoClassName,
+                                  "Java Accessibility API view",
+                                  WS_OVERLAPPEDWINDOW,
+                                  CW_USEDEFAULT,
+                                  CW_USEDEFAULT,
+                                  600,
+                                  750,
+                                  HWND_DESKTOP,
+                                  NULL,
+                                  theInstance,
+                                  (void *) NULL);
+
+    if (!apiWindow) {
+        printError("cannot create API window");
+        return FALSE;
+    }
+
+    char buffer[HUGE_BUFSIZE];
+    buffer[0] = '\0';
+    getAccessibleInfo(vmID, ac, buffer, sizeof(buffer));
+    displayAndLog(apiWindow, cAccessInfoText, logfile, buffer);
+
+    ShowWindow(apiWindow, SW_SHOWNORMAL);
+    UpdateWindow(apiWindow);
+
+    return TRUE;
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.h	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#include <windows.h>   // includes basic windows functionality
+#include <stdio.h>
+#include <commctrl.h>
+#include <jni.h>
+#include "jaccesswalkerResource.h"
+#include "AccessBridgeCalls.h"
+#include "AccessBridgeCallbacks.h"
+#include "AccessBridgeDebug.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <io.h>
+#include <direct.h>
+#include <process.h>
+
+#include <time.h>
+
+extern FILE *file;
+
+#define null NULL
+#define JACCESSWALKER_LOG "jaccesswalker.log"
+
+/**
+ * A node in the jaccesswalker tree
+ */
+class AccessibleNode {
+
+    HWND baseHWND;
+    HTREEITEM treeNodeParent;
+    long vmID;
+    AccessibleContext ac;
+    AccessibleNode *parentNode;
+    char accessibleName[MAX_STRING_SIZE];
+    char accessibleRole[SHORT_STRING_SIZE];
+
+public:
+    AccessibleNode(long vmID, AccessibleContext context,
+                   AccessibleNode *parent, HWND hWnd,
+                   HTREEITEM parentTreeNodeItem);
+    ~AccessibleNode();
+    void setAccessibleName(char *name);
+    void setAccessibleRole(char *role);
+    BOOL displayAPIWindow();  // bring up an Accessibility API detail window
+};
+
+
+/**
+ * The main application class
+ */
+class Jaccesswalker {
+
+public:
+    Jaccesswalker(int nCmdShow);
+    BOOL InitWindow(int windowMode);
+    char *getAccessibleInfo( long vmID, AccessibleContext ac, char *buffer,
+                             int bufsize );
+    void exitjaccesswalker(HWND hWnd);
+    void buildAccessibilityTree();
+    void addComponentNodes( long vmID, AccessibleContext context,
+                            AccessibleNode *parent, HWND hWnd,
+                            HTREEITEM treeNodeParent, HWND treeWnd );
+};
+
+char *getTimeAndDate();
+
+void displayAndLogText(char *buffer, ...);
+
+LRESULT CALLBACK WinProc (HWND, UINT, WPARAM, LPARAM);
+
+void debugString(char *msg, ...);
+
+LRESULT CALLBACK jaccesswalkerWindowProc( HWND hDlg, UINT message, UINT wParam,
+                                          LONG lParam );
+
+BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam);
+BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam);
+
+HWND CreateATreeView(HWND hwndParent);
+
+LRESULT CALLBACK AccessInfoWindowProc( HWND hWnd, UINT message, UINT wParam,
+                                       LONG lParam );
+
+char *getAccessibleInfo( long vmID, AccessibleContext ac, char *buffer,
+                         int bufsize );
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerResource.h	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#define cTreeControl                    1001
+#define cAccessInfoText                 2001
+#define cMonkeyMenus                    10000
+#define cFileMenu                       10100
+#define cRefreshTreeItem                10101
+#define cExitMenuItem                   10103
+#define cSettingsMenu                   10200
+#define cAPIMenuItem                    10201
+#define cAPIPopupItem                   10202
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_COMMAND_VALUE         40003
+#define _APS_NEXT_CONTROL_VALUE         1032
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerWindow.rc	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,182 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "jaccesswalkerResource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+JACCESSWALKERWINDOW DIALOG DISCARDABLE  160, 78, 294, 214
+STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |
+    WS_THICKFRAME
+CAPTION "jaccesswalker"
+MENU 10000
+FONT 8, "MS Sans Serif"
+BEGIN
+    CONTROL         "Tree1",cTreeControl,"SysTreeView32",TVS_HASBUTTONS |
+                    TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP |
+                    WS_BORDER | WS_TABSTOP,4,0,283,214
+END
+
+EXPLORERWINDOW DIALOG DISCARDABLE  160, 78, 294, 214
+STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |
+    WS_THICKFRAME
+CAPTION "Java Accessibility Information"
+MENU 10000
+FONT 8, "MS Sans Serif"
+BEGIN
+    EDITTEXT        cAccessInfoText,4,0,283,214,ES_MULTILINE | ES_AUTOVSCROLL |
+                    ES_READONLY | WS_VSCROLL
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "jaccesswalkerResource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+    "JACCESSWALKERWINDOW", DIALOG
+    BEGIN
+        LEFTMARGIN, 4
+        RIGHTMARGIN, 287
+    END
+
+    "ACCESSINFOWINDOW", DIALOG
+    BEGIN
+        LEFTMARGIN, 4
+        RIGHTMARGIN, 287
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+JACCESSWALKERMENU MENU DISCARDABLE
+BEGIN
+    POPUP "File"
+    BEGIN
+        MENUITEM "Refresh Tree",                cRefreshTreeItem
+        MENUITEM SEPARATOR
+        MENUITEM "Exit",                        cExitMenuItem
+    END
+    POPUP "Panels"
+    BEGIN
+        MENUITEM "Display Accessibility Information",     cAPIMenuItem
+    END
+END
+
+
+PopupMenu MENU
+    {
+    POPUP ""
+        {
+        MENUITEM "Display Accessibility Information",     cAPIPopupItem
+        }
+    }
+
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+// Need 2 defines so macro argument to XSTR will get expanded before quoting.
+#define XSTR(x) STR(x)
+#define STR(x)  #x
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION    JDK_FVER
+ PRODUCTVERSION JDK_FVER
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only
+ FILEOS 0x4L
+ // FILETYPE should be 0x1 for .exe and 0x2 for .dll
+ FILETYPE JDK_FTYPE
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "000004b0"
+        BEGIN
+            VALUE "CompanyName",      XSTR(JDK_COMPANY)       "\0"
+            VALUE "FileDescription",  XSTR(JDK_COMPONENT)     "\0"
+            VALUE "FileVersion",      XSTR(JDK_VER)           "\0"
+            VALUE "Full Version",     XSTR(JDK_BUILD_ID)      "\0"
+            VALUE "InternalName",     XSTR(JDK_INTERNAL_NAME) "\0"
+            VALUE "LegalCopyright",   XSTR(JDK_COPYRIGHT)     "\0"
+            VALUE "OriginalFilename", XSTR(JDK_FNAME)         "\0"
+            VALUE "ProductName",      XSTR(JDK_NAME)          "\0"
+            VALUE "ProductVersion",   XSTR(JDK_VER)           "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x0, 1200
+    END
+END
--- a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp	Fri Nov 20 16:44:33 2015 +0400
+++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp	Fri Nov 20 17:54:58 2015 -0600
@@ -3487,10 +3487,15 @@
 
     // Get the index at the given point
     if (getAccessibleIndexAtPointFromContextMethod != (jmethodID) 0) {
-        textInfo->indexAtPoint = jniEnv->CallIntMethod(accessBridgeObject,
-                                                       getAccessibleIndexAtPointFromContextMethod,
-                                                       accessibleContext, x, y);
-        EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE);
+        // If x or y is -1 return -1
+        if (x == -1 || y == -1) {
+            textInfo->indexAtPoint = -1;
+        } else {
+            textInfo->indexAtPoint = jniEnv->CallIntMethod(accessBridgeObject,
+                                                           getAccessibleIndexAtPointFromContextMethod,
+                                                           accessibleContext, x, y);
+            EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE);
+        }
         PrintDebugString("  Index at point = %d", textInfo->indexAtPoint);
     } else {
         PrintDebugString("  Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/toolscommon/AccessInfo.cpp	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,948 @@
+/*
+ * 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.
+ */
+
+#include "AccessBridgeCalls.h"
+#include "AccessInfo.h"
+#include <stdio.h>
+#include <time.h>
+
+LogStringCallbackFP g_LogStringCallback = NULL;
+
+/*
+ * returns formatted date and time
+ */
+char *getTimeAndDate() {
+    static char datebuf[64];
+    struct tm *newtime;
+    char am_pm[] = "AM";
+    time_t long_time;
+
+    time( &long_time );                /* Get time as long integer. */
+    newtime = localtime( &long_time ); /* Convert to local time. */
+
+    if( newtime->tm_hour > 12 )        /* Set up extension. */
+        strcpy( am_pm, "PM" );
+    if( newtime->tm_hour > 12 )        /* Convert from 24-hour */
+                newtime->tm_hour -= 12;    /*   to 12-hour clock.  */
+    if( newtime->tm_hour == 0 )        /*Set hour to 12 if midnight. */
+        newtime->tm_hour = 12;
+
+    sprintf(datebuf, "%.19s %s\n", asctime( newtime ), am_pm );
+    return (char *)datebuf;
+}
+
+
+/*
+ * displays a message in a dialog and writes the message to a logfile
+ */
+void displayAndLog(HWND hDlg, int nIDDlgItem, FILE *logfile, char *msg, ...) {
+
+    if (hDlg == NULL || msg == NULL) {
+        return;
+    }
+
+    char tmpbuf[HUGE_BUFSIZE];
+    va_list argprt;
+
+    va_start(argprt, msg);
+    vsprintf(tmpbuf, msg, argprt);
+
+    SetDlgItemText(hDlg, nIDDlgItem, tmpbuf);
+
+    fprintf(logfile, "\n****************************************\n");
+    fprintf(logfile, "%s\n", getTimeAndDate());
+    fprintf(logfile, "%s\n", tmpbuf);
+    fflush(logfile);
+
+    if ( NULL != g_LogStringCallback )
+    {
+        g_LogStringCallback (tmpbuf);
+    }
+}
+
+/*
+ * writes a text string to a logfile
+ */
+void logString(FILE *logfile, char *msg, ...) {
+
+    if (logfile == NULL || msg == NULL) {
+        return;
+    }
+
+    char tmpbuf[LINE_BUFSIZE];
+    va_list argprt;
+
+    va_start(argprt, msg);
+    vsprintf(tmpbuf, msg, argprt);
+
+    fprintf(logfile, tmpbuf);
+    fprintf(logfile, "\n");
+    fflush(logfile);
+}
+
+/*
+ * safely appends a message to a buffer
+ */
+BOOL appendToBuffer(char *buf, size_t buflen, char *msg, ...) {
+
+    static char warning[] =
+        "\nNot enough buffer space; remaining information truncated.\n";
+    size_t warningLength = strlen(warning) + 1;
+
+    if (buf == NULL || msg == NULL) {
+        return FALSE;
+    }
+
+    char tmpbuf[LARGE_BUFSIZE];
+    va_list argprt;
+
+    va_start(argprt, msg);
+    vsprintf(tmpbuf, msg, argprt);
+
+    // verify there's enough space in the buffer
+    size_t spaceRemaining = buflen - strlen(buf) - 1;
+    if (spaceRemaining <= warningLength) {
+        strncat(buf, warning, spaceRemaining);
+        return FALSE;
+    }
+    strncat(buf, tmpbuf, spaceRemaining);
+    return TRUE;
+}
+
+/**
+ * returns accessibility information for an AccessibleContext
+ */
+char *getAccessibleInfo(long vmID, AccessibleContext ac, char *buffer,
+                        int bufsize) {
+    return getAccessibleInfo(vmID, ac, 0, 0, buffer, bufsize);
+}
+
+/**
+ * returns accessibility information at the specified coordinates in an
+ * AccessibleContext
+ */
+char *getAccessibleInfo(long vmID, AccessibleContext ac, int x, int y,
+                        char *buffer, int bufsize) {
+
+    wchar_t tmpBuf[LINE_BUFSIZE];
+    wchar_t name[LINE_BUFSIZE];
+    int i, j;
+    long start;
+    long end;
+
+    if (buffer == NULL || bufsize <= 0) {
+        return NULL;
+    }
+    buffer[0] = NULL;
+
+    /* ===== AccessBridge / J2SE version information ===== */
+
+    AccessBridgeVersionInfo versionInfo;
+    BOOL result = GetVersionInfo(vmID, &versionInfo);
+
+    if (result == FALSE) {
+        appendToBuffer( buffer, bufsize,
+                        "\r\nERROR: cannot get version information", bufsize );
+    } else {
+        appendToBuffer(buffer, bufsize, "Version Information:");
+        appendToBuffer( buffer, bufsize,
+                        "\r\n    Java virtual machine version: %ls",
+                        versionInfo.VMversion );
+        appendToBuffer( buffer, bufsize,
+                        "\r\n    Access Bridge Java class version: %ls",
+                        versionInfo.bridgeJavaClassVersion );
+        appendToBuffer( buffer, bufsize,
+                        "\r\n    Access Bridge Java DLL version: %ls",
+                        versionInfo.bridgeJavaDLLVersion );
+        appendToBuffer( buffer, bufsize,
+                        "\r\n    Access Bridge Windows DLL version: %ls",
+                        versionInfo.bridgeWinDLLVersion );
+    }
+
+    if (ac == (AccessibleContext) 0) {
+        return buffer;
+    }
+
+
+    /* ===== core AccessibleContext information ===== */
+
+    AccessibleContextInfo info;
+    if (GetAccessibleContextInfo(vmID, ac, &info) == FALSE) {
+        appendToBuffer( buffer, bufsize,
+                        "\r\nERROR: GetAccessibleContextInfo failed ", bufsize );
+    } else {
+        appendToBuffer( buffer, bufsize,
+                        "\r\n\r\nAccessibleContext information", bufsize );
+        if (x >= 0 && y >= 0) {
+            appendToBuffer(buffer, bufsize, " at mouse point [%d, %d]:", x, y);
+        } else {
+            appendToBuffer(buffer, bufsize, ":", bufsize);
+        }
+
+        appendToBuffer(buffer, bufsize, "\r\n    Name:  %ls", info.name);
+        if ( getVirtualAccessibleName( vmID, ac, name,
+                                       (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) {
+            appendToBuffer( buffer, bufsize,
+                            "\r\n\r\nERROR: getVirtualAccessibleName", bufsize );
+        } else {
+            appendToBuffer(buffer, bufsize, "\r\n    Virtual Name:  %ls", name);
+        }
+        appendToBuffer( buffer, bufsize, "\r\n    Description:  %ls",
+                        info.description );
+        appendToBuffer(buffer, bufsize, "\r\n    Role:  %ls", info.role);
+        appendToBuffer( buffer, bufsize, "\r\n    Role in en_US locale:  %ls",
+                        info.role_en_US );
+        appendToBuffer(buffer, bufsize, "\r\n    States:  %ls", info.states);
+        appendToBuffer( buffer, bufsize, "\r\n    States in en_US locale:  %ls",
+                        info.states_en_US );
+        appendToBuffer( buffer, bufsize, "\r\n    Index in parent:  %d",
+                        info.indexInParent );
+        appendToBuffer( buffer, bufsize, "\r\n    Children count:  %d",
+                        info.childrenCount );
+        appendToBuffer( buffer, bufsize,
+                        "\r\n    Bounding rectangle:  [%d, %d, %d, %d]",
+                        info.x, info.y, info.x + info.width,
+                        info.y + info.height );
+
+        /*  top-level window info */
+        AccessibleContext topAC  = getTopLevelObject(vmID, ac);
+        if (topAC == NULL) {
+            appendToBuffer( buffer, bufsize,
+                            "\r\nERROR: getTopLevelObject failed", bufsize );
+        } else {
+            AccessibleContextInfo topInfo;
+            if (GetAccessibleContextInfo(vmID, topAC, &topInfo) == FALSE) {
+                appendToBuffer(
+                    buffer, bufsize,
+                    "\r\nERROR: GetAccessibleContextInfo failed for top-level window ",
+                    bufsize );
+            } else {
+                if (getVirtualAccessibleName(vmID, topAC, name,
+                        (sizeof(name) / sizeof(wchar_t)) ) == FALSE) {
+                    appendToBuffer( buffer, bufsize,
+                                    "\r\n\r\nERROR: getVirtualAccessibleName",
+                                    bufsize );
+                } else {
+                    appendToBuffer( buffer, bufsize,
+                                    "\r\n    Top-level window name:  %ls",
+                                    name );
+                }
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Top-level window role:  %ls",
+                                topInfo.role ) ;
+            }
+            ReleaseJavaObject(vmID, topAC);
+
+        }
+
+        /* ===== AccessibleParent information ===== */
+
+        AccessibleContext parentAC = GetAccessibleParentFromContext(vmID, ac);
+        if (parentAC == NULL) {
+            appendToBuffer(buffer, bufsize, "\r\n    No parent", bufsize);
+        } else {
+            AccessibleContextInfo parentInfo;
+            if (GetAccessibleContextInfo(vmID, parentAC, &parentInfo) == FALSE) {
+                appendToBuffer( buffer, bufsize,
+                    "\r\nERROR: GetAccessibleContextInfo failed for parent",
+                    bufsize );
+            } else {
+                appendToBuffer( buffer, bufsize, "\r\n    Parent name:  %ls",
+                                parentInfo.name );
+                if ( getVirtualAccessibleName( vmID, parentAC, name,
+                        (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) {
+                    appendToBuffer( buffer, bufsize,
+                                    "\r\n\r\nERROR: getVirtualAccessibleName",
+                                    bufsize );
+                } else {
+                    appendToBuffer( buffer, bufsize,
+                                    "\r\n    Parent virtual name:  %ls", name );
+                }
+                appendToBuffer( buffer, bufsize, "\r\n    Parent role:  %ls",
+                                parentInfo.role );
+            }
+            ReleaseJavaObject(vmID, parentAC);
+        }
+
+
+        /* ====== visible children ===== */
+        int nChildren = getVisibleChildrenCount(vmID, ac);
+        if (nChildren == -1) {
+            appendToBuffer( buffer, bufsize,
+                            "\r\nERROR: GetVisibleChildrenCount failed",
+                            bufsize );
+        } else {
+            appendToBuffer( buffer, bufsize,
+                            "\r\n    Visible descendents count:  %d",
+                            nChildren );
+        }
+
+        if (nChildren > 0) {
+            VisibleChildrenInfo visibleChildrenInfo;
+            if (getVisibleChildren(vmID, ac, 0, &visibleChildrenInfo) == FALSE) {
+                appendToBuffer( buffer, bufsize,
+                                "\r\nERROR: GetVisibleChildren failed",
+                                bufsize );
+            } else {
+                AccessibleContextInfo childACInfo;
+                for ( int child = 0;
+                      child < visibleChildrenInfo.returnedChildrenCount;
+                      child++ ) {
+                    AccessibleContext childAC =
+                        visibleChildrenInfo.children[child];
+                    if (GetAccessibleContextInfo(vmID, childAC, &childACInfo)) {
+                        if ( getVirtualAccessibleName( vmID, childAC, name,
+                                (sizeof(name) / sizeof(wchar_t))) == FALSE) {
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n\r\nERROR: getVirtualAccessibleName",
+                                bufsize );
+                        } else {
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n    Descendent %d name:  %ls", child,
+                                name );
+                        }
+                        appendToBuffer( buffer, bufsize,
+                                        "\r\n    Descendent %d role:  %ls",
+                                        child, childACInfo.role );
+                    }
+                    ReleaseJavaObject(vmID, childAC);
+                }
+            }
+        }
+
+        /* ===== AccessibleSelection ===== */
+
+        if (info.accessibleSelection == TRUE) {
+
+            int selCount;
+            AccessibleContext selectedAC;
+
+            appendToBuffer( buffer, bufsize,
+                            "\r\n\r\nAccessible Selection information:",
+                            bufsize );
+
+            if ((selCount = GetAccessibleSelectionCountFromContext(vmID, ac)) != -1) {
+                appendToBuffer( buffer, bufsize, "\r\n    Selection count:  %d",
+                                selCount );
+
+                for (i = 0; i < selCount; i++) {
+                    if ( ( selectedAC =
+                            GetAccessibleSelectionFromContext(vmID, ac, i) ) == NULL ) {
+                        appendToBuffer( buffer, bufsize,
+                            "\r\nERROR: GetAccessibleSelectionFromContext failed forselection %d",
+                            i );
+                    } else {
+                        if (GetAccessibleContextInfo(vmID, selectedAC, &info) == FALSE) {
+                            appendToBuffer( buffer, bufsize,
+                                "\r\nERROR: GetAccessibleContextInfo failed for selection %d", i);
+                        } else {
+                            if ( getVirtualAccessibleName( vmID, selectedAC, name,
+                                    (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) {
+                                appendToBuffer( buffer, bufsize,
+                                    "\r\n\r\nERROR: getVirtualAccessibleName", bufsize);
+                            } else {
+                                appendToBuffer( buffer, bufsize,
+                                    "\r\n    Selection %d name: %ls", i, name );
+                            }
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n    Selection %d role: %ls", i, info.role);
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n    Index in parent of selection %d: %d",
+                                i, info.indexInParent );
+                        }
+                        ReleaseJavaObject(vmID, selectedAC);
+                    }
+                }
+            }
+        }
+
+        // ====== Accessible KeyBindings, Icons and Actions ======
+
+        AccessibleKeyBindings keyBindings;
+        if (getAccessibleKeyBindings(vmID, ac, &keyBindings) == TRUE &&
+            keyBindings.keyBindingsCount > 0) {
+
+            appendToBuffer( buffer, bufsize,
+                            "\r\n\r\nAccessibleKeyBinding info:", bufsize );
+            appendToBuffer( buffer, bufsize,
+                            "\r\n    Number of key bindings:  %d",
+                            keyBindings.keyBindingsCount );
+
+            for (j = 0; j < keyBindings.keyBindingsCount; j++) {
+
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Key binding %d character: %c", j,
+                                keyBindings.keyBindingInfo[j].character );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Key binding %d modifiers: %d", j,
+                                keyBindings.keyBindingInfo[j].modifiers );
+            }
+        }
+
+        AccessibleIcons icons;
+        if (getAccessibleIcons(vmID, ac, &icons) == TRUE &&
+            icons.iconsCount > 0) {
+
+            appendToBuffer( buffer, bufsize,
+                            "\r\n\r\nAccessibleIcons info:", bufsize );
+            appendToBuffer( buffer, bufsize,
+                            "\r\n    Number of icons:  %d", icons.iconsCount );
+
+            for (j = 0; j < icons.iconsCount; j++) {
+
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Icon %d description: %ls", j,
+                                icons.iconInfo[j].description );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Icon %d height: %d", j,
+                                icons.iconInfo[j].height );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Icon %d width: %d", j,
+                                icons.iconInfo[j].width );
+            }
+        }
+
+        AccessibleActions actions;
+        if (getAccessibleActions(vmID, ac, &actions) == TRUE &&
+            actions.actionsCount > 0) {
+
+            appendToBuffer( buffer, bufsize, "\r\n\r\nAccessibleActions info:",
+                            bufsize );
+            appendToBuffer( buffer, bufsize, "\r\n    Number of actions:  %d",
+                            actions.actionsCount );
+
+            for (j = 0; j < actions.actionsCount; j++) {
+                appendToBuffer( buffer, bufsize, "\r\n    Action %d name: %ls",
+                                j, actions.actionInfo[j].name );
+            }
+        }
+
+        /* ===== AccessibleRelationSet ===== */
+
+        AccessibleRelationSetInfo relationSetInfo;
+        if (getAccessibleRelationSet(vmID, ac, &relationSetInfo) == FALSE) {
+            appendToBuffer( buffer, bufsize,
+                            "\r\nGetAccessibleRelationSet failed.", bufsize );
+        } else {
+            int i;
+            AccessibleContextInfo relInfo;
+
+            if (relationSetInfo.relationCount > 0) {
+                appendToBuffer( buffer, bufsize,
+                                "\r\n\r\nAccessibleRelationSet information:",
+                                bufsize );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Number of relations:  %d",
+                                relationSetInfo.relationCount );
+            }
+            for (i = 0; i < relationSetInfo.relationCount; i++) {
+                AccessibleRelationInfo relationInfo =
+                    relationSetInfo.relations[i];
+
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Relation %d key:  %ls", i,
+                                relationInfo.key );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Relation %d target count:  %d", i,
+                                relationInfo.targetCount );
+                for (j = 0; j < relationInfo.targetCount; j++) {
+                    if (GetAccessibleContextInfo(
+                            vmID, relationInfo.targets[j], &relInfo ) == FALSE) {
+                        appendToBuffer( buffer, bufsize,
+                            "\r\nERROR: GetAccessibleContextInfo failed.",
+                            bufsize );
+                    } else {
+                        // Core AccessibleContext information for relation target
+                        if ( getVirtualAccessibleName( vmID, relationInfo.targets[j],
+                                name, (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) {
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n\r\nERROR: getVirtualAccessibleName", bufsize );
+                        } else {
+                            appendToBuffer( buffer, bufsize,
+                                            "\r\n        Target %d name:  %ls",
+                                            j, name );
+                        }
+                        appendToBuffer( buffer, bufsize,
+                                        "\r\n        Target %d role:  %ls", j,
+                                        relInfo.role);
+                    }
+                    ReleaseJavaObject(vmID, relationInfo.targets[j]);
+
+                }
+            }
+        }
+
+        /* ===== AccessibleValue ===== */
+
+        if (info.accessibleInterfaces & cAccessibleValueInterface) {
+
+            appendToBuffer( buffer, bufsize,
+                            "\r\n\r\nAccessible Value information:", bufsize);
+
+            if ( GetCurrentAccessibleValueFromContext( vmID, ac, tmpBuf,
+                    (sizeof(tmpBuf) / sizeof(wchar_t)) ) == TRUE ) {
+                appendToBuffer( buffer, bufsize, "\r\n    Current Value:  %ls",
+                                tmpBuf );
+            }
+            if ( GetMaximumAccessibleValueFromContext( vmID, ac, tmpBuf,
+                    (sizeof(tmpBuf) / sizeof(wchar_t))) == TRUE ) {
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Maximum Value:  %ls", tmpBuf );
+            }
+            if ( GetMinimumAccessibleValueFromContext( vmID, ac, tmpBuf,
+                 (sizeof(tmpBuf) / sizeof(wchar_t)) ) == TRUE ) {
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    Minimum Value:  %ls", tmpBuf );
+            }
+        }
+
+
+        /* ===== AccessibleTable ===== */
+
+        AccessibleTableInfo tableInfo;
+
+        if ( (info.accessibleInterfaces & cAccessibleTableInterface) ==
+             cAccessibleTableInterface ) {
+            if (getAccessibleTableInfo(vmID, ac, &tableInfo) != TRUE) {
+                appendToBuffer( buffer, bufsize,
+                                "\r\nERROR: getAccessibleTableInfo failed",
+                                bufsize );
+            } else {
+                appendToBuffer( buffer, bufsize,
+                                "\r\n\r\nAccessibleTable info:", bufsize );
+
+                int trow = getAccessibleTableRow( vmID,
+                                                  tableInfo.accessibleTable, 3 );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    getAccessibleTableRow:  %d", trow);
+
+                int tcol =
+                    getAccessibleTableColumn(vmID, tableInfo.accessibleTable, 2);
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    getAccessibleTableColumn:  %d", tcol );
+
+                int tindex = getAccessibleTableIndex( vmID,
+                                                      tableInfo.accessibleTable,
+                                                      2, 3 );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    getAccessibleTableIndex:  %d",
+                                tindex );
+
+                // Core info
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    table row count:  %d",
+                                tableInfo.rowCount );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n    table column count:  %d",
+                                tableInfo.columnCount );
+
+                AccessibleTableCellInfo tableCellInfo;
+                for (int i = 0; i < tableInfo.rowCount; i++) {
+                    for (int j = 0; j < tableInfo.columnCount; j++) {
+
+                        if ( !getAccessibleTableCellInfo( vmID,
+                                                         tableInfo.accessibleTable,
+                                                         i, j,
+                                                         &tableCellInfo ) ) {
+
+                            appendToBuffer(
+                                buffer, bufsize,
+                                "\r\nERROR: GetAccessibleTableCellInfo failed.",
+                                bufsize );
+                        } else {
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n\r\n    AccessibleTable cell[%d,%d] info:",
+                                i, j );
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n    Index: %ld", tableCellInfo.index );
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n    Row extent: %ld",
+                                tableCellInfo.rowExtent );
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n    Column extent: %ld",
+                                tableCellInfo.columnExtent );
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n    Is selected?: %ld",
+                                tableCellInfo.isSelected );
+
+                            AccessibleContextInfo cellACInfo;
+                            if ( !GetAccessibleContextInfo(
+                                    vmID,
+                                    tableCellInfo.accessibleContext,
+                                    &cellACInfo ) ) {
+                                appendToBuffer( buffer, bufsize,
+                                    "\r\nERROR: GetAccessibleContextInfo failed for table cell [%d,%d].",
+                                    i, j );
+                            } else {
+                                if ( !getVirtualAccessibleName( vmID,
+                                        tableCellInfo.accessibleContext, name,
+                                        (sizeof(name) / sizeof(wchar_t)) ) ) {
+                                    appendToBuffer( buffer, bufsize,
+                                        "\r\n\r\nERROR: getVirtualAccessibleName",
+                                        bufsize );
+                                } else {
+                                    appendToBuffer( buffer, bufsize,
+                                                    "\r\n    Name:  %ls", name );
+                                }
+                                appendToBuffer( buffer, bufsize,
+                                                "\r\n    Role:  %ls",
+                                                cellACInfo.role );
+                            }
+                            ReleaseJavaObject( vmID,
+                                               tableCellInfo.accessibleContext );
+                        }
+                    }
+                }
+
+                // Get the column headers
+                AccessibleTableInfo columnInfo;
+                if ( !getAccessibleTableColumnHeader(vmID, ac, &columnInfo)) {
+                    appendToBuffer( buffer, bufsize,
+                        "\r\nERROR: getAccessibleTableColumnHeader failed.",
+                        bufsize );
+                } else {
+                    appendToBuffer( buffer, bufsize,
+                        "\r\n\r\nAccessibleTable column header info:", bufsize );
+
+                    // Core info
+                    appendToBuffer( buffer, bufsize,
+                                    "\r\n    Column header row count:  %d",
+                                    columnInfo.rowCount );
+                    appendToBuffer( buffer, bufsize,
+                                    "\r\n    Column header column count:  %d",
+                                    columnInfo.columnCount );
+
+                }
+
+                // Get the selected rows
+                int numSelections =
+                    getAccessibleTableRowSelectionCount( vmID,
+                                                         tableInfo.accessibleTable );
+                appendToBuffer( buffer, bufsize,
+                                "\r\n\r\nRow selection count:  %d",
+                                numSelections );
+                jint *selections = new jint[numSelections];
+
+                if ( !getAccessibleTableRowSelections( vmID,
+                                                       tableInfo.accessibleTable,
+                                                       numSelections,
+                                                       selections ) ) {
+                    appendToBuffer( buffer, bufsize,
+                        "\r\nERROR: getAccessibleTableRowSelections failed.",
+                        bufsize );
+                } else {
+                    appendToBuffer(buffer, bufsize, "  \r\n  Row selections: ");
+                    for (int j = 0; j < numSelections; j++) {
+                        appendToBuffer(buffer, bufsize, " %d", selections[j]);
+                    }
+                }
+
+                // Get column header info
+                for (int i = 0; i < columnInfo.columnCount; i++) {
+                    if ( !getAccessibleTableCellInfo( vmID,
+                                                      columnInfo.accessibleTable,
+                                                      0, i, &tableCellInfo ) ) {
+
+                        appendToBuffer( buffer, bufsize,
+                            "\r\nERROR: GetAccessibleTableCellInfo failed.",
+                            bufsize );
+                    } else {
+                        appendToBuffer( buffer, bufsize,
+                            "\r\n\r\nColumn header [0,%d] cell info.", i );
+                        appendToBuffer( buffer, bufsize,
+                            "\r\n    Index: %ld", tableCellInfo.index );
+                        appendToBuffer( buffer, bufsize,
+                            "\r\n    Row extent: %ld",
+                            tableCellInfo.rowExtent );
+                        appendToBuffer( buffer, bufsize,
+                            "\r\n    Column extent: %ld",
+                            tableCellInfo.columnExtent );
+                        appendToBuffer( buffer, bufsize,
+                            "\r\n    Is selected: %ld",
+                            tableCellInfo.isSelected );
+
+                        AccessibleContextInfo cellACInfo;
+                        if ( !GetAccessibleContextInfo( vmID,
+                                tableCellInfo.accessibleContext, &cellACInfo ) ) {
+                            appendToBuffer( buffer, bufsize,
+                                "\r\nERROR: GetAccessibleContextInfo failed.",
+                                bufsize );
+                        } else {
+                            if ( !getVirtualAccessibleName( vmID,
+                                    tableCellInfo.accessibleContext, name,
+                                    (sizeof(name) / sizeof(wchar_t)) ) ) {
+                                appendToBuffer( buffer, bufsize,
+                                    "\r\n\r\nERROR: getVirtualAccessibleName",
+                                    bufsize );
+                            } else {
+                                appendToBuffer( buffer, bufsize,
+                                    "\r\n    Name:  %ls", name );
+                            }
+                            appendToBuffer( buffer, bufsize,
+                                "\r\n    Role:  %ls", cellACInfo.role );
+                        }
+                        ReleaseJavaObject(vmID, tableCellInfo.accessibleContext);
+                    }
+                }
+            }
+        }
+
+        /* ===== AccessibleText ===== */
+
+        if (info.accessibleText == TRUE) {
+            AccessibleTextInfo textInfo;
+            AccessibleTextItemsInfo textItems;
+            AccessibleTextSelectionInfo textSelection;
+            AccessibleTextRectInfo rectInfo;
+            AccessibleTextAttributesInfo attributeInfo;
+
+            appendToBuffer( buffer, bufsize,
+                            "\r\n\r\nAccessible Text information:", bufsize);
+
+            if (GetAccessibleTextInfo(vmID, ac, &textInfo, x, y) == TRUE) {
+                appendToBuffer( buffer, bufsize,
+                    "\r\n    Mouse point at text index:  %d",
+                    textInfo.indexAtPoint );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n    Caret at text index:  %d",
+                    textInfo.caretIndex );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n    Char count:  %d",
+                    textInfo.charCount );
+            }
+            if ( GetAccessibleTextSelectionInfo(vmID, ac, &textSelection) ) {
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n    Selection start index:  %d",
+                    textSelection.selectionStartIndex );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n    Selection end index:  %d",
+                    textSelection.selectionEndIndex );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n    Selected text:  %ls",
+                    textSelection.selectedText );
+            }
+
+            /* ===== AccessibleText information at the mouse point ===== */
+
+            appendToBuffer( buffer, bufsize,
+                "\r\n\r\n    At mouse point index: %d", textInfo.indexAtPoint);
+
+            if (GetAccessibleTextRect(vmID, ac, &rectInfo, textInfo.indexAtPoint)) {
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Character bounding rectangle: [%d, %d, %d, %d]",
+                    rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height );
+            }
+
+            if ( GetAccessibleTextLineBounds( vmID, ac, textInfo.indexAtPoint,
+                                              &start, &end ) ) {
+                if ( GetAccessibleTextRange( vmID, ac, start, end, tmpBuf,
+                        (sizeof(tmpBuf) / sizeof(wchar_t)) ) ) {
+                    appendToBuffer( buffer, bufsize,
+                        "\r\n        Line bounds: [%d, %d]", start, end);
+                }
+            }
+            if ( GetAccessibleTextItems( vmID, ac, &textItems,
+                                         textInfo.indexAtPoint ) ) {
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Character:  %lc", textItems.letter );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Word:  %ls", textItems.word );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Sentence:  %ls", textItems.sentence );
+            }
+
+            /* ===== AccessibleText attributes ===== */
+
+            if (GetAccessibleTextAttributes(vmID, ac,
+                                            textInfo.indexAtPoint,
+                                            &attributeInfo)) {
+
+                appendToBuffer( buffer, bufsize, "\r\n        Core attributes: %s",
+                        attributeInfo.bold ? "bold" : "not bold" );
+                appendToBuffer( buffer, bufsize, ", %s",
+                        attributeInfo.italic ? "italic" : "not italic" );
+                appendToBuffer( buffer, bufsize, ", %s",
+                        attributeInfo.underline ? "underline" : "not underline" );
+                appendToBuffer( buffer, bufsize, ", %s",
+                        attributeInfo.strikethrough ? "strikethrough" :
+                                                      "not strikethrough" );
+                appendToBuffer( buffer, bufsize, ",  %s",
+                        attributeInfo.superscript ? "superscript" :
+                                                    "not superscript" );
+                appendToBuffer( buffer, bufsize, ", %s",
+                        attributeInfo.subscript ? "subscript" : "not subscript" );
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Background color:  %ls",
+                    attributeInfo.backgroundColor );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Foreground color:  %ls",
+                    attributeInfo.foregroundColor );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Font family:  %ls",
+                    attributeInfo.fontFamily );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Font size:  %d",
+                    attributeInfo.fontSize );
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        First line indent:  %f",
+                    attributeInfo.firstLineIndent );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Left indent:  %f",
+                    attributeInfo.leftIndent );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Right indent:  %f",
+                    attributeInfo.rightIndent );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Line spacing:  %f",
+                    attributeInfo.lineSpacing );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Space above:  %f",
+                    attributeInfo.spaceAbove );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Space below:  %f",
+                    attributeInfo.spaceBelow );
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Full attribute string:  %ls",
+                    attributeInfo.fullAttributesString );
+
+                // get the attribute run length
+                short runLength = -1;
+                if ( getTextAttributesInRange( vmID, ac, textInfo.indexAtPoint,
+                                               textInfo.indexAtPoint + 100,
+                                               &attributeInfo, &runLength ) ) {
+                    appendToBuffer( buffer, bufsize,
+                        "\r\n        Attribute run:  %d", runLength );
+                } else {
+                    appendToBuffer( buffer, bufsize,
+                        "\r\n        getTextAttributesInRangeFailed" );
+                }
+            }
+
+            /* ===== AccessibleText information at the caret index ===== */
+
+            appendToBuffer( buffer, bufsize,
+                "\r\n\r\n    At caret index: %d", textInfo.caretIndex);
+
+            if (getCaretLocation(vmID, ac, &rectInfo, textInfo.caretIndex)) {
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Caret bounding rectangle: [%d, %d, %d, %d]",
+                    rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height );
+            }
+
+            if (GetAccessibleTextRect(vmID, ac, &rectInfo, textInfo.caretIndex)) {
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Character bounding rectangle: [%d, %d, %d, %d]",
+                    rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height );
+            }
+
+            if ( GetAccessibleTextLineBounds( vmID, ac, textInfo.caretIndex,
+                                              &start, &end ) ) {
+                if ( GetAccessibleTextRange( vmID, ac, start, end, tmpBuf,
+                                             (sizeof(tmpBuf) / sizeof(wchar_t)) ) ) {
+
+                    appendToBuffer( buffer, bufsize,
+                        "\r\n        Line bounds: [%d, %d]", start, end);
+                }
+            }
+            if (GetAccessibleTextItems(vmID, ac, &textItems, textInfo.caretIndex)) {
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Character:  %lc", textItems.letter );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Word:  %ls", textItems.word );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Sentence:  %ls", textItems.sentence );
+            }
+
+            /* ===== AccessibleText attributes ===== */
+
+            if (GetAccessibleTextAttributes(vmID, ac, textInfo.caretIndex, &attributeInfo)) {
+
+                appendToBuffer( buffer, bufsize, "\r\n        Core attributes: %s",
+                    attributeInfo.bold ? "bold" : "not bold" );
+                appendToBuffer( buffer, bufsize, ", %s",
+                    attributeInfo.italic ? "italic" : "not italic" );
+                appendToBuffer( buffer, bufsize, ", %s",
+                    attributeInfo.underline ? "underline" : "not underline" );
+                appendToBuffer( buffer, bufsize, ", %s",
+                    attributeInfo.strikethrough ? "strikethrough" :
+                                                  "not strikethrough" );
+                appendToBuffer( buffer, bufsize, ",  %s",
+                    attributeInfo.superscript ? "superscript" :
+                                                "not superscript" );
+                appendToBuffer( buffer, bufsize, ", %s",
+                    attributeInfo.subscript ? "subscript" : "not subscript");
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Background color:  %ls",
+                    attributeInfo.backgroundColor );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Foreground color:  %ls",
+                    attributeInfo.foregroundColor );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Font family:  %ls", attributeInfo.fontFamily );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Font size:  %d", attributeInfo.fontSize);
+
+
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        First line indent:  %f",
+                    attributeInfo.firstLineIndent );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Left indent:  %f", attributeInfo.leftIndent );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Right indent:  %f", attributeInfo.rightIndent );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Line spacing:  %f", attributeInfo.lineSpacing );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Space above:  %f", attributeInfo.spaceAbove );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Space below:  %f", attributeInfo.spaceBelow );
+                appendToBuffer( buffer, bufsize,
+                    "\r\n        Full attribute string:  %ls",
+                    attributeInfo.fullAttributesString );
+                // get the attribute run length
+                short runLength = -1;
+                if ( getTextAttributesInRange( vmID, ac, textInfo.caretIndex,
+                                               textInfo.caretIndex + 100,
+                                               &attributeInfo, &runLength ) ) {
+                    appendToBuffer( buffer, bufsize,
+                        "\r\n        Attribute run:  %d", runLength);
+                } else {
+                    appendToBuffer( buffer, bufsize,
+                        "\r\n        getTextAttributesInRangeFailed" );
+                }
+            }
+        }
+    }
+    return buffer;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/native/toolscommon/AccessInfo.h	Fri Nov 20 17:54:58 2015 -0600
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+typedef void (WINAPI * LogStringCallbackFP) (const char * lpString);
+extern LogStringCallbackFP g_LogStringCallback;
+
+#define LINE_BUFSIZE 1024
+#define LARGE_BUFSIZE 5120
+#define HUGE_BUFSIZE 20480
+
+/*
+ * returns formatted date and time
+ */
+char *getTimeAndDate();
+
+/*
+ * displays a message in a dialog and writes the message to a logfile
+ */
+void displayAndLog(HWND hDlg, int nIDDlgItem, FILE *logfile, char *msg, ...);
+
+/*
+ * writes a text string to a logfile
+ */
+void logString(FILE *logfile, char *msg, ...);
+
+/**
+ * returns accessibility information for an AccessibleContext
+ */
+char *getAccessibleInfo(long vmID, AccessibleContext ac, char *buffer, int bufsize);
+
+/**
+ * returns accessibility information at the specified coordinates in an AccessibleContext
+ */
+char *getAccessibleInfo(long vmID, AccessibleContext ac, int x, int y, char *buffer, int bufsize);