Index: /gli/branches/rtl-gli/src/org/greenstone/gatherer/Configuration.java
===================================================================
--- /gli/branches/rtl-gli/src/org/greenstone/gatherer/Configuration.java	(revision 18362)
+++ /gli/branches/rtl-gli/src/org/greenstone/gatherer/Configuration.java	(revision 18363)
@@ -67,6 +67,5 @@
     /** The name of the general Gatherer configuration file. */
     static public String CONFIG_XML = "config.xml";
-    /** The name of the general Gatherer configuration file for running with GS3. */
-    static public String GS3_CONFIG_XML = "config3.xml";
+    static public String FEDORA_CONFIG_PREFIX = "fedora-";
 
     /** The name of the root element of the subtree containing gatherer configuration options. This is required as the document itself may contain several other subtrees of settings (such as in the case of a '.col' file). */
@@ -101,4 +100,7 @@
     /** If we are using GLI in Greenstone 3, the path to gsdl3 src directory (== gsdl3 dir)*/
     static public String gsdl3_src_path = "";
+
+    static public FedoraInfo fedora_info = null;
+    
     /** The path to the PERL executable, up to and including Perl.exe. */
     static public String perl_path = "";
@@ -126,6 +128,6 @@
     static public URL gliserver_url = null;
     static public URL library_url = null;
-
-
+    
+    
     /** Constructor.
      * @param gsdl_path The path to the Greenstone directory as a <strong>String</strong>.
@@ -133,9 +135,12 @@
      * @param gsdl3_src_path The path to the Greenstone 3 src directory as a <strong>String</strong>.
      * @param site_name The name of the Greenstone 3 site currently in use.
+     * @param fedora_info A FedoraInfo object containing the user-provided details for creating
+     * a connection to a Fedora repository.
      */
