Index: /gli/trunk/src/org/greenstone/gatherer/remote/ActionQueue.java
===================================================================
--- /gli/trunk/src/org/greenstone/gatherer/remote/ActionQueue.java	(revision 17629)
+++ /gli/trunk/src/org/greenstone/gatherer/remote/ActionQueue.java	(revision 17630)
@@ -33,5 +33,4 @@
 import java.util.zip.*;
 import javax.swing.*;
-import java.io.ByteArrayOutputStream;
 import org.greenstone.gatherer.Configuration;
 import org.greenstone.gatherer.DebugStream;
@@ -68,8 +67,10 @@
     /** The queue of waiting jobs. */
     private ArrayList queue = null;
-    
-    
+    private boolean exited;
+
     public ActionQueue()
     {
+	super("RemoteGreenstoneServerActionQueue");
+	exited = false;
 	if (Gatherer.isGsdlRemote) {
 	    queue = new ArrayList();
@@ -86,80 +87,106 @@
     
     
-    public int size()
+    synchronized public int size()
     {
 	return queue.size();
     }
     
+    synchronized public RemoteGreenstoneServerAction getAction(int i)
+    {
+	return (RemoteGreenstoneServerAction)queue.get(i);
+    }
+
+    synchronized public boolean hasExited() { 
+	return exited; 
+    }
     
+    synchronized public void clear() { 
+	queue.clear(); 
+    }
+
     public void run()
     {
 	boolean exit = false;
+
 	while (!exit) {
-	    // If there are jobs on the queue, get the next in line and process it
-	    if (queue.size() > 0) {
-		RemoteGreenstoneServerAction remote_greenstone_server_action = (RemoteGreenstoneServerAction) queue.get(0);
+	    RemoteGreenstoneServerAction remote_greenstone_server_action = null;
+	    
+	    // Wait until we are notify()ed by addAction that there is a new job on the queue
+	    try {
+		Gatherer.remoteGreenstoneServer.getProgressBar().setAction(null);
+		synchronized (this) {
+		    while(queue.size() <= 0) {
+			wait(); // wait for queue size to become > 0, which is done by external thread (performAction())
+		    }
+		    // Now there is at least one job on the queue, get the next in line and process it
+		    remote_greenstone_server_action = (RemoteGreenstoneServerAction) queue.get(0); //getAction(0) is already synchronized 
+		}
+	    } catch (InterruptedException exception) {
+		// It may be that GLI is exiting if we get here 
+		exit = true;
+	    }
+	    
+	    if(exit) {
+		break;
+	    }
+	    
+	    try {
+		remote_greenstone_server_action.perform();
 		
-		try {
-		    remote_greenstone_server_action.perform();
-		    
-		    // No exceptions were thrown, so the action was successful
-		    remote_greenstone_server_action.processed_successfully = true;
+		// No exceptions were thrown, so the action was successful
+		remote_greenstone_server_action.processed_successfully = true;
+	    }
+	    catch (RemoteGreenstoneServerAction.ActionCancelledException exception) {
+		remote_greenstone_server_action.processed_successfully = false;
+	    } 
+	    catch(java.net.ConnectException exception) {
+		if(exception.getMessage().trim().startsWith("Connection refused")) {
+		    exit = true;
+		} else {
+		    DebugStream.printStackTrace(exception);
 		}
-		catch (RemoteGreenstoneServerAction.ActionCancelledException exception) {
-		    remote_greenstone_server_action.processed_successfully = false;
-		    exit = true;
-		} 
-		catch(java.net.ConnectException exception) {
-		    if(exception.getMessage().trim().startsWith("Connection refused")) {
-			exit = true;
-		    } else {
-			DebugStream.printStackTrace(exception);
-		    }
-		    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", exception.getMessage()), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
-		    remote_greenstone_server_action.processed_successfully = false;			
+		JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", exception.getMessage()), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
+		remote_greenstone_server_action.processed_successfully = false;			
+	    }
+	    catch (FileNotFoundException exception) {
+		// FileNotFoundException happens when there's no GS server at the user-provided
+		// url (the address of gliserver.pl is wrong).
+		exit = true;
+		DebugStream.printStackTrace(exception);
+		JOptionPane.showMessageDialog(Gatherer.g_man, 
+					      Dictionary.get("RemoteGreenstoneServer.Error", 
+							     "No gliserver.pl found. " + exception.getMessage()), 
+					      Dictionary.get("RemoteGreenstoneServer.Error_Title"), 
+					      JOptionPane.ERROR_MESSAGE);
+		remote_greenstone_server_action.processed_successfully = false;
+	    }
+	    catch (Exception exception) {
+		DebugStream.printStackTrace(exception);
+		JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", exception.getMessage()), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
+		remote_greenstone_server_action.processed_successfully = false;
+	    }
+	    
+	    // We're done with this action, for better or worse
+	    try {
+		remote_greenstone_server_action.processed = true;
+		synchronized(remote_greenstone_server_action) {
+		    remote_greenstone_server_action.notifyAll(); // notifies RemoteGreenstoneServer.performAction()
 		}
-		catch (FileNotFoundException exception) {
-		    // FileNotFoundException happens when there's no GS server at the user-provided
-		    // url (the address of gliserver.pl is wrong).
-		    exit = true;
-		    DebugStream.printStackTrace(exception);
-		    JOptionPane.showMessageDialog(Gatherer.g_man, 
-						  Dictionary.get("RemoteGreenstoneServer.Error", 
-								 "No gliserver.pl found. " + exception.getMessage()), 
-						  Dictionary.get("RemoteGreenstoneServer.Error_Title"), 
-						  JOptionPane.ERROR_MESSAGE);
-		    remote_greenstone_server_action.processed_successfully = false;
-		}
-		catch (Exception exception) {
-		    DebugStream.printStackTrace(exception);
-		    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", exception.getMessage()), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
-		    remote_greenstone_server_action.processed_successfully = false;
-		}
-		
-		// We're done with this action, for better or worse
-		remote_greenstone_server_action.processed = true;
+	    } catch (Exception exception) {
+		System.err.println("RemoteGreenstoneServerActionQueue.run() - exception: " + exception);
+	    }
+	    synchronized (this) { // remove the action just processed from the queue, since it's done.
 		queue.remove(0);
 	    }
-	    
-	    // Otherwise the queue is empty
-	    else {
-		Gatherer.remoteGreenstoneServer.getProgressBar().setAction(null);
-		
-		// Wait until we are notify()ed by addAction that there is a new job on the queue
-		synchronized (this) {
-		    try {
-			wait();
-		    }
-		    catch (InterruptedException exception) { }
-		}
-	    }
-	    
 	}
-	// stop the gazillion annoying error messages when the connection was simply
-	// refused or when the user pressed Cancel in the opening dialog, by exitting
-	// cleanly in one go.
-	//if(exit == true) {
-	    //Gatherer.exit();
-	//}
+
+	// Out of while, means exit = true
+	// Stop the gazillion annoying error messages when the connection was simply
+	// refused or when the user pressed Cancel in the opening dialog, by clearing
+	// the action queue of subsequent actions and setting exited to true.
+	synchronized(this) {
+	    queue.clear();
+	    exited = true;
+	}
     }
 }
Index: /gli/trunk/src/org/greenstone/gatherer/remote/RemoteGreenstoneServer.java
===================================================================
--- /gli/trunk/src/org/greenstone/gatherer/remote/RemoteGreenstoneServer.java	(revision 17629)
+++ /gli/trunk/src/org/greenstone/gatherer/remote/RemoteGreenstoneServer.java	(revision 17630)
@@ -66,6 +66,8 @@
 
     public RemoteGreenstoneServer() {
+	// Create the progress_bar first since ActionQueue uses it in its thread 
+	// (the thread will start immediately).
+	progress_bar = new RemoteGreenstoneServer.ProgressBar();
 	remote_greenstone_server_action_queue = new ActionQueue();
-	progress_bar = new RemoteGreenstoneServer.ProgressBar();
     }
 
@@ -230,5 +232,5 @@
 	}
     }
-
+    
 
     // ----------------------------------------------------------------------------------------------------
@@ -240,23 +242,38 @@
     private String performAction(RemoteGreenstoneServerAction remote_greenstone_server_action)
     {
+	// Check for whether the queue thread stopped running because 
+	// the user cancelled out. If so, exit GLI.
+	if(remote_greenstone_server_action_queue.hasExited()) {
+	    remote_greenstone_server_action_queue.clear();
+	    //remote_greenstone_server_action_queue = null;
+	    Gatherer.exit();
+	    return "";
+	}
+
 	// Add the action to the queue
 	remote_greenstone_server_action_queue.addAction(remote_greenstone_server_action);
+	String threadName = Thread.currentThread().getName();
 
 	// If we're running in the GUI thread we must return immediately
 	// We cannot wait for the action to complete because this will block any GUI updates
 	if (SwingUtilities.isEventDispatchThread()) {
-	    System.err.println("WARNING: In event dispatch thread, returning immediately...");
+	    System.err.println(threadName 
+			       + "\tACTION QUEUED: In event dispatch thread, returning immediately...\n\t" 
+			       + remote_greenstone_server_action);
 	    return null;
 	}
 
 	// Otherwise wait until the action is processed
-	while (!remote_greenstone_server_action.processed) {
+	try {
 	    synchronized (remote_greenstone_server_action) {
-		try {
+		while(!remote_greenstone_server_action.processed) {
+		    //System.err.println("Waiting for action to complete...: " + remote_greenstone_server_action);
 		    DebugStream.println("Waiting for action to complete...");
-		    remote_greenstone_server_action.wait(500);
+		    remote_greenstone_server_action.wait(); // wait to be notified when the action has been processed 
 		}
-		catch (InterruptedException exception) {}
-	    }
+	    }
+	} catch (Exception e) {
+	    System.err.println("RemoteGreenstoneServer.performAction() - exception: " + e);
+	    e.printStackTrace();
 	}
 
@@ -285,6 +302,6 @@
 	}
 
-
-	public void setAction(String action)
+	/** synchronized to avoid conflicts since several threads access this */
+	synchronized public void setAction(String action)
 	{
 	    if (action != null) {
@@ -310,5 +327,6 @@
     }
     
-    public RemoteGreenstoneServer.ProgressBar getProgressBar()
+    /** synchronized to avoid conflicts since several threads access this */
+    synchronized public RemoteGreenstoneServer.ProgressBar getProgressBar()
     {
 	return progress_bar;
@@ -327,5 +345,5 @@
 	    remote_greenstone_server_authentication = new RemoteGreenstoneServerAuthenticator().getAuthentication();
 	}
-
+    
 
 	static private class RemoteGreenstoneServerAuthenticator
@@ -366,4 +384,5 @@
 	    }
 	    catch (Exception exception) {
+		System.err.println("Exception occurred when authenticating the user: " + exception);
 		DebugStream.printStackTrace(exception);
 	    }
