https://bugs.eclipse.org/bugs/show_bug.cgi?id=226428
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/.cvsignore b/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/.cvsignore
index 4c23740..a80d792 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/.cvsignore
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/.cvsignore
@@ -1,2 +1,3 @@
 *.pdb
 org_eclipse_actf_ai_screenreader_jaws_JawsAPI.h
+org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil.h
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/IEWindow.cpp b/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/IEWindow.cpp
index 30d31b5..227a923 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/IEWindow.cpp
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/IEWindow.cpp
@@ -13,7 +13,7 @@
 #include <shlguid.h>
 #include <tchar.h>
 #include <windows.h>
-#include "org_eclipse_actf_ai_screenreader_jaws_JawsAPI.h"
+#include "org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil.h"
 
 WNDPROC original_winproc;
 
@@ -115,7 +115,7 @@
  * Signature: (J)Z
  */
 jboolean JNICALL
-Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1TakeBackControl
+Java_org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil__1TakeBackControl
 (JNIEnv *env, jclass clazz, jlong browser)
 {
     wm_html_getobject_msgid = RegisterWindowMessage(_T("WM_HTML_GETOBJECT"));
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/Makefile b/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/Makefile
index acf49df..0c01b9c 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/Makefile
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/Makefile
@@ -10,9 +10,9 @@
 ###############################################################################
 
 BASEPKG = org.eclipse.actf.ai.screenreader.jaws
-JAVAH = $(JAVA_HOME:/=\)\bin\javah
+JAVAH = "$(JAVA_HOME:/=\)\bin\javah"
 JAVAH_FLAGS = -classpath ../bin
-JAVA_INC = $(JAVA_HOME)/include
+JAVA_INC = "$(JAVA_HOME)/include"
 BLD = ..\build
 CC = cl.exe
 CFLAGS = -c -Zi -Od -I $(JAVA_INC)
@@ -32,7 +32,7 @@
 	-rd /S/Q $(BLD)
 
 headers: 
-	$(JAVAH) $(JAVAH_FLAGS) $(BASEPKG).JawsAPI
+	$(JAVAH) $(JAVAH_FLAGS) $(BASEPKG).JawsAPI $(BASEPKG).JawsWindowUtil
 
 $(DLL): $(OBJS)
 	$(LINK) $(LDFLAGS) $(OBJS) -out:$(DLL) $(LIBS)
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/jawsapi-bridge.cpp b/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/jawsapi-bridge.cpp
index a51141e..dba4e88 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/jawsapi-bridge.cpp
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/cpp/jawsapi-bridge.cpp
@@ -16,11 +16,14 @@
 //#include "stdafx.h"
 #include "common.h"
 #include "org_eclipse_actf_ai_screenreader_jaws_JawsAPI.h"
+#include "org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil.h"
 
-typedef BOOL (WINAPI *JFWSayStringType)(LPCTSTR lpszStrinToSpeak,BOOL bInterrupt);
+typedef BOOL (WINAPI *JFWRunFunctionType)(LPCTSTR lpszFuncName);
+typedef BOOL (WINAPI *JFWSayStringType)(LPCTSTR lpszStringToSpeak,BOOL bInterrupt);
 typedef BOOL (WINAPI *JFWStopSpeechType)(void);
 typedef BOOL (WINAPI *JFWRunScriptType)(LPCTSTR lpszScriptName);
 
+static JFWRunFunctionType JFWRunFunctionProc;
 static JFWSayStringType JFWSayStringProc;
 static JFWStopSpeechType JFWStopSpeechProc;
 static JFWRunScriptType JFWRunScriptProc;
@@ -29,7 +32,7 @@
 static const TCHAR jaws_api_dllname[] = "jfwapi.dll";
 
 static JavaVM *jvm;
-static jclass class_JawsAPI;
+static jclass class_JawsWindowUtil;
 static jmethodID callBackMethodID;
 
 static LPTSTR
@@ -116,13 +119,14 @@
     return tstr;
 }
 
+
 /*
- * Class:     org_eclipse_actf_ai_screenreader_jaws_JawsAPI
- * Method:    _initialize
+ * Class:     org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil
+ * Method:    _initializeWindow
  * Signature: ()Z
  */
 jboolean JNICALL
-Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1initialize
+Java_org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil__1initializeWindow
 (JNIEnv* env, jclass jcls, jint topwnd)
 {
     LPTSTR jfwapidllpath = findJFWAPIDLL();
@@ -130,36 +134,63 @@
 	fprintf(stderr, "Could not find out jfwapi.dll\n");
 	return JNI_FALSE;
     }
