Index: /gli/trunk/src/org/greenstone/gatherer/Gatherer.java
===================================================================
--- /gli/trunk/src/org/greenstone/gatherer/Gatherer.java	(revision 19543)
+++ /gli/trunk/src/org/greenstone/gatherer/Gatherer.java	(revision 19544)
@@ -367,6 +367,7 @@
 
 	    // Check that we now know the Greenstone library URL, since we need this for previewing collections
+	    // It is not necessary if an independent GSI was launched and the user hasn't pressed Enter Library yet
 	    DebugStream.println("Configuration.library_url = " + Configuration.library_url);
-	    if (Configuration.library_url == null) {
+	    if (Configuration.library_url == null && !LocalLibraryServer.isURLPending()) {
 		missingEXEC(); 
 	    }
Index: /gli/trunk/src/org/greenstone/gatherer/greenstone/LocalLibraryServer.java
===================================================================
--- /gli/trunk/src/org/greenstone/gatherer/greenstone/LocalLibraryServer.java	(revision 19543)
+++ /gli/trunk/src/org/greenstone/gatherer/greenstone/LocalLibraryServer.java	(revision 19544)
@@ -140,7 +140,15 @@
     static public boolean isRunning()
     {
-	if (!running) return false;
+	if (!running) return false; // if the url is pending, then running would also be false (server not started up yet)
+
 	llssite_cfg_file.load(true);
-	if (llssite_cfg_file.getURL() == null)  return false;
+	String url = llssite_cfg_file.getURL();
+	if (url == null) return false;
+	
+	// Called by Gatherer to check whether we need to stop the server.
+	// if the url is pending, then the GSI hasn't started the server up yet
+	// Already covered in !running
+	//if (url.equals(LLSSiteConfig.URL_PENDING)) return false;
+
 	return true;
     }
@@ -184,5 +192,15 @@
 
 	llssite_cfg_file = new LLSSiteConfig(local_library_server_file);
-	
+		
+	// If the user launched the GSI independent of GLI, but user has not pressed
+	// Enter Library yet, then we will obtain the previewURL later.
+	if(LocalLibraryServer.isURLPending()) {
+	    // running is still false when the URL is pending because only GSI is running, not the server
+	    return;
+	} else if(llssite_cfg_file.isIndependentGSI()) {
+	    // there is a url, it's not pending, and it is llssite.cfg: meaning GSI has started up
+	    return;	    
+	}
+
 	// Spawn local library server process
 	String local_library_server_command = local_library_server_file.getAbsolutePath() + getExtraLaunchArguments(llssite_cfg_file);
@@ -215,5 +233,5 @@
 	// Wait until program has started
 	try {
-	    testServerRunning(); // will set running = true when the server is up and running successfully
+	    testServerRunning(); // will set running = true when the server is up and running successfully	    
 	} catch (IOException bad_url_connection) {
 	    try {
@@ -236,5 +254,11 @@
     static public void stop()
     {
-	if (running == false) {
+	if (!running) {
+	    // also the case if the URL is pending in an independently launched GSI
+	    return;
+	}
+
+	// don't (can't) shutdown the GSI/server if it was launched independent of GLI
+	if(llssite_cfg_file.isIndependentGSI()) {
 	    return;
 	}
@@ -255,5 +279,6 @@
 	llssite_cfg_file.load(false);
 	int attempt_count = 0;
-	while (llssite_cfg_file.getURL() != null) {
+	String url = llssite_cfg_file.getURL();
+	while (url != null && !url.equals(LLSSiteConfig.URL_PENDING)) { // if pending, the server is already stopped (not running)
 	    new OneSecondWait();  // Wait one second (give or take)
 	    llssite_cfg_file.load(false);
@@ -269,4 +294,6 @@
 		attempt_count = 0;
 	    }
+	    // read the url again to see if it's updated
+	    url = llssite_cfg_file.getURL();
 	}
 
@@ -275,5 +302,6 @@
 
 	// If the local server is still running then our changed values will get overwritten.
-	if (llssite_cfg_file.getURL() != null) {
+	url = llssite_cfg_file.getURL();
+	if (url != null && !url.equals(LLSSiteConfig.URL_PENDING)) {
 	    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Server.QuitManual"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
 	}
@@ -346,8 +374,43 @@
     }
 
+    /** Returns true if we're waiting on the user to click on Enter Library button
+     * in an independently launched GSI (one not launched by GLI). */
+    static public boolean isURLPending() {
+	/*if(Configuration.library_url != null) {
+	    System.err.println("**** Configuration.library_url: " + Configuration.library_url );
+	    return false; // don't need to do anything as we already have the url
+	    }*/
+
+	llssite_cfg_file.load(true); // don't force reload, load only if modified
+
+	String url = llssite_cfg_file.getURL();
+
+	if(url != null) {
+	    if(url.equals(LLSSiteConfig.URL_PENDING)) {
+		running = false; // imagine if they restarted an external GSI
+		return true; 
+	    } else {
+		// a valid URL at last
+		try {
+		    Configuration.library_url = new URL(url);
+		    running = true;
+		}
+		catch (MalformedURLException exception) {
+		    exception.printStackTrace();
+		    DebugStream.printStackTrace(exception);
+		}
+		return false;
+	    }
+	}
+
+	// If either the URL is null--which means no independent GSI (Greenstone server interface
+	// app) was launched--or if the 'URL' doesn't say it's pending, then we're not waiting
+	return false;
+    }
+
     static public void checkServerRunning() {
-	if (!running) return; // don't worry about it if its not supposed to be running 
+	if (!running) return; // don't worry about it if it's not supposed to be running 
 	llssite_cfg_file.load(true); // don't force reload, load only if modified
-
+	
 	String url = llssite_cfg_file.getURL();
 	if(url != null) {
@@ -357,9 +420,19 @@
 	    catch (MalformedURLException exception) {
 		DebugStream.printStackTrace(exception);
+		exception.printStackTrace();
 	    }
 	} else {
 	    // need to restart the server again
-	    llssite_cfg_file.set();
-
+ 
+	    // if we were running an independently launched GSI before, but the GSI has been
+	    // exited, it would need to be relaunched, but from within GLI (dependent) this time.
+	    if(llssite_cfg_file.isIndependentGSI()) {
+		// first save the current configFile (llssite.cfg), then set to use glisite.cfg
+		llssite_cfg_file.save();
+		llssite_cfg_file.relaunchAsDependentGSI(local_library_server_file);
+	    } else {
+		// We were using glisite.cfg before, don't need to swap config files
+		llssite_cfg_file.set();
+	    }
 	    // Spawn local library server process
 	    String local_library_server_command = local_library_server_file.getAbsolutePath() + getExtraLaunchArguments(llssite_cfg_file);
@@ -391,5 +464,8 @@
 
     static public class LLSSiteConfig
-	extends LinkedHashMap {
+	extends LinkedHashMap 
+    {
+	private File configFile;
+
 	private File llssite_cfg;
 	private File glisite_cfg;
@@ -414,4 +490,6 @@
 	static final private String URL = "url";
 
+	static final public String URL_PENDING = "URL_pending";
+
 	public LLSSiteConfig(File server_exe) {
 	    debug("New LLSSiteConfig for: " + server_exe.getAbsolutePath());
@@ -420,10 +498,29 @@
 	    glisite_cfg = new File(server_exe.getParentFile(), GLISITE_CFG);
 
-	    File configFile = null;
+	    configFile = null;
+
+	    autoenter_initial = null;
+	    start_browser_initial = null;
+	    
+	    // first test if server was started independently of GLI
+	    // if so, the config file we'd be using would be llssite.cfg
+	    if(!usingLLS_configFile()) { // if we were using llssite_cfg, this would have loaded it in
+		// else we try using the glisite configfile
+		useGLISiteCfg(server_exe);
+	    }
+
+	    if(configFile != null && configFile.exists()) {
+		System.err.println("Using configfile: " + configFile);
+		lastModified = configFile.lastModified();
+	    }
+	}
+
+	/** Tries to get a glisite.cfg file and then loads it, setting it as the configFile */
+	public void useGLISiteCfg(File server_exe) {
 	    if(!glisite_cfg.exists()) { // create it from the templates or the llssite.cfg file
-
+		
 		File llssite_cfg_in = new File(server_exe.getParentFile(), LLSSITE_CFG+".in");
 		File glisite_cfg_in = new File(server_exe.getParentFile(), GLISITE_CFG+".in");
-
+		
 		// need to generate glisite_cfg from glisite_cfg_in, llssite_cfg or llssite.cfg.in
 		if(glisite_cfg_in.exists()) {
@@ -441,12 +538,136 @@
 		}
 	    }
-
+	    // use the config file now
 	    if(glisite_cfg.exists()) {
 		configFile = glisite_cfg;
+		load(false); // force reload
 	    } 
-
-	    autoenter_initial = null;
-	    start_browser_initial = null;
-	    if(configFile != null) {
+	}
+
+	/** Tests whether the server interface is up, running independently of GLI
+	 * If so, we don't need to launch the server interface.
+	 * The server interface may not have started up the server itself though
+	 * (in which case the server URL would be URL_PENDING).
+	 * This method returns true if the server interface has already started
+	 * and, if so, it would have loaded in the llssite_cfg configFile.
+	 */
+	private boolean usingLLS_configFile() {
+	    if(!llssite_cfg.exists()) {
+		return false;
+	    }
+
+	    // check if the configfile contains the URL line
+	    configFile = llssite_cfg;
+	    load(false); // force load
+
+	    if(getURL() == null) {
+		configFile = null;
+		clear(); // we're not using llssite_cfg, so clear the values we just read
+		return false;
+	    }
+
+	    //System.err.println("***** we're using llssite_configfile, url:" + getURL());
+	    return true;
+	}
+	
+	/** @return true if GSI was started up independently and outside of GLI. 
+	 * In such a case, GLI would be using llssite_cfg. */
+	public boolean isIndependentGSI() {
+	    return (configFile == llssite_cfg);
+	}
+
+	/** Call this when an independently launched GSI server has been stopped
+	 * (one using llssite_cfg) and GLI needs to next launch another server.
+	 * In such a case, since GLI itself is relaunching the GSI, we use glisite_cfg.
+	*/
+	public void relaunchAsDependentGSI(File server_exe) {
+		useGLISiteCfg(server_exe);
+	}
+
+	public boolean exists() {
+	    return configFile.exists();
+	}
+
+	public String getLocalHostURL() {
+	    StringBuffer url = new StringBuffer(LOCAL_HOST);
+	    url.append(COLON);
+	    url.append((String)get(PORTNUMBER));
+	    String enterlib = (String)get(ENTERLIB);
+	    if(enterlib == null || enterlib.length() == 0) {
+		// Use the default /gsdl and hope for the best.
+		url.append(SEPARATOR);
+		url.append(GSDL);
+	    }
+	    else {
+		if(!enterlib.startsWith(SEPARATOR)) {
+		    url.append(SEPARATOR);
+		}
+		url.append(enterlib);
+	    }
+	    enterlib = null;
+	    debug("Found Local Library Address: " + url.toString());
+	    return url.toString();
+	}
+
+	/** @return the cmd-line parameter for the configfile used to launch
+	 * the server through GLI: --config <glisite.cfg/llssite.cfg file path>. */
+	public String getSiteConfigFilename() {
+	    return SPECIFIC_CONFIG + configFile.getAbsolutePath();
+	}
+
+	public String getURL() {
+	    // URL is made from url and portnumber
+	    String url = (String) get(URL);
+
+	    // server interface is already up, independent of GLI
+	    // but it has not started the server (hence URL is pending) 
+	    if(url != null && url.equals(URL_PENDING)) {
+		return url;
+	    }
+
+	    if(!Utility.isWindows()) {
+		return url;
+	    }
+
+	    if(url != null) {
+		StringBuffer temp = new StringBuffer(url);
+		temp.append(COLON);
+		temp.append((String)get(PORTNUMBER));
+		String enterlib = (String)get(ENTERLIB);
+		if(enterlib == null || enterlib.length() == 0) {
+		    // Use the default /greenstone prefix and hope for the best.
+		    temp.append(SEPARATOR);
+		    temp.append(GSDL);
+		}
+		else {
+		    if(!enterlib.startsWith(SEPARATOR)) {
+			temp.append(SEPARATOR);
+		    }
+		    temp.append(enterlib);
+		}
+		enterlib = null;
+		url = temp.toString();
+	    }
+	    debug("Found Local Library Address: " + url);
+	    return url;
+	}
+
+	public boolean isModified() {
+	    return (lastModified != configFile.lastModified());
+	}
+
+	public void load(boolean reloadOnlyIfModified) {	    
+
+	    if(configFile == null) {
+		debug(configFile.getAbsolutePath() + " cannot be found!");
+	    }
+
+	    if(isModified()) {
+		lastModified = configFile.lastModified();
+	    } else if(reloadOnlyIfModified) {
+		return; // asked to reload only if modified. Don't reload since not modified
+	    }
+
+	    if(configFile.exists()) {
 		debug("Load: " + configFile.getAbsolutePath());
 		clear();
@@ -473,109 +694,6 @@
 		}
 	    }
-
-	    if(glisite_cfg.exists()) {
-		lastModified = glisite_cfg.lastModified();
-	    }
-	}
-	
-	public boolean exists() {
-	    return llssite_cfg.exists();
-	}
-
-	public String getLocalHostURL() {
-	    StringBuffer url = new StringBuffer(LOCAL_HOST);
-	    url.append(COLON);
-	    url.append((String)get(PORTNUMBER));
-	    String enterlib = (String)get(ENTERLIB);
-	    if(enterlib == null || enterlib.length() == 0) {
-		// Use the default /gsdl and hope for the best.
-		url.append(SEPARATOR);
-		url.append(GSDL);
-	    }
 	    else {
-		if(!enterlib.startsWith(SEPARATOR)) {
-		    url.append(SEPARATOR);
-		}
-		url.append(enterlib);
-	    }
-	    enterlib = null;
-	    debug("Found Local Library Address: " + url.toString());
-	    return url.toString();
-	}
-
-	public String getSiteConfigFilename() {
-	    return SPECIFIC_CONFIG + glisite_cfg.getAbsolutePath();
-	}
-
-	public String getURL() {
-	    // URL is made from url and portnumber
-	    String url = (String) get(URL);
-
-	    if(!Utility.isWindows()) {
-		return url;
-	    }
-
-	    if(url != null) {
-		StringBuffer temp = new StringBuffer(url);
-		temp.append(COLON);
-		temp.append((String)get(PORTNUMBER));
-		String enterlib = (String)get(ENTERLIB);
-		if(enterlib == null || enterlib.length() == 0) {
-		    // Use the default /gsdl and hope for the best.
-		    temp.append(SEPARATOR);
-		    temp.append(GSDL);
-		}
-		else {
-		    if(!enterlib.startsWith(SEPARATOR)) {
-			temp.append(SEPARATOR);
-		    }
-		    temp.append(enterlib);
-		}
-		enterlib = null;
-		url = temp.toString();
-	    }
-	    debug("Found Local Library Address: " + url);
-	    return url;
-	}
-
-	public boolean isModified() {
-	    return (lastModified != glisite_cfg.lastModified());
-	}
-
-	public void load(boolean reloadOnlyIfModified) {	    
-
-	    if(isModified()) {
-		lastModified = glisite_cfg.lastModified();
-	    } else if(reloadOnlyIfModified) {
-		return; // asked to reload only if modified. Don't reload since not modified
-	    }
-
-	    if(glisite_cfg.exists()) {
-		debug("Load: " + glisite_cfg.getAbsolutePath());
-		clear();
-		try {
-		    BufferedReader in = new BufferedReader(new FileReader(glisite_cfg));
-		    String line = null;
-		    while((line = in.readLine()) != null) {
-			String key = null;
-			String value = null;
-			int index = -1;
-			if((index = line.indexOf("=")) != -1 && line.length() >= index + 1) {
-			    key = line.substring(0, index);
-			    value = line.substring(index + 1);
-			}
-			else {
-			    key = line;
-			}
-			put(key, value);
-		    }
-		    in.close();
-		}
-		catch (Exception error) {
-		    error.printStackTrace();
-		}
-	    }
-	    else {
-		debug("No glisite.cfg file can be found!");
+		debug(configFile.getAbsolutePath() + " cannot be found!");
 	    }
 	}
@@ -583,7 +701,7 @@
 	/** Restore the autoenter value to its initial value, and remove url if present. */
 	public void restore() {
-	    if(glisite_cfg != null) {
+	    if(configFile != null) {
 		// Delete the file
-		glisite_cfg.delete();
+		configFile.delete();
 	    }
 	    else {
@@ -617,8 +735,8 @@
 	private void save() {
 	    //debug("Save: " + llssite_cfg.getAbsolutePath());
-	    debug("Save: " + glisite_cfg.getAbsolutePath());
+	    debug("Save: " + configFile.getAbsolutePath());
 	    try {
 		//BufferedWriter out = new BufferedWriter(new FileWriter(llssite_cfg, false));
-		BufferedWriter out = new BufferedWriter(new FileWriter(glisite_cfg, false));
+		BufferedWriter out = new BufferedWriter(new FileWriter(configFile, false));
 		for(Iterator keys = keySet().iterator(); keys.hasNext(); ) {
 		    String key = (String) keys.next();
@@ -627,5 +745,16 @@
 		    if(value != null) {
 			out.write('=');
-			out.write(value, 0, value.length());
+			
+			// if the server is using llssite.cfg, don't overwrite its default
+			// autoenter and startbrowser values
+			if(configFile == llssite_cfg && (key == AUTOENTER || key == STARTBROWSER)) {
+			    if(key == AUTOENTER) {
+				out.write(autoenter_initial, 0, autoenter_initial.length());
+			    } else { // STARTBROWSER
+				out.write(start_browser_initial, 0, start_browser_initial.length());
+			    }
+			 } else {
+			     out.write(value, 0, value.length());
+			}
 		    }
 		    out.newLine();
Index: /gli/trunk/src/org/greenstone/gatherer/gui/PreviewButton.java
===================================================================
--- /gli/trunk/src/org/greenstone/gatherer/gui/PreviewButton.java	(revision 19543)
+++ /gli/trunk/src/org/greenstone/gatherer/gui/PreviewButton.java	(revision 19544)
@@ -35,4 +35,5 @@
 import javax.swing.*;
 import org.greenstone.gatherer.Configuration;
+import org.greenstone.gatherer.Dictionary;
 import org.greenstone.gatherer.Gatherer;
 import org.greenstone.gatherer.collection.CollectionManager;
@@ -134,5 +135,15 @@
 	    Gatherer.c_man.saveCollection();
 	    
-	    configureHomeURL();
+	    if(LocalLibraryServer.isURLPending()) {
+		// Remind the user to press Enter Library, and return from this method
+		JOptionPane.showMessageDialog(Gatherer.g_man,
+					      Dictionary.get("General.LLS_Not_Started"), 
+					      Dictionary.get("General.LLS_Not_Started_Title"),
+					      JOptionPane.ERROR_MESSAGE);
+		return;
+		
+	    } else {
+		configureHomeURL();
+	    }
 	    
 	    if (Gatherer.GS3) {