-    public Configuration(String gli_user_directory_path, String gsdl_path, String gsdl3_path, String gsdl3_src_path, String site_name)
+    public Configuration(String gli_user_directory_path, String gsdl_path, String gsdl3_path, String gsdl3_src_path, 
+				 String site_name, FedoraInfo fedora_info) 
     {
 	super();
-	self = this;
+	self = this; // allows Configuration to statically refer to itself in the static methods
 
 	this.gli_user_directory_path = gli_user_directory_path;
@@ -145,12 +150,16 @@
 	this.site_name = site_name;
 
+	this.fedora_info = fedora_info;
+
 	// Try to load the configuration file from the user specific location
 	String config_xml_file_name = CONFIG_XML;
-	if (gsdl3_path != null || (Gatherer.isGsdlRemote && Gatherer.GS3)) {
-	    config_xml_file_name = GS3_CONFIG_XML;
+
+	if (fedora_info != null && fedora_info.isActive()) {
+	    config_xml_file_name = FEDORA_CONFIG_PREFIX + config_xml_file_name;
 	}
 
 	// If the existing user config.xml file isn't recent enough, backup the old version and update it
 	File config_xml_file = new File(gli_user_directory_path + config_xml_file_name);
+
 	if (config_xml_file != null && config_xml_file.exists()) {
 	    just_updated_config_xml_file = updateUserConfigXMLFileIfNecessary(config_xml_file);
@@ -171,5 +180,5 @@
 
 	// Read the Greenstone library URL from the config file
-	String library_url_string = getString("general.library_url", true);
+	String library_url_string = getString("general.library_url"+gliPropertyNameSuffix(), true);
 	if (!library_url_string.equals("")) {
 	    try {
@@ -194,25 +203,49 @@
 	}
 	
-	if (gsdl3_path != null || (Gatherer.GS3 && Gatherer.isGsdlRemote)) {
-	    if (this.site_name == null || this.site_name.equals("")) {
-		this.site_name = getString("general.site_name", true);
-		this.servlet_path = getString("general.servlet_path", true);
-		if (this.site_name.equals("")) {
-		    this.site_name = "localsite"; // can we assume these??
-		    this.servlet_path = "/library";
-		    setString("general.site_name", true, this.site_name);
-		    setString("general.servlet_path", true, this.servlet_path);
-		}
-		
-	    } else {
-		// we set the current one in the config
-		setString("general.site_name", true, this.site_name);
-		if (this.servlet_path != null && !this.servlet_path.equals("")) {
-		    setString("general.servlet_path", true, this.servlet_path);
-		}
-	    }
-	}
-    }
-
+	if(gsdl3_path != null) {
+	    prepareForGS3();
+	}
+
+    }
+
+    /** @return the suffix for the the config file's library_url/open_collection propertyname. 
+     * For Fedora and remote GS2 cases, there is no suffix.
+     * However, when dealing with a local Greenstone server, this returns suffix _gs2 or _gs3
+     * so it can be appended to the default library_url/open_collection propertynames.
+     * Having 2 separate library URL properties and open_collection properties for the two 
+     * local versions of Greenstone allows GLI to save the library_url and last opened 
+     * collection for both GS2 and GS3, in case anyone runs them alternatively. (This is useful
+     * when developing and testing across GS versions.) */
+    static public String gliPropertyNameSuffix() {
+	if(Gatherer.isGsdlRemote) {
+	    return ""; // no special suffix
+	} else if(Gatherer.GS3) { // local GS3, including FLI for GS3
+	    return "_gs3";
+	} else { // local GS2, including FLI for GS2
+	    return "_gs2";
+	}
+    }
+
+
+    // Called when (gsdl3_path != null) || (Gatherer.GS3 && Gatherer.isGsdlRemote) 
+    static public void prepareForGS3() {
+	if (site_name == null || site_name.equals("")) {
+	    site_name = getString("general.site_name", true);
+	    servlet_path = getString("general.servlet_path", true);
+	    if (site_name.equals("")) {
+		site_name = "localsite"; // can we assume these??
+		servlet_path = "/library";
+		setString("general.site_name", true, site_name);
+		setString("general.servlet_path", true, servlet_path);
+	    }
+	    
+	} else {
+	    // we set the current one in the config
+	    setString("general.site_name", true, site_name);
+	    if (servlet_path != null && !servlet_path.equals("")) {
+		setString("general.servlet_path", true, servlet_path);
+	    }
+	}
+    }
 
     static private boolean updateUserConfigXMLFileIfNecessary(File config_xml_file)
@@ -228,10 +261,10 @@
 	String new_version = new_document.getDocumentElement().getAttribute(StaticStrings.VERSION_ATTRIBUTE);
 	String old_version = old_document.getDocumentElement().getAttribute(StaticStrings.VERSION_ATTRIBUTE);
-	if (new_version.compareTo(old_version) <= 0) {
+	if (new_version.equals(old_version)) {
 	    // Don't need to update file
 	    return false;
 	}
 
-	System.err.println("Updating user config.xml from version " + old_version + " to version " + new_version + "...");
+	System.err.println("Converting user config.xml from version " + old_version + " to version " + new_version + "...");
 
 	// Build up the new user config.xml file from the template config.xml with the user's preferences added
@@ -254,12 +287,15 @@
 		// Argument found
 		if (old_argument_element_name.equals(new_argument_element_name)) {
-		    if (!new_argument_element_name.equals("general.open_collection")) {
-			String old_argument_element_value = XMLTools.getElementTextValue(old_argument_element);
-			if (!old_argument_element_value.equals(new_argument_element_value)) {
-			    XMLTools.setElementTextValue(new_argument_element, old_argument_element_value);
-			}
+		  // we don't want to carry over open_collection or library_url
+		  // as these may be invalid
+		  if (!new_argument_element_name.equals("general.open_collection"+Configuration.gliPropertyNameSuffix()) && !new_argument_element_name.equals("general.library_url"+Configuration.gliPropertyNameSuffix())) {
+		    
+		    String old_argument_element_value = XMLTools.getElementTextValue(old_argument_element);
+		    if (!old_argument_element_value.equals(new_argument_element_value)) {
+		      XMLTools.setElementTextValue(new_argument_element, old_argument_element_value);
 		    }
-
-		    // We don't care about this option any more
+		  }
+		  
+		  // We don't care about this option any more
 		    old_argument_element.getParentNode().removeChild(old_argument_element);
 		    break;
@@ -597,4 +633,12 @@
     }
 
+    static public String getApplicationTitle() {
+	String gli_title = getString("GLI.Title", GENERAL_SETTING);
+	String title = (gli_title=="") ? Gatherer.PROGRAM_NAME : gli_title;
+
+	return title;
+    }
+
+
     static public String getServletPath() {
 	return servlet_path;
@@ -688,15 +732,9 @@
 	File user_config_xml = null;
 	String config_xml_name = CONFIG_XML;
-	if (gsdl3_path!=null) {
-	    config_xml_name = GS3_CONFIG_XML;
-	}
-
-	if (Gatherer.isGsdlRemote) {
-	    if (Gatherer.GS3){
-		config_xml_name = GS3_CONFIG_XML;
-	    }else{
-		config_xml_name = CONFIG_XML;
-	    }
-	}
+
+	if (fedora_info != null && fedora_info.isActive()) {
+	    config_xml_name = FEDORA_CONFIG_PREFIX + config_xml_name;
+	}
+
 	try {
 	    user_config_xml = new File(gli_user_directory_path + config_xml_name);
Index: /gli/branches/rtl-gli/src/org/greenstone/gatherer/FedoraInfo.java
===================================================================
--- /gli/branches/rtl-gli/src/org/greenstone/gatherer/FedoraInfo.java	(revision 18363)
+++ /gli/branches/rtl-gli/src/org/greenstone/gatherer/FedoraInfo.java	(revision 18363)
@@ -0,0 +1,177 @@
+/**
+ *#########################################################################
+ *
+ * A component of the Gatherer application, part of the Greenstone digital
+ * library suite from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * Author: John Thompson and David Bainbridge, 
+ *         Greenstone Digital Library, University of Waikato
+ *
+ * Copyright (C) 1999 New Zealand Digital Library Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *########################################################################
+ */
+
+package org.greenstone.gatherer;
+
+import java.io.*;
+import org.greenstone.gatherer.util.StaticStrings; 
+import org.greenstone.gatherer.util.Utility;
+
+public class FedoraInfo 
+{
+    public static final int minimumSupportedMajorVersion = 2;
+
+    private boolean active = false;
+    private String home = null;
+    private String version = null;
+
+    private String hostname = null;
+    private String port     = null;
+    private String username = null;
+    private String password = null;
+    private String protocol = null;
+
+    public FedoraInfo() 
+    {	
+	this("localhost", "8080", "fedoraAdmin", "fedoraAdmin", "http");
+    }
+
+    public FedoraInfo(String hostname, String port, String username, String password, String protocol) 
+    {
+	this.hostname = hostname;
+	this.port     = port;
+	this.username = username;
+	this.password = password;
+	this.protocol = protocol;
+    }
+
+    // Called when we are attempting to run fedora
+    public void setActive(boolean active) {
+	this.active = active; 
+    }
+
+    // Called when an environment variable was wrongly set for running Fedora
+    public void deactivate(String errorMessage) {
+	this.active = false;
+	// display an errormessage and exit cleanly
+	System.err.println(errorMessage);
+	Gatherer.exit();
+    }
+
+    public boolean isActive()
+    {
+	return active;
+    }
+
+    public void setHome(String home)
+    {
+	this.home = home;
+    }
+
+
+    public String getHome()
+    {
+	return home;
+    }
+
+    public void setVersion(String version)
+    {
+	String firstChar = version.substring(0, 1);
+	if(!Character.isDigit(version.charAt(0))) { // version is illegal if it does not begin with a number
+	    deactivate("Incorrect format for major version: " + version + ". The Fedora version must start with a number.");
+	}
+	else if(Integer.parseInt(firstChar) < minimumSupportedMajorVersion) { 
+	    // major version number of Fedora must be more than this
+	    deactivate("The major version number of Fedora must be at least " +  minimumSupportedMajorVersion + ".");
+	}
+	else { // acceptable
+	    this.version = version;
+	} 
+    }
+
+
+    public String getVersion()
+    {
+	return version;
+    }
+
+    public void setHostname(String hostname)
+    {
+	this.hostname = hostname;
+    }
+
+    public String getHostname()
+    {
+	return hostname;
+    }
+
+
+    public void setPort(String port)
+    {
+	this.port = port;
+    }
+
+    public String getPort()
+    {
+	return port;
+    }
+
+
+    public void setUsername(String username)
+    {
+	this.username = username;
+    }
+
+    public String getUsername()
+    {
+	return username;
+    }
+
+
+    public void setPassword(String password)
+    {
+	this.password = password;
+    }
+
+    public String getPassword()
+    {
+	return password;
+    }
+
+
+    public void setProtocol(String protocol)
+    {
+	this.protocol = protocol;
+    }
+
+    public String getProtocol()
+    {
+	return protocol;
+    }
+
+    public String getBaseURL() 
+    {
+	return this.protocol+"://"+this.hostname+":"+this.port+"/";
+    }
+    
+    // The library preview address for Fedora
+    public String getLibraryURL() 
+    {
+	return this.getBaseURL() + "fedora/search";
+    }
+}
Index: /gli/branches/rtl-gli/src/org/greenstone/gatherer/GAuthenticator.java
===================================================================
--- /gli/branches/rtl-gli/src/org/greenstone/gatherer/GAuthenticator.java	(revision 18362)
+++ /gli/branches/rtl-gli/src/org/greenstone/gatherer/GAuthenticator.java	(revision 18363)
@@ -42,5 +42,8 @@
 import java.util.*;
 import javax.swing.*;
+
+
 import org.greenstone.gatherer.gui.GLIButton;
+
 
 /** Provides a graphic authenticator for network password requests.
@@ -65,5 +68,16 @@
     /** The default size of this dialog. */
     static final private Dimension SIZE = new Dimension(470,160);
-
+    
+    /** For Wget downloads, we want to avoid the second automatic request for proxy authentication
+     * But the settings for that specific case will otherwise interfere with how this GAuthenticator 
+     * is to function in the usual situation. For this reason, we use two modes.*/
+    static final public int REGULAR = 0;
+    static final public int DOWNLOAD = 1;
+    static private int operationMode = REGULAR; 
+
+    public static void setMode(int mode) {
+	operationMode = mode;
+    }
+    
     /** Constructor. */
     public GAuthenticator() {
@@ -75,5 +89,27 @@
      * @see org.greenstone.gatherer.GAuthenticator.RequestFocusListener
      */
-    protected PasswordAuthentication getPasswordAuthentication() {
+    protected PasswordAuthentication getPasswordAuthentication(String username_str, String password_str) {
+	if(operationMode == DOWNLOAD) { // special handling of proxy authentication popup for Wget downloads
+	    
+	    // Don't prompt if the details were already saved for the same host and port. This is necessary
+	    // when running wget because wget requires proxy authentication. And without the following, the
+	    // regular proxy authentication would also popup a dialog requesting the same information.
+	    
+	    String key = getRequestingHost() + ":" + getRequestingPort();
+	    String value = (String)authentications.get(key);
+	    
+	    if(value != null) { // authentication for this host and port was already stored
+		// Arguments may be null. If so, retrieve them from the stored value
+		if(username_str == null) {
+		    username_str = value.substring(0, value.indexOf("@"));
+		} 
+		if(password_str == null) {
+		    password_str = value.substring(value.indexOf("@") + 1);
+		}
+		operationMode = REGULAR; // reset the state of the Authenticator to normal mode
+		return new PasswordAuthentication(username_str, password_str.toCharArray());
+	    }
+	}
+	
 	// Component definition.
 	dialog = new JDialog (Gatherer.g_man, Dictionary.get("GAuthenticator.Title"), true);
@@ -82,8 +118,13 @@
 	JPanel content_pane = (JPanel) dialog.getContentPane();
 	JLabel title_label = new JLabel(getMessageString());
+
 	JPanel user_panel = new JPanel();
 	JLabel username_label = new JLabel(Dictionary.get("GAuthenticator.Username"));
 	JTextField username = new JTextField();
 	username.setToolTipText(Dictionary.get("GAuthenticator.Username_Tooltip"));
+	if (username_str != null) {
+	    username.setText(username_str);
+	}
+
 	JPanel password_panel = new JPanel();
 	JLabel password_label = new JLabel(Dictionary.get("GAuthenticator.Password"));
@@ -91,4 +132,8 @@
 	password.setEchoChar('*');
 	password.setToolTipText(Dictionary.get("GAuthenticator.Password_Tooltip"));
+	if (password_str != null) {
+	    password.setText(password_str);
+	}
+
 	JPanel button_panel = new JPanel();
 	ok_button = new GLIButton(Dictionary.get("General.OK"), Dictionary.get("General.OK_Tooltip"));
@@ -134,4 +179,7 @@
     }
 
+    protected PasswordAuthentication getPasswordAuthentication() {
+	return getPasswordAuthentication(null,null);
+    }
 
     /** This is defined so it can be overridden by subclasses (getRequestingPrompt is final). */
Index: /gli/branches/rtl-gli/src/org/greenstone/gatherer/Gatherer.java
===================================================================
--- /gli/branches/rtl-gli/src/org/greenstone/gatherer/Gatherer.java	(revision 18362)
+++ /gli/branches/rtl-gli/src/org/greenstone/gatherer/Gatherer.java	(revision 18363)
@@ -36,6 +36,9 @@
 import javax.swing.plaf.*;
 import javax.swing.text.*;
+
+
 import org.greenstone.gatherer.Configuration;
 import org.greenstone.gatherer.GAuthenticator;
+import org.greenstone.gatherer.FedoraInfo;
 import org.greenstone.gatherer.collection.CollectionManager;
 import org.greenstone.gatherer.feedback.ActionRecorderDialog;
@@ -51,4 +54,5 @@
 import org.greenstone.gatherer.gui.URLField;
 import org.greenstone.gatherer.gui.WarningDialog;
+import org.greenstone.gatherer.gui.FedoraLogin;
 import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
 import org.greenstone.gatherer.util.JarTools;
@@ -74,10 +78,12 @@
 		* in a line which maches this java regex:
 		* ^(.*)String\s*PROGRAM_VERSION\s*=\s*"trunk";
-		* If change the daclaration and it no longer matches the regex, please
+		* If change the declaration and it no longer matches the regex, please
 		* change the regex in the gs3-release-maker code and in this message
 		*/
+
     static final public String PROGRAM_VERSION = "trunk";
 
     static private Dimension size = new Dimension(800, 540);
+    static public RemoteGreenstoneServer remoteGreenstoneServer = null;
 
     /** Has the exit flag been set? */
@@ -165,12 +171,9 @@
 	    // We don't have a local Greenstone!
 	    go.gsdl_path = null;
+	    go.gsdl3_path=null;
+	    go.gsdl3_src_path=null;
 
 	    // We have to use our own collect directory since we can't use the Greenstone one
 	    setCollectDirectoryPath(getGLIUserDirectoryPath() + "collect" + File.separator);
-	    if (go.run_gsdl3){	 
-		GS3=true;
-		go.gsdl3_path=null;
-		go.gsdl3_src_path=null;
-	    }
 	}
 	// No, we have a local Greenstone
@@ -186,10 +189,12 @@
 	// More special code for running with a remote Greenstone
 	if (isGsdlRemote) {
-	    Configuration.TEMPLATE_CONFIG_XML = "xml/configRemote.xml";
-	    if (!go.run_gsdl3){	 
-		Configuration.CONFIG_XML = "configRemote.xml";
-	    }else{
-		Configuration.GS3_CONFIG_XML = "config3Remote.xml";
-	    }
+	    if (go.fedora_info.isActive()) {
+		Configuration.TEMPLATE_CONFIG_XML = "xml/" + Configuration.FEDORA_CONFIG_PREFIX + "configRemote.xml";
+	    }
+	    else {
+		Configuration.TEMPLATE_CONFIG_XML = "xml/configRemote.xml";
+	    }
+
+	    Configuration.CONFIG_XML = "configRemote.xml"; 
 
 	    File collect_directory = new File(Gatherer.getCollectDirectoryPath());
@@ -198,6 +203,14 @@
 	    }
 	}
-
-	init(go.gsdl_path, go.gsdl3_path, go.gsdl3_src_path, go.local_library_path, go.library_url_string, 
+	else {	    
+	    if (go.fedora_info.isActive()) {
+		Configuration.TEMPLATE_CONFIG_XML = "xml/" + Configuration.FEDORA_CONFIG_PREFIX + Configuration.CONFIG_XML;
+	    }
+	    // else, the CONFIG_XML uses the default config file, which is for the local GS server
+	}
+
+	init(go.gsdl_path, go.gsdl3_path, go.gsdl3_src_path, 
+	     go.fedora_info,
+	     go.local_library_path, go.library_url_string, 
 	     go.gliserver_url_string, go.debug, go.perl_path, go.no_load, go.filename, go.site_name,
 	     go.servlet_path);
@@ -205,5 +218,7 @@
 
 
-    public void init(String gsdl_path, String gsdl3_path, String gsdl3_src_path, String local_library_path,
+    public void init(String gsdl_path, String gsdl3_path, String gsdl3_src_path, 
+		     FedoraInfo fedora_info,
+		     String local_library_path,
 		     String library_url_string, String gliserver_url_string, boolean debug_enabled,
 		     String perl_path, boolean no_load, String open_collection, 
@@ -245,6 +260,7 @@
 	try {
 	    // Load GLI config file
-	    new Configuration(getGLIUserDirectoryPath(), gsdl_path, gsdl3_path, gsdl3_src_path, site_name);
-
+	    new Configuration(getGLIUserDirectoryPath(), gsdl_path, gsdl3_path, gsdl3_src_path, site_name,
+			      fedora_info);
+	    
 	    // Check we know where Perl is
 	    Configuration.perl_path = perl_path;
@@ -278,9 +294,39 @@
 	    }
 
-	    // Start up the local library server, if that's what we want
-	    if (Utility.isWindows() && local_library_path != null && !isGsdlRemote && !GS3) {
-		LocalLibraryServer.start(gsdl_path, local_library_path);
-	    }
-
+	    if (fedora_info.isActive()) {
+		popupFedoraInfo();
+	    }
+
+	    // Finally, we're ready to find out the version of the remote Greenstone server 
+	    if(isGsdlRemote) {
+		// instantiate the RemoteGreenstoneServer object first
+		remoteGreenstoneServer = new RemoteGreenstoneServer();
+
+		int greenstoneVersion = 2;
+		requestGLIServerURL();
+		gliserver_url_string = Configuration.gliserver_url.toString();
+		
+		greenstoneVersion = remoteGreenstoneServer.getGreenstoneVersion();
+		// Display the version to make error reports a lot more useful
+		System.err.println("Remote Greenstone server version: " + greenstoneVersion);
+		if(greenstoneVersion >= 3) {
+		    this.GS3 = true;
+		    Configuration.prepareForGS3();
+		} 
+		
+		if(fedora_info.isActive()) { 
+		    // when GS server is remote, FEDORA_HOME resides on the remote server side,
+		    // but we know the library URL from user-provided information
+		    library_url_string = fedora_info.getLibraryURL();
+		} else {
+		    library_url_string = remoteGreenstoneServer.getLibraryURL(Configuration.gliserver_url.toString());
+		}
+	    }
+	    else { // local greenstone: Start up the local library server, if that's what we want
+		if (Utility.isWindows() && local_library_path != null && !GS3) {
+		    LocalLibraryServer.start(gsdl_path, local_library_path);
+		}
+	    }
+	    
 	    // The "-library_url" option overwrites anything in the config files
 	    if (library_url_string != null && library_url_string.length() > 0) {
@@ -293,4 +339,5 @@
 		}
 	    }
+  
 
 	    // Check that we now know the Greenstone library URL, since we need this for previewing collections
@@ -298,12 +345,4 @@
 	    if (Configuration.library_url == null) {
 		missingEXEC(); 
-		if ((Configuration.library_url!=null) && isGsdlRemote && (gliserver_url_string==null)){
-		    if (GS3){
-			default_gliserver_url = new URL(Configuration.library_url.toString() + "/cgi-bin/gliserver4gs3.pl");
-		    }else{
-			default_gliserver_url = new URL(Configuration.library_url.toString().substring(0,Configuration.library_url.toString().lastIndexOf("/library")) + "/gliserver.pl");
-		    }
-		    missingGLIServer();
-		}
 	    }
 
@@ -321,19 +360,4 @@
 	    // If we're using a remote Greenstone we need to know where the gliserver script is
 	    DebugStream.println("Configuration.gliserver_url = " + Configuration.gliserver_url);
-	    if (isGsdlRemote) {
-		if (Configuration.gliserver_url == null) {
-		    if (Configuration.library_url != null) {
-			if (GS3){
-			    default_gliserver_url = new URL(Configuration.library_url.toString() + "/cgi-bin/gliserver4gs3.pl");
-			}else{
-			    default_gliserver_url = new URL(Configuration.library_url.toString().substring(0,Configuration.library_url.toString().lastIndexOf("/library")) + "/gliserver.pl");
-			}
-		    }
-		    missingGLIServer();
-		}
-		if (Configuration.gliserver_url != null) {
-		    gliserver_url_string = Configuration.gliserver_url.toString();
-		}
-	    }
 
 	    if (GS3) {
@@ -348,4 +372,11 @@
 	    if (GS3 && Configuration.servlet_path == null) {
 		Configuration.servlet_path = servlet_config.getServletPath(Configuration.site_name);
+	    }
+	     
+	    // ensure that a directory called 'cache' exists in the GLI user directory  
+	    File user_cache_dir = new File(Gatherer.getGLIUserCacheDirectoryPath());
+	    System.err.println("User cache dir: " + Gatherer.getGLIUserCacheDirectoryPath());
+	    if (!user_cache_dir.exists() && !user_cache_dir.mkdir()) {
+		System.err.println("Warning: Unable to make directory: " + user_cache_dir);
 	    }
 
@@ -424,5 +455,6 @@
 	    open_collection_file_path = open_collection;
 	    if (open_collection_file_path == null) {
-		open_collection_file_path = Configuration.getString("general.open_collection", true);
+		open_collection_file_path = Configuration.getString(
+			"general.open_collection"+Configuration.gliPropertyNameSuffix(), true);
 	    }
 	    if (no_load || open_collection_file_path.equals("")) {
@@ -434,4 +466,5 @@
 	}
 
+	
 	// Create GUI Manager (last) or else suffer the death of a thousand NPE's
 	g_man = new GUIManager(size);
@@ -443,12 +476,24 @@
 	// If using a remote Greenstone we need to download the collection configurations now
 	if (Gatherer.isGsdlRemote) {
-	    if (RemoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
+	    if (remoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
 		// !! Something went wrong downloading the collection configurations
 		System.err.println("Error: Could not download collection configurations.");
-		System.exit(0);
-	    }
-	}
-
-    }
+		if(!Gatherer.isApplet) { // don't close the browser if it is an applet!
+		    System.exit(0);
+		}
+	    }
+	}
+    }
+
+    
+    /** Returns the correct version of the (local or remote) Greenstone server if init() has already been called. */
+    public static int serverVersionNumber() { 
+	return GS3 ? 3 : 2;
+    } 
+
+    /** Returns "Server: version number" if init() has already been called. */
+    public static String getServerVersionAsString() { 
+	return "Server: v" + serverVersionNumber();
+    } 
 
     public void openGUI()
@@ -511,5 +556,5 @@
 	// If using a remote Greenstone we need to download the collection configurations now
 	if (Gatherer.isGsdlRemote) {
-	    if (RemoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
+	    if (remoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
 		// !! Something went wrong downloading the collection configurations
 		System.err.println("Error: Could not download collection configurations.");
@@ -561,6 +606,8 @@
 
 	// Get the gui to deallocate
-	g_man.destroy();
-	g_man_built = false;
+	if(g_man != null) {
+	    g_man.destroy();
+	    g_man_built = false;
+	}
 
 	// Flush debug
@@ -574,5 +621,5 @@
 	// If we're using a remote Greenstone server we need to make sure that all jobs have completed first
 	if (isGsdlRemote) {
-	    RemoteGreenstoneServer.exit();
+	    remoteGreenstoneServer.exit();
 	}
 
@@ -715,4 +762,8 @@
 	    url = null;
 	}
+	catch(java.net.ConnectException connectException) {
+	    JOptionPane.showMessageDialog(g_man, Dictionary.get("Preferences.Connection.Library_Path_Connection_Failure", Configuration.library_url.toString()), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
+	    DebugStream.println(connectException.getMessage());
+	}
 	catch (Exception exception) {            
 	    DebugStream.printStackTrace(exception);
@@ -767,17 +818,54 @@
     static private void missingEXEC() {
 	WarningDialog dialog;
+	String configPropertyName = "general.library_url"+Configuration.gliPropertyNameSuffix();
+
 	if (GS3) {
-	    dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC_GS3.Title"), Dictionary.get("MissingEXEC_GS3.Message"), "general.library_url", false);
-	}else {
-	    dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC.Title"), Dictionary.get("MissingEXEC.Message"), "general.library_url", false);
-	}
-	dialog.setValueField(new URLField(Configuration.getColor("coloring.editable_foreground", false), Configuration.getColor("coloring.editable_background", false)));
+	    // Warning dialog with no cancel button and no "turn off warning" checkbox 
+	    dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC_GS3.Title"), Dictionary.get("MissingEXEC_GS3.Message"), configPropertyName, false, false);
+	} else { // local case
+	    dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC.Title"), Dictionary.get("MissingEXEC.Message"), configPropertyName, false);
+	}
+
+	JTextField field = new URLField.Text(Configuration.getColor("coloring.editable_foreground", false), Configuration.getColor("coloring.editable_background", false));
+
+	// Set the default library URL to the tomcat server and port number
+	// specified in the build.properties located in the gsdl3_src_path 
+	if (GS3) {
+	    String host = "localhost";
+	    String port = "8080";
+	    
+	    File buildPropsFile = new File(Configuration.gsdl3_src_path + File.separator + "build.properties");
+	    if(buildPropsFile.exists()) {
+		Properties props = new Properties();
+		try{
+		    props.load(new FileInputStream(buildPropsFile));
+		    host = props.getProperty("tomcat.server", host); 
+		    port = props.getProperty("tomcat.port", port); 
+		}catch(Exception e){
+		    DebugStream.println("Could not load build.properties file");
+		    System.err.println("Could not load build.properties file");
+		}
+		props = null;
+	    }
+	    String defaultURL = "http://"+host+":"+port+"/"+"greenstone3/library";
+	    field.setText(defaultURL);
+	    field.selectAll();
+	}
+	dialog.setValueField(field);
 	dialog.display();
 	dialog.dispose();
 	dialog = null;
 
-	String library_url_string = Configuration.getString("general.library_url", true);
+	String library_url_string = Configuration.getString(configPropertyName, true);
 	if (!library_url_string.equals("")) {
 	    try {
+		// WarningDialog does not allow invalid URLs, so the following is ignored:
+		// make sure the URL the user provided contains the http:// prefix
+		// and then save the corrected URL
+		if(!library_url_string.startsWith("http://") 
+		   && !library_url_string.startsWith("https://")) {
+		    library_url_string = "http://"+library_url_string;
+		    Configuration.setString(configPropertyName, true, configPropertyName);
+		}
 		Configuration.library_url = new URL(library_url_string);
 	    }
@@ -789,21 +877,113 @@
 
 
-    static private void missingGLIServer()
+
+    /** Prints a warning message about a missing library path, which means the final collection cannot be previewed in the Gatherer.
+     */
+    static private void popupFedoraInfo() {
+
+	FedoraLogin dialog = new FedoraLogin("Fedora Login", false);
+
+	if (Configuration.library_url == null) {
+	    
+	    String library_url_string = dialog.getLibraryURL();
+	    if (!library_url_string.equals("")) {
+		try {
+		    Configuration.library_url = new URL(library_url_string);
+		}
+		catch (MalformedURLException exception) {
+		    DebugStream.printStackTrace(exception);
+		}
+	    }
+	}
+	
+	boolean showLogin = true;
+	do {
+	    if(!dialog.loginRequested()) { // user pressed cancel to exit the FedoraLogin dialog
+		System.exit(0);
+	    } else {
+		showLogin = dialog.loginRequested();
+		String hostname = dialog.getHostname();
+		String port     = dialog.getPort();
+		String username = dialog.getUsername();
+		String password = dialog.getPassword();
+		String protocol = dialog.getProtocol();
+	    
+		Configuration.fedora_info.setHostname(hostname);
+		Configuration.fedora_info.setPort(port);
+		Configuration.fedora_info.setUsername(username);
+		Configuration.fedora_info.setPassword(password);
+		Configuration.fedora_info.setProtocol(protocol);
+	    
+		String ping_url_str = protocol + "://" + hostname + ":" + port + "/fedora";
+		String login_str = username + ":" + password;
+		
+		String login_encoding = new sun.misc.BASE64Encoder().encode(login_str.getBytes());
+				
+		try {
+		    URL ping_url = new URL(ping_url_str);
+		    URLConnection uc = ping_url.openConnection();
+		    uc.setRequestProperty  ("Authorization", "Basic " + login_encoding);
+		    // Attempt to access some content ...
+		    InputStream content = (InputStream)uc.getInputStream();
+		    
+		    // if no exception occurred in the above, we would have come here:
+		    showLogin = false;
+		    dialog.dispose();
+		}
+		catch (Exception exception) {
+		    // TODO: move into dictionary
+		    String[] errorMessage = {"Failed to connect to the Fedora server.", "It might not be running, or",
+					     "incorrect username and/or password."};
+		    dialog.setErrorMessage(errorMessage);
+		    //DebugStream.printStackTrace(exception);
+		    // exception occurred, show the dialog again (do this after printing to
+		    // debugStream, else the above does not get done for some reason).
+		    dialog.setVisible(true);
+		}
+	    } 
+	} while(showLogin);
+
+	dialog = null; // no more need of the dialog
+	
+	// Now we are connected.
+    }
+
+
+
+    static private void requestGLIServerURL()
     {
 	WarningDialog dialog;
-	if (GS3) {
-	    dialog = new WarningDialog("warning.MissingGLIServer", Dictionary.get("MissingGLIServer_GS3.Title"), Dictionary.get("MissingGLIServer_GS3.Message"), "general.gliserver_url", false);
-	}else {
-	    dialog = new WarningDialog("warning.MissingGLIServer", Dictionary.get("MissingGLIServer.Title"), Dictionary.get("MissingGLIServer.Message"), "general.gliserver_url", false);
-	}
-	dialog.setValueField(new URLField(Configuration.getColor("coloring.editable_foreground", false), Configuration.getColor("coloring.editable_background", false)));
-	
+	String[] defaultURLs = {
+	    "http://localhost:8080/greenstone3/cgi-bin/gliserver.pl", 
+	    "http://localhost:8080/gsdl/cgi-bin/gliserver.pl"
+	};
+
+	// Warning dialog with no cancel button and no "turn off warning" checkbox 
+	// (since user-input of the gliserver script is mandatory)
+	dialog = new WarningDialog("warning.MissingGLIServer", Dictionary.get("MissingGLIServer.Title"), Dictionary.get("MissingGLIServer.Message"), "general.gliserver_url", false, false); 
+
+	dialog.setValueField(new URLField.DropDown(Configuration.getColor("coloring.editable_foreground", false), 
+						   Configuration.getColor("coloring.editable_background", false), 
+						   defaultURLs, "general.gliserver_url", 
+						   "general.open_collection"+Configuration.gliPropertyNameSuffix(), 
+						   "gliserver.pl")); 
+
 	if (Gatherer.default_gliserver_url!=null){
 	    dialog.setValueField(Gatherer.default_gliserver_url.toString());
 	}
+
+	// A WarningDialog cannot always be made to respond (let alone to exit the program) on close. We
+	// handle the response of this particular WarningDialog here: a URL for gliserver.pl is a crucial
+	// piece of user-provided data. Therefore, if no URL was entered for gliserver.pl, it'll exit safely.
+	dialog.addWindowListener(new WindowAdapter() {
+		public void windowClosing(WindowEvent e) {
+		    Gatherer.exit();
+		}
+	    });
 	
 	dialog.display();
 	dialog.dispose();
 	dialog = null;
+
 	
 	String gliserver_url_string = Configuration.getString("general.gliserver_url", true);
@@ -1045,12 +1225,19 @@
 		//new way of detection of ImageMagick
 		InputStreamReader isr = new InputStreamReader(image_magick_process.getInputStream());
+
 	        BufferedReader br = new BufferedReader(isr);
 	        // Capture the standard output stream and seach for two particular occurances: Version and ImageMagick.
-	        String line = br.readLine().toLowerCase();
-		if (line.indexOf("version") != -1 || line.indexOf("imagemagick") != -1) {
+
+	        String line = br.readLine();
+		if (line == null) {
+		    return false;
+		}
+	        String lc_line = line.toLowerCase();
+		if (lc_line.indexOf("version") != -1 || lc_line.indexOf("imagemagick") != -1) {
 			return true;
 		} else {
 		        return false;
 		}
+
 		//return (image_magick_process.exitValue() == 0);
 	    }
Index: /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererApplet.java
===================================================================
--- /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererApplet.java	(revision 18362)
+++ /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererApplet.java	(revision 18363)
@@ -87,5 +87,6 @@
 	// Ensure platform specific LAF
 	try {
-	    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+	    //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+	    UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
 	}
 	catch (Exception exception) {
@@ -115,5 +116,14 @@
 	Gatherer.isApplet = true;
 	String library_url_string = fullLibraryURL(getParameter("gwcgi"));
-	String gliserver_url_string = library_url_string.substring(0, library_url_string.lastIndexOf('/') + 1) + "gliserver.pl";
+
+	String gs3 = getParameter("gsdl3");
+	boolean isGS3 = (gs3 == null || !gs3.equals("true")) ? false : true;
+
+	String gliserver_url_string;
+	if(!isGS3) {
+	    gliserver_url_string = library_url_string.substring(0, library_url_string.lastIndexOf('/') + 1) + "gliserver.pl";
+	} else {
+	    gliserver_url_string = library_url_string + "/cgi-bin/gliserver.pl";
+	}
 
         // String debug_param = getParameter("debug");
@@ -122,10 +132,24 @@
         // }
 
-	String[] args = { "-use_remote_greenstone",
-			  "-gliserver_url", gliserver_url_string,
-			  "-library_url", library_url_string,
-			  // "-debug",
-	                };
-
+	String[] args;
+	if(!isGS3) {
+	    String[] gs2_args = { 
+		"-use_remote_greenstone",
+		"-gliserver_url", gliserver_url_string,
+		"-library_url", library_url_string,
+		// "-debug",
+	    };
+	    args = gs2_args;
+	} else { // >= GS3
+	    String[] gs3_args = {
+		"-use_remote_greenstone",
+		"-gliserver_url", gliserver_url_string,
+		"-library_url", library_url_string,
+		"-gsdl3",
+		//"-debug",
+	    };
+	    args = gs3_args;
+	}
+	
 	File collect_directory = new File(Gatherer.getCollectDirectoryPath());
 	if (!collect_directory.exists()) {
@@ -178,4 +202,5 @@
 	System.err.println("Destroy called");
 	gatherer.exit();
+	gatherer = null;
 	System.err.println("Done gatherer exit.");
     }
@@ -189,5 +214,5 @@
 
     /** 
-     * Method which unzips a given metadata resoure.
+     * Method which unzips a given metadata resource.
      * @param jar_zip_fname The name of the jar file as a <strong>String</strong>.
      * @param dst_dir The destination directory for unzipping, also as a <strong>String</strong>.
Index: /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererApplet4gs3.java
===================================================================
--- /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererApplet4gs3.java	(revision 18362)
+++ /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererApplet4gs3.java	(revision 18363)
@@ -117,5 +117,5 @@
 	Gatherer.isApplet = true;
 	String library_url_string = fullLibraryURL(getParameter("gwcgi"));
-	String gliserver_url_string = library_url_string + "/cgi-bin/gliserver4gs3.pl";
+	String gliserver_url_string = library_url_string + "/cgi-bin/gliserver.pl";
 	String[] args = { "-use_remote_greenstone",
 			  "-gliserver_url", gliserver_url_string,
@@ -174,5 +174,6 @@
 	System.err.println("Destroy called");
 	gatherer.exit();
-	gatherer = null;
+	// bug that causes browser (Firefox to freeze) when trying to reload the applet
+	// gatherer = null;
 	System.err.println("Done gatherer exit.");
     }
Index: /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererProg.java
===================================================================
--- /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererProg.java	(revision 18362)
+++ /gli/branches/rtl-gli/src/org/greenstone/gatherer/GathererProg.java	(revision 18363)
@@ -55,5 +55,6 @@
 	// Ensure platform specific LAF
 	try {
-	    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+	    // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+	    UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
 	}
 	catch (Exception exception) {
Index: /gli/branches/rtl-gli/src/org/greenstone/gatherer/GetOpt.java
===================================================================
--- /gli/branches/rtl-gli/src/org/greenstone/gatherer/GetOpt.java	(revision 18362)
+++ /gli/branches/rtl-gli/src/org/greenstone/gatherer/GetOpt.java	(revision 18363)
@@ -55,8 +55,12 @@
     public String metadata_path = null;
 
+    protected FedoraInfo fedora_info = null;
+    
     public GetOpt(String[] args)
     {
 	// Default dictionary. Only used for starting error messages.
 	Dictionary dictionary = new Dictionary(null, null); 
+
+	fedora_info = new FedoraInfo();
 
 	// Parse arguments
@@ -142,6 +146,6 @@
 			use_remote_greenstone = true;
 			//Use a remote Greenstone
-		
-		    }else if (argument_name.equals(StaticStrings.GSDL3_ARGUMENT)){
+		    }
+		    else if (argument_name.equals(StaticStrings.GSDL3_ARGUMENT)){
 			//Use a remote Greenstone3
 			run_gsdl3=true;
@@ -149,4 +153,8 @@
 		    else if (argument_name.equals(StaticStrings.NEW_METADATASET)) {
 			new_set = true;
+		    }
+		    else if(argument_name.equals(StaticStrings.FEDORA_MODE)) {
+			// Running FLI remotely
+			fedora_info.setActive(true);
 		    }
 		}
@@ -243,4 +251,68 @@
 			}
 		    }
+
+		    // Fedora home - when running Fedora locally
+		    if(argument_name.equals(StaticStrings.FEDORA_HOME)) {
+			if(argument_value.endsWith(File.separator)) {
+			    fedora_info.setHome(argument_value);
+			}
+			else {
+			    fedora_info.setHome(argument_value + File.separator);
+			}
+		    }
+
+		    if(argument_name.equals(StaticStrings.FEDORA_VERSION)) {
+			fedora_info.setVersion(argument_value);
+		    }
+		    
+		    // Fedora hostname
+		    if(argument_name.equals(StaticStrings.FEDORA_HOSTNAME)) {
+			if(argument_value.endsWith(File.separator)) {
+			    fedora_info.setHostname(argument_value);
+			}
+			else {
+			    fedora_info.setHostname(argument_value + File.separator);
+			}
+		    }
+		    // Fedora port
+		    if(argument_name.equals(StaticStrings.FEDORA_PORT)) {
+			if(argument_value.endsWith(File.separator)) {
+			    fedora_info.setPort(argument_value);
+			}
+			else {
+			    fedora_info.setPort(argument_value + File.separator);
+			}
+		    }
+		    // Fedora username
+		    if(argument_name.equals(StaticStrings.FEDORA_USERNAME)) {
+			if(argument_value.endsWith(File.separator)) {
+			    fedora_info.setUsername(argument_value);
+			}
+			else {
+			    fedora_info.setUsername(argument_value + File.separator);
+			}
+		    }
+		    // Fedora password
+		    if(argument_name.equals(StaticStrings.FEDORA_PASSWORD)) {
+			if(argument_value.endsWith(File.separator)) {
+			    fedora_info.setPassword(argument_value);
+			}
+			else {
+			    fedora_info.setPassword(argument_value + File.separator);
+			}
+		    }
+		    // Fedora protocol, e.g. http or https
+		    if(argument_name.equals(StaticStrings.FEDORA_PROTOCOL)) {
+			if(argument_value.endsWith(File.separator)) {
+			    fedora_info.setProtocol(argument_value);
+			}
+			else {
+			    fedora_info.setProtocol(argument_value + File.separator);
+			}
+		    }
+
+
+
+
                   
 		}