-    HMODULE h = LoadLibrary(jfwapidllpath);
-    free(jfwapidllpath);
+    
+    env->GetJavaVM(&jvm);
+    class_JawsWindowUtil = (jclass) env->NewGlobalRef(jcls);
+    callBackMethodID = env->GetStaticMethodID(class_JawsWindowUtil, "callBack", "(I)Z");
 
+    init_jaws_window((HWND) topwnd);
+    
+    return JNI_TRUE;
+}
+
+
+/*
+ * Class:     org_eclipse_actf_ai_screenreader_jaws_JawsAPI
+ * Method:    _initialize
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1initialize
+(JNIEnv* env, jclass jcls)
+{
+    HMODULE h;
+    LPTSTR jfwapidllpath = findJFWAPIDLL();
+    if (!jfwapidllpath) {
+	fprintf(stderr, "Could not find out jfwapi.dll\n");
+	return JNI_FALSE;
+	
+    }
+    h = LoadLibrary(jfwapidllpath);
+    free(jfwapidllpath);
+	
     if (!h) {
-	fprintf(stderr, "Can't load the \"jfwapi.dll\"\n");
+        fprintf(stderr, "Can't load the \"jfwapi.dll\"\n");
 	return JNI_FALSE;
     }
+    
 
+
+    JFWRunFunctionProc = (JFWRunFunctionType) GetProcAddress(h, "JFWRunFunction");
+    if (!JFWRunFunctionProc) {
+	fprintf(stderr, "Could not obtain JFWRunFunction entry pointer.\n");
+	//return JNI_FALSE;
+    }
     JFWSayStringProc = (JFWSayStringType) GetProcAddress(h, "JFWSayString");
     if (!JFWSayStringProc) {
 	fprintf(stderr, "Could not obtain JFWSayString entry pointer.\n");
-	return JNI_FALSE;
+	//return JNI_FALSE;
     }
     JFWStopSpeechProc = (JFWStopSpeechType) GetProcAddress(h, "JFWStopSpeech");
     if (!JFWStopSpeechProc) {
 	fprintf(stderr, "Could not obtain JFWStopSpeech entry pointer.\n");
-	return JNI_FALSE;
+	//return JNI_FALSE;
     }
     JFWRunScriptProc = (JFWRunScriptType)  GetProcAddress(h, "JFWRunScript");
     if (!JFWRunScriptProc) {
 	fprintf(stderr, "Could not obtain JFWRunScript entry pointer.\n");
-	return JNI_FALSE;
+	//return JNI_FALSE;
     }
 
-    env->GetJavaVM(&jvm);
-    class_JawsAPI = (jclass) env->NewGlobalRef(jcls);
-    callBackMethodID = env->GetStaticMethodID(class_JawsAPI, "callBack", "(I)Z");
-
-    init_jaws_window((HWND) topwnd);
-
     return JNI_TRUE;
 }
 
@@ -179,6 +210,22 @@
 }
 
 /*
+ * Class:     org_eclipse_actf_ai_screenreader_jaws_JawsAPI
+ * Method:    _JawsRunFunction
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1JawsRunFunction
+  (JNIEnv *env, jclass jcls, jstring jstringFuncName)
+{
+  if (!JFWRunFunctionProc) 
+    return JNI_FALSE;
+  LPTSTR str = convertJavaString(env, jstringFuncName);
+  jboolean b = (JFWRunFunctionProc)(str);
+  free(str);
+  return b;
+}
+
+/*
  * Class:     Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI_JawsRunFunction
  * Method:    JawsSayString
  * Signature: (Ljava/lang/String;Z)Z
@@ -187,10 +234,12 @@
 Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1JawsSayString
 (JNIEnv *env, jclass jcls, jstring jstringToSpeak, jboolean bInterrupt)
 {
+    if (!JFWSayStringProc)
+      return JNI_FALSE;
     LPTSTR str = convertJavaString(env, jstringToSpeak);
     jboolean b = (JFWSayStringProc)(str, bInterrupt);
     free(str);
-    return JNI_TRUE;
+    return b;
 }
 
 
@@ -203,6 +252,8 @@
 Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1JawsStopSpeech
 (JNIEnv *env, jclass jcls)
 {
+    if (!JFWStopSpeechProc)
+      return JNI_FALSE;
     return (JFWStopSpeechProc)();
 }
 
@@ -215,6 +266,8 @@
 Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1JawsRunScript
 (JNIEnv *env, jclass jcls, jstring jscriptName)
 {
+    if (!JFWRunScriptProc)
+      return JNI_FALSE;
     LPTSTR str = convertJavaString(env, jscriptName);
     jboolean b = (JFWRunScriptProc)(str);
     free(str);
@@ -223,12 +276,12 @@
 }
 
 /*
- * Class:     org_eclipse_actf_ai_screenreader_jaws_JawsAPI
+ * Class:     org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil
  * Method:    _setJawsWindowText
  * Signature: (Ljava/lang/String;)Z
  */
 jboolean JNICALL
-Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1setJawsWindowText
+Java_org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil__1setJawsWindowText
 (JNIEnv *env, jclass jcls, jstring text)
 {
     LPTSTR str = convertJavaString(env, text);
@@ -238,12 +291,12 @@
 }
 
 /*
- * Class:     org_eclipse_actf_ai_screenreader_jaws_JawsAPI
+ * Class:     org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil
  * Method:    _resetJawsWindowText
  * Signature: ()Z
  */
 jboolean JNICALL
-Java_org_eclipse_actf_ai_screenreader_jaws_JawsAPI__1resetJawsWindowText
+Java_org_eclipse_actf_ai_screenreader_jaws_JawsWindowUtil__1resetJawsWindowText
 (JNIEnv *env, jclass jcls)
 {
     reset_jaws_window();
@@ -260,7 +313,7 @@
 {
     JNIEnv *env;
     if (jvm->GetEnv((void**) &env, JNI_VERSION_1_2) != JNI_OK) return 0;
-    return env->CallStaticBooleanMethod(class_JawsAPI,
+    return env->CallStaticBooleanMethod(class_JawsWindowUtil,
 					callBackMethodID,
 					(jint) param);
 }
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/jawsapi-bridge.dll b/plugins/org.eclipse.actf.ai.screenreader.jaws/jawsapi-bridge.dll
index a2fbc8a..70a1515 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.jaws/jawsapi-bridge.dll
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/jawsapi-bridge.dll
Binary files differ
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/Jaws.java b/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/Jaws.java
index 0f36b43..887d846 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/Jaws.java
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/Jaws.java
@@ -26,7 +26,10 @@
 
     public static final String JAWS_OBSERVE_SPEECH = "ObserveSpeech";
 
+    public static final String SAYALLOFF = "AiBrowserSayAllOff";
+
     JawsAPI jaws = JawsAPI.getInstance();
+    JawsWindowUtil util = JawsWindowUtil.getInstance();
 
     public void dispose() {
         // not supported
@@ -38,7 +41,8 @@
     }
 
     public void setEventListener(IVoiceEventListener eventListener) {
-        jaws.setEventListener(eventListener);
+    	if (util != null)
+    		util.setEventListener(eventListener);
     }
 
     public void setLanguage(String language) {
@@ -50,19 +54,21 @@
     }
 
     public void speak(String text, int flags, int index) {
-        if (jaws == null) return;
+        if (jaws == null || util == null) return;
         if (index < 0) {
             jaws.JawsSayString(text, flags == TTSFLAG_FLUSH);
         }  else {
-            jaws.JawsShowTextToWindow(text, flags == TTSFLAG_FLUSH, index);
+            util.JawsShowTextToWindow(text, flags == TTSFLAG_FLUSH, index);
             // Yield.forWhile(10);
             jaws.JawsRunScript(JAWS_OBSERVE_SPEECH);
         }
     }
 
     public void stop() {
-        if (jaws != null) {
+        if (jaws != null && util != null) {
             jaws.JawsStopSpeech();
+            util.resetJawsWindowText();
+            jaws.JawsRunScript(SAYALLOFF);
         }
     }
 
@@ -79,8 +85,8 @@
     }
     
     public void takeBackControl(IWebBrowserACTF browser){
-        if(jaws != null){
-            jaws.TakeBackControl(browser);
+        if(util != null){
+            util.TakeBackControl(browser);
         }
     }
 
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/JawsAPI.java b/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/JawsAPI.java
index 31af6cd..537c672 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/JawsAPI.java
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/JawsAPI.java
@@ -13,12 +13,8 @@
 import org.eclipse.actf.ai.voice.IVoiceEventListener;
 import org.eclipse.actf.model.IWebBrowserACTF;
 
-
-
 public class JawsAPI {
     private static JawsAPI instance;
-    private static final String SAYALLOFF = "AiBrowserSayAllOff";
-    
     static{
         try{
             System.loadLibrary("jawsapi-bridge");
@@ -32,15 +28,14 @@
 
     public static JawsAPI getInstance(){
         if (instance == null) {
-            int handle = JawsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell().handle;
-            if (!_initialize(handle)) return null;
+        	if (!_initialize()) return null;
             instance = new JawsAPI();
         }
         return instance;
     }
-
-    public boolean isAvailable() {
-        return _isAvailable();
+    
+    public boolean JawsRunFunction(String funcName) {
+    	return _JawsRunFunction(funcName);
     }
 
     public boolean JawsSayString(String stringToSpeak, boolean bInterrupt) {
@@ -48,56 +43,25 @@
         return _JawsSayString(stringToSpeak, bInterrupt);
     }
 
-    public boolean JawsShowTextToWindow(String stringToSpeak, boolean bInterrupt, int index) {
-        // if (bInterrupt) JawsStopSpeech();
-        boolean ret = _setJawsWindowText(stringToSpeak);
-        if (listener != null) {
-            listener.indexReceived(index);
-        }
-        return ret;
-    }
-
     public boolean JawsStopSpeech() {
-        _resetJawsWindowText();
-        JawsRunScript(SAYALLOFF);
-        return _JawsStopSpeech();
+    	// JawsStopSpeech does not work well, so null string will be spoken.
+        // return _JawsStopSpeech();
+    	
+    	return _JawsSayString("", true);
     }
 
     public boolean JawsRunScript(String scriptName) {
         return _JawsRunScript(scriptName);
     }
     
-    public boolean TakeBackControl(IWebBrowserACTF browser){
-        //return _TakeBackControl(browser.getIWebBrowser2());
-        
-        int handle = JawsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell().handle;
-        return _TakeBackControl(handle);
-    }
+	public boolean isAvailable() {
+	    return _isAvailable();
+	}
 
-    private static IVoiceEventListener listener;
-
-    public void setEventListener(IVoiceEventListener eventListener) {
-        listener = eventListener;
-    }
-
-    public static boolean callBack(int param) {
-        System.err.println("Callbacked!!!" + param);
-        if (listener == null) return true;
-        if (param == 0) {
-            listener.indexReceived(-1);
-        } else if (param == 1) {
-            getInstance().JawsStopSpeech();
-            listener.indexReceived(-2);
-        }
-        return true;
-    }
-
-    private static native boolean _initialize(int handle);
-    private static native boolean _isAvailable();
+	private static native boolean _initialize();
+	private static native boolean _isAvailable();
+	private static native boolean _JawsRunFunction(String funcName);
     private static native boolean _JawsSayString(String stringToSpeak, boolean bInterrupt);
     private static native boolean _JawsStopSpeech();
     private static native boolean _JawsRunScript(String scriptName);
-    private static native boolean _TakeBackControl(long browser);
-    private static native boolean _setJawsWindowText(String text);
-    private static native boolean _resetJawsWindowText();
 }
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/JawsWindowUtil.java b/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/JawsWindowUtil.java
new file mode 100644
index 0000000..657b493
--- /dev/null
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/JawsWindowUtil.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and Others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daisuke SATO - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.ai.screenreader.jaws;
+
+import org.eclipse.actf.ai.voice.IVoiceEventListener;
+import org.eclipse.actf.model.IWebBrowserACTF;
+
+public class JawsWindowUtil {
+	
+	private static JawsAPI jaws = JawsAPI.getInstance();
+
+	private static IVoiceEventListener listener;
+	
+	private static JawsWindowUtil instance;
+
+	public static JawsWindowUtil getInstance() {
+		if (instance == null) {
+            int handle = JawsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell().handle;
+            if (!_initializeWindow(handle)) return null;
+            instance = new JawsWindowUtil();
+		}
+		return instance;
+	}
+	
+	private JawsWindowUtil() {
+		
+	}
+
+	public void setEventListener(IVoiceEventListener eventListener) {
+	    listener = eventListener;
+	}
+
+	public boolean JawsShowTextToWindow(String stringToSpeak, boolean bInterrupt, int index) {
+	    // if (bInterrupt) JawsStopSpeech();
+	    boolean ret = _setJawsWindowText(stringToSpeak);
+	    if (listener != null) {
+	        listener.indexReceived(index);
+	    }
+	    return ret;
+	}
+
+	public boolean TakeBackControl(IWebBrowserACTF browser){
+	    //return _TakeBackControl(browser.getIWebBrowser2());
+	    
+	    int handle = JawsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell().handle;
+	    return _TakeBackControl(handle);
+	}
+
+	public static boolean callBack(int param) {
+	    System.err.println("Callbacked!!!" + param);
+	    if (listener == null) return true;
+	    if (param == 0) {
+	        listener.indexReceived(-1);
+	    } else if (param == 1) {
+	        jaws.JawsStopSpeech();
+	        resetJawsWindowText();
+            jaws.JawsRunScript(Jaws.SAYALLOFF);
+	        listener.indexReceived(-2);
+	    }
+	    return true;
+	}
+
+	public static void resetJawsWindowText() {
+        _resetJawsWindowText();
+	}
+	
+
+	private static native boolean _TakeBackControl(long browser);
+	private static native boolean _setJawsWindowText(String text);
+	private static native boolean _resetJawsWindowText();
+	private static native boolean _initializeWindow(int handle);
+}