Index: main/trunk/gli/src/org/greenstone/gatherer/Gatherer.java
===================================================================
--- main/trunk/gli/src/org/greenstone/gatherer/Gatherer.java	(revision 31666)
+++ main/trunk/gli/src/org/greenstone/gatherer/Gatherer.java	(revision 31670)
@@ -1676,5 +1676,4 @@
 			    }
 			    DebugStream.println("***** Running ImageMagickTest command: " + cmd_str);
-			    System.err.println("***** Running ImageMagickTest command: " + cmd_str);
 			   
 			    SafeProcess image_magick_process = new SafeProcess(command_parts);
@@ -1684,5 +1683,4 @@
 			    String output = image_magick_process.getStdOutput().toLowerCase();
 			    if (output.indexOf("version") != -1 || output.indexOf("imagemagick") != -1) {
-				System.err.println("*** ImageMagickTest output: " + output);
 				found = true;
 			    } // else found var remains false	
Index: main/trunk/gli/src/org/greenstone/gatherer/shell/GShell.java
===================================================================
--- main/trunk/gli/src/org/greenstone/gatherer/shell/GShell.java	(revision 31666)
+++ main/trunk/gli/src/org/greenstone/gatherer/shell/GShell.java	(revision 31670)
@@ -41,4 +41,5 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.regex.*;
 import javax.swing.*;
@@ -68,6 +69,9 @@
     private boolean cancel = false;
     private BufferedOutputStream buffered_output_stream = null;
-    /** The list of listeners associated with this class. */
-    private EventListenerList listeners = null;
+    /** The list of listeners associated with this class. 
+     * Make it a CopyOnWriteArrayList to make it threadsafe at a cost of decreased efficiency. 
+     * see http://stackoverflow.com/questions/8259479/should-i-synchronize-listener-notifications-or-not
+     */
+    private final CopyOnWriteArrayList<GShellListener> listeners;
     /** The current status of this shell process. */
     private int status = -1;
@@ -85,6 +89,6 @@
     private String commandOutput = null;
 
-    /** The process safely run in this GShell. Make sure to set to null when done with. */
-    SafeProcess prcs = null;
+    /** The process safely run in this GShell Thread. Make sure to set to prcs to null when done with. */
+    private SafeProcess prcs = null;
 
     /** Elements in process type enumeration. */
@@ -136,6 +140,6 @@
 	// Lower this jobs priority
 	this.setPriority(Thread.MIN_PRIORITY);
-	listeners = new EventListenerList();
-	listeners.add(GShellListener.class, caller);
+	listeners = new CopyOnWriteArrayList<GShellListener>();
+	listeners.add(caller);
     }
     /** This method adds another shell listener to this process.
@@ -143,5 +147,5 @@
      */
     public void addGShellListener(GShellListener listener) {
-	listeners.add(GShellListener.class, listener);
+	listeners.add(listener);
     }
     /** This method removes a certain shell listener from this process.
@@ -149,5 +153,5 @@
      */
     /* private void removeGShellListener(GShellListener listener) {
-       listeners.remove(GShellListener.class, listener);
+       listeners.remove(listener);
        } */
 
@@ -549,11 +553,8 @@
 	    // If the event hasn't been vetoed, pass it on to other listeners
 	    if(!current_event.isVetoed()) {
-		Object[] concerned = listeners.getListenerList();
-		for(int i = 0; i < concerned.length ; i++) {
-		    if(concerned[i] == GShellListener.class) {
-			((GShellListener)concerned[i+1]).message(current_event);
-		    }
-		}
-		concerned = null;
+		// See http://stackoverflow.com/questions/8259479/should-i-synchronize-listener-notifications-or-not
+		for (GShellListener l: this.listeners) {
+		    l.message(current_event);
+		}
 	    }
 	}
@@ -585,9 +586,6 @@
 	// Fire an event
 	GShellEvent event = new GShellEvent(this, 0, type, "", status);
-	Object[] concerned = listeners.getListenerList();
-	for(int i = 0; i < concerned.length ; i++) {
-	    if(concerned[i] == GShellListener.class) {
-		((GShellListener)concerned[i+1]).processBegun(event);
-	    }
+	for (GShellListener l: this.listeners) {
+	    l.processBegun(event);
 	}
     }
@@ -607,11 +605,7 @@
 	if(status == CANCELLED && Configuration.getMode() <= Configuration.LIBRARIAN_MODE) {
 	    GShellEvent current_event = new GShellEvent(this, 0, type, Dictionary.get("GShell.Build.BuildCancelled"), status);
-	    Object[] concerned = listeners.getListenerList();
-	    for(int i = 0; i < concerned.length ; i++) {
-		if(concerned[i] == GShellListener.class) {
-		    ((GShellListener)concerned[i+1]).message(current_event);
-		}
-	    }
-	    concerned = null;
+	    for (GShellListener l: this.listeners) {
+		l.message(current_event);
+	    }
 	}
 	
@@ -623,9 +617,6 @@
 	// And firing off an event
 	GShellEvent event = new GShellEvent(this, 0, type, msg, status);
-	Object[] concerned = listeners.getListenerList();
-	for(int i = 0; i < concerned.length ; i++) {
-	    if(concerned[i] == GShellListener.class) {
-		((GShellListener)concerned[i+1]).processComplete(event);
-	    }
+	for (GShellListener l: this.listeners) {
+	    l.processComplete(event);
 	}
     }
