Index: main/trunk/gli/src/org/greenstone/gatherer/Gatherer.java
===================================================================
--- main/trunk/gli/src/org/greenstone/gatherer/Gatherer.java	(revision 31717)
+++ main/trunk/gli/src/org/greenstone/gatherer/Gatherer.java	(revision 31718)
@@ -1456,5 +1456,5 @@
 	static private class ExternalApplication
 	extends Thread {
-		private Process process = null;
+		private SafeProcess process = null;
 		/** The initial command string given to this sub-process. */
 		private String command = null;
@@ -1515,14 +1515,11 @@
 					}
 					DebugStream.println("Running " + whole_command.toString());
-					Runtime rt = Runtime.getRuntime();
-					process = rt.exec(commands);
-					process.waitFor();
+					process = new SafeProcess(commands);
 				}
 				else {
 					DebugStream.println("Running " + command);
-					Runtime rt = Runtime.getRuntime();
-					process = rt.exec(command);
-					process.waitFor();
-				}
+					process = new SafeProcess(command);
+				}
+				process.runProcess();
 			}
 			catch (Exception exception) {
@@ -1548,5 +1545,6 @@
 		public void stopExternalApplication() {
 			if(process != null) {
-				process.destroy();
+			    SafeProcess.log("*** stopExternalApplication called.");
+			    process.cancelRunningProcess();
 			}
 		}
@@ -1555,5 +1553,5 @@
 	static private class BrowserApplication
 	extends Thread {
-		private Process process = null;
+		private SafeProcess process = null;
 		/** The initial command string given to this sub-process. */
 		private String command = null;
@@ -1595,11 +1593,12 @@
 					printArray(new_commands);
 
-					Runtime rt = Runtime.getRuntime();
-					process = rt.exec(new_commands);
-					int exitCode = process.waitFor();
+					process = new SafeProcess(new_commands);
+					int exitCode = process.runProcess();
 					if (exitCode != 0) { // if Netscape or mozilla was not open
 						DebugStream.println("couldn't do remote, trying original command");
 						printArray(commands);
-						process = rt.exec(commands); // try the original command
+						process = null;
+						process = new SafeProcess(commands); // try the original command
+						process.runProcess();
 					}
 				} else {
@@ -1611,7 +1610,6 @@
 					}
 					DebugStream.println("Running " + whole_command.toString());
-					Runtime rt = Runtime.getRuntime();
-					process = rt.exec(commands);
-					process.waitFor();
+					process = new SafeProcess(commands);
+					process.runProcess();
 				}
 			}
@@ -1635,5 +1633,6 @@
 		public void stopBrowserApplication() {
 			if(process != null) {
-				process.destroy();
+			    SafeProcess.log("*** stopBrowserApplication called.");
+			    process.cancelRunningProcess();
 			}
 		}
Index: main/trunk/gli/src/org/greenstone/gatherer/util/Readme_Using_SafeProcess.txt
===================================================================
--- main/trunk/gli/src/org/greenstone/gatherer/util/Readme_Using_SafeProcess.txt	(revision 31717)
+++ main/trunk/gli/src/org/greenstone/gatherer/util/Readme_Using_SafeProcess.txt	(revision 31718)
@@ -163,4 +163,5 @@
 
 
+All the runProcess() variants do a Process.waitFor(). This means all runProcess() variants block the primary thread, which is the thread in which they're executing, until the internal Process has completed.
 
 If you want to completely override the default behaviour of any of SafeProcess' iostream related worker threads (such as if you want to read a char at a time from the stderr stream and do something, instead of the default behaviour of reading a line at a time from it), then call this method.
@@ -756,5 +757,5 @@
 	+ src/org/greenstone/gatherer/gui/DownloadPane.java
 	+ src/org/greenstone/gatherer/util/GS3ServerThread.java
-	+ 2 src/org/greenstone/gatherer/Gatherer.java [2 MORE but don't want to mess with those]
+	+ 4 src/org/greenstone/gatherer/Gatherer.java [All 4 instances that used Process now go through SafeProcess instead]
 	+ 1 src/org/greenstone/gatherer/download/ServerInfoDialog.java
 	+ 2 src/org/greenstone/gatherer/greenstone/Classifiers.java
Index: main/trunk/gli/src/org/greenstone/gatherer/util/SafeProcess.java
===================================================================
--- main/trunk/gli/src/org/greenstone/gatherer/util/SafeProcess.java	(revision 31717)
+++ main/trunk/gli/src/org/greenstone/gatherer/util/SafeProcess.java	(revision 31718)
@@ -162,5 +162,5 @@
      * This method returns a boolean that you can call sentInterrupt.  
      */
-    public boolean cancelRunningProcess() {	
+    public boolean cancelRunningProcess() {
 
 	boolean forceWaitUntilInterruptible = true;
@@ -921,5 +921,5 @@
 	*/
 	
-	if(pid == -1) {
+	if(pid == -1) { // if the process has already terminated, or we can't get the pid for any reason:
 	    p.destroy(); // at minimum. Will have no effect if the process had already terminated 
 	} else {
@@ -929,5 +929,7 @@
 	    if(!killUnixProcessWithID(pid, !forceKill, killEntireProcessTree)) { // send sig TERM (kill -15 or kill -TERM)
 		killUnixProcessWithID(pid, forceKill, killEntireProcessTree); // send sig KILL (kill -9 or kill -KILL)
-	    }	    
+	    }
+	    // if both kill commands failed for whatever reason, can still at least end the top level process:
+	    p.destroy(); // no effect if the process has already terminated.
 	}
 	
