Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryServlet.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryServlet.java	(revision 24220)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryServlet.java	(revision 24221)
@@ -588,5 +588,4 @@
 		}
 		
-		//GSXML.printXMLNode(xml_message);
 		Node xml_result = this.recept.process(xml_message);
 		encodeURLs (xml_result, response);
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java	(revision 24220)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java	(revision 24221)
@@ -1,20 +1,20 @@
 /*
- *    Collection.java
- *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
- *
- *    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.
- */
+*    Collection.java
+*    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+*
+*    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.gsdl3.collection;
 
@@ -49,587 +49,597 @@
 
 /**
- * Represents a collection in Greenstone. A collection is an extension of
- * a ServiceCluster - it has local data that the services use.
- *
- * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
- * @see ModuleInterface
- */
+* Represents a collection in Greenstone. A collection is an extension of
+* a ServiceCluster - it has local data that the services use.
+*
+* @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
+* @see ModuleInterface
+*/
 public class Collection 
-    extends ServiceCluster {
-
-    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.Collection.class.getName());
-
-    /** is this collection being tidied */
-    protected boolean useBook = false;
-    /** is this collection public or private */
-    protected boolean is_public = true;
-
-    /** does this collection provide the OAI service */
-    protected boolean has_oai = true;
-    /** time when this collection was built */
-    protected long lastmodified = 0;
-    /** earliestDatestamp of this collection. Necessary for OAI */
-    protected long earliestDatestamp = 0;
-
-
-    /** An element containing the serviceRackList element of buildConfig.xml, used to determine whether it contains
-     *  the OAIPMH serviceRack 
-     */
-    //protected Element service_rack_list = null;
-    
-    protected XMLTransformer transformer = null;
-    /** same as setClusterName */
-    public void setCollectionName(String name) {
-	setClusterName(name);
-    }
-
-    public Collection() {
-	super();
-	this.description = this.doc.createElement(GSXML.COLLECTION_ELEM);
+extends ServiceCluster {
+
+	static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.Collection.class.getName());
+
+	/** is this collection being tidied */
+	protected boolean useBook = false;
+	/** is this collection public or private */
+	protected boolean is_public = true;
+
+	/** does this collection provide the OAI service */
+	protected boolean has_oai = true;
+	/** time when this collection was built */
+	protected long lastmodified = 0;
+	/** earliestDatestamp of this collection. Necessary for OAI */
+	protected long earliestDatestamp = 0;
+
+
+	/** An element containing the serviceRackList element of buildConfig.xml, used to determine whether it contains
+	*  the OAIPMH serviceRack 
+	*/
+	//protected Element service_rack_list = null;
 	
-    }
+	protected XMLTransformer transformer = null;
+	/** same as setClusterName */
+	public void setCollectionName(String name) {
+		setClusterName(name);
+	}
+
+	public Collection() {
+		super();
+		this.description = this.doc.createElement(GSXML.COLLECTION_ELEM);
+		
+	}
 	
-    /**
-     * Configures the collection.
-     *
-     * gsdlHome and collectionName must be set before configure is called.
-     *
-     * the file buildcfg.xml is located in gsdlHome/collect/collectionName
-     * collection metadata is obtained, and services loaded.
-     *
-     * @return true/false on success/fail
-     */
-    public boolean configure() {
+	/**
+	* Configures the collection.
+	*
+	* gsdlHome and collectionName must be set before configure is called.
+	*
+	* the file buildcfg.xml is located in gsdlHome/collect/collectionName
+	* collection metadata is obtained, and services loaded.
+	*
+	* @return true/false on success/fail
+	*/
+	public boolean configure() {
+		
+		if (this.site_home == null || this.cluster_name== null) {
+			logger.error("Collection: site_home and collection_name must be set before configure called!");
+			return false;
+		}
+		
+		Element coll_config_xml = loadCollConfigFile();
+		Element build_config_xml = loadBuildConfigFile();
+		
+		if (coll_config_xml==null||build_config_xml==null) {
+			return false;
+		}
+		
+		// get the collection type attribute
+		Element search = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SEARCH_ELEM);	
+		if(search != null) {
+			col_type = search.getAttribute(GSXML.TYPE_ATT);
+		}
+		
+		Element browse = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.INFODB_ELEM);	
+		if(browse != null) {
+			db_type = browse.getAttribute(GSXML.TYPE_ATT);
+		}
+		else
+		{
+			db_type = "gdbm"; //The default
+		}
+		System.err.println("DB_TYPE = "  + db_type);
+		
+		// process the metadata and display items
+		findAndLoadInfo(coll_config_xml, build_config_xml);
+		
+		// now do the services
+		configureServiceRacks(coll_config_xml, build_config_xml);
+
+		return true;
+		
+	}
+
+	public boolean useBook() {
+		return useBook;
+	}
 	
-	if (this.site_home == null || this.cluster_name== null) {
-	    logger.error("Collection: site_home and collection_name must be set before configure called!");
-	    return false;
+	public boolean isPublic() {
+		return is_public;
+	}
+	// Not used anymore by the OAIReceptionist to find out the earliest datestamp 
+	// amongst all oai collections in the repository. May be useful generally.
+	public long getLastmodified() {
+		return lastmodified;
+	}
+	//used by the OAIReceptionist to find out the earliest datestamp amongst all oai collections in the repository
+	public long getEarliestDatestamp() {
+		return earliestDatestamp;
+	}
+
+	/** whether the service_map in ServiceCluster.java contains the service 'OAIPMH'
+	*  11/06/2007 xiao
+	*/
+	public boolean hasOAI() {
+		return has_oai;
+	}
+	/** 
+	* load in the collection config file into a DOM Element 
+	*/    
+	protected Element loadCollConfigFile() {
+
+		File coll_config_file = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name));
+		
+		if (!coll_config_file.exists()) {
+			logger.error("Collection: couldn't configure collection: "+this.cluster_name+", "+coll_config_file+" does not exist");
+			return null;
+		}
+		// get the xml for both files
+		Document coll_config_doc = this.converter.getDOM(coll_config_file, CONFIG_ENCODING);
+		Element coll_config_elem = null;
+		if (coll_config_doc != null) {
+			coll_config_elem = coll_config_doc.getDocumentElement();
+		}
+		return coll_config_elem;
+
 	}
 	
-	Element coll_config_xml = loadCollConfigFile();
-	Element build_config_xml = loadBuildConfigFile();
-	
-	if (coll_config_xml==null||build_config_xml==null) {
-	    return false;
-	}
-	
-	// get the collection type attribute
-	Element search = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SEARCH_ELEM);	
-	if(search!=null) {
-	  col_type = search.getAttribute(GSXML.TYPE_ATT);
-	}
-	
-	// process the metadata and display items
-	findAndLoadInfo(coll_config_xml, build_config_xml);
-	
-	// now do the services
-	configureServiceRacks(coll_config_xml, build_config_xml);
-
-	return true;
-	
-    }
-
-    public boolean useBook() {
-    	return useBook;
-    }
-    
-    public boolean isPublic() {
-	return is_public;
-    }
-    // Not used anymore by the OAIReceptionist to find out the earliest datestamp 
-    // amongst all oai collections in the repository. May be useful generally.
-    public long getLastmodified() {
-      return lastmodified;
-    }
-    //used by the OAIReceptionist to find out the earliest datestamp amongst all oai collections in the repository
-    public long getEarliestDatestamp() {
-	return earliestDatestamp;
-    }
-
-    /** whether the service_map in ServiceCluster.java contains the service 'OAIPMH'
-     *  11/06/2007 xiao
-     */
-    public boolean hasOAI() {
-      return has_oai;
-    }
-    /** 
-     * load in the collection config file into a DOM Element 
-     */    
-    protected Element loadCollConfigFile() {
-
-	File coll_config_file = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name));
-	
-	if (!coll_config_file.exists()) {
-	    logger.error("Collection: couldn't configure collection: "+this.cluster_name+", "+coll_config_file+" does not exist");
-	    return null;
-	}
-	// get the xml for both files
-	Document coll_config_doc = this.converter.getDOM(coll_config_file, CONFIG_ENCODING);
-	Element coll_config_elem = null;
-	if (coll_config_doc != null) {
-	    coll_config_elem = coll_config_doc.getDocumentElement();
-	}
-	return coll_config_elem;
-
-    }
-    
-    /** 
-     * load in the collection build config file into a DOM Element 
-     */        
-    protected Element loadBuildConfigFile() {
-	
-	File build_config_file = new File(GSFile.collectionBuildConfigFile(this.site_home, this.cluster_name));
-	if (!build_config_file.exists()) {
-	    logger.error("Collection: couldn't configure collection: "+this.cluster_name+", "+build_config_file+" does not exist");
-	    return null;
-	}
-	Document build_config_doc = this.converter.getDOM(build_config_file, CONFIG_ENCODING);
-	Element build_config_elem = null;
-	if (build_config_doc != null) {
-	    build_config_elem = build_config_doc.getDocumentElement();
-	}
-
-	lastmodified = build_config_file.lastModified();
-  
-	return build_config_elem;
-    }
-
-    /**
-     * find the metadata and display elems from the two config files and add it to the appropriate lists
-     */
-    protected boolean findAndLoadInfo(Element coll_config_xml, 
-				      Element build_config_xml){
-		      
-      // metadata
-      Element meta_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-      addMetadata(meta_list);
-      meta_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-      addMetadata(meta_list);
-      
-      meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
-      GSXML.addMetadata(this.doc, meta_list, "httpPath", this.site_http_address+"/collect/"+this.cluster_name);
-      addMetadata(meta_list);
-      
-      // display stuff
-      Element display_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER);
-      if (display_list != null) {
-        resolveMacros(display_list);
-        addDisplayItems(display_list);
-      }
-      
-      //check whether the html are tidy or not
-      Element import_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.IMPORT_ELEM);
-      if (import_list != null) {
-        Element plugin_list = (Element)GSXML.getChildByTagName(import_list, GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
-        addPlugins(plugin_list);
-        if (plugin_list != null){
-          Element plugin_elem = (Element)GSXML.getNamedElement(plugin_list, GSXML.PLUGIN_ELEM, GSXML.NAME_ATT, "HTMLPlugin");
-          if (plugin_elem != null) {
-            //get the option
-            Element option_elem = (Element)GSXML.getNamedElement(plugin_elem, GSXML.PARAM_OPTION_ELEM, GSXML.NAME_ATT, "-use_realistic_book");
-            if (option_elem != null) {
-              useBook = true;
-            }
-          }
-        }
-      }
-      meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
-      if (useBook == true)
-        GSXML.addMetadata(this.doc, meta_list, "tidyoption", "tidy");
-      else
-        GSXML.addMetadata(this.doc, meta_list, "tidyoption", "untidy");
-      addMetadata(meta_list);
-      
-      // check whether we are public or not
-      if (meta_list != null) {
-        Element meta_elem = (Element) GSXML.getNamedElement(metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "public");
-        if (meta_elem != null) {
-          String value = GSXML.getValue(meta_elem).toLowerCase().trim();
-          if (value.equals("false")) {
-            is_public = false;
-          }
-        }
-      }
-      return true;
-
-    }
-
-  protected boolean configureServiceRacks(Element coll_config_xml, 
-					  Element build_config_xml){
-    clearServices();
-    Element service_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
-    configureServiceRackList(service_list, coll_config_xml);
-        
-    // collection Config may also contain manually added service racks
-    service_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
-    if (service_list != null) {
-      configureServiceRackList(service_list, build_config_xml);
-      
-      // Check for oai
-      Element oai_service_rack = GSXML.getNamedElement(service_list, GSXML.SERVICE_CLASS_ELEM, OAIXML.NAME, OAIXML.OAIPMH);
-      if (oai_service_rack == null) {
-	has_oai = false;
-	logger.info("No oai for collection: " + this.cluster_name);
-	
-      } else {
-	has_oai = true;
-	
-	// extract earliestDatestamp from the buildconfig.xml for OAI
-	Element metadata_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-
-	if(metadata_list != null) {
-	    NodeList children = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM); 
-	           // can't do getChildNodes(), because whitespace, such as newlines, creates Text nodes
-	    for (int i = 0; i < children.getLength(); i++) {
-		Element metadata = (Element)children.item(i);
-		if(metadata.getAttribute(GSXML.NAME_ATT).equals(OAIXML.EARLIEST_DATESTAMP)) {
-		    String earliestDatestampStr = GSXML.getValue(metadata);
-		    if(!earliestDatestampStr.equals("")) {
-			earliestDatestamp = Long.parseLong(earliestDatestampStr);
-		    }
-		    break; // found a metadata element with name=earliestDatestamp in buildconfig
-		}
-	    }
-	}
-	
-	// If at the end of this, there is no value for earliestDatestamp, print out a warning
-	logger.warn("No earliestDatestamp in buildConfig.xml for collection: " + this.cluster_name + ". Defaulting to 0.");
-
-      }
-    } else { // no list of services (no ServiceRackList), so no oai_service_rack either
-	// explicitly set has_oai to false here, since it's initialised to true by default
-	has_oai = false;
-    }
-    return true;
-  }
-  
-  protected boolean resolveMacros(Element display_list) {
-	if (display_list==null) return false;
-	NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
-	if (displaynodes.getLength()>0) { 
-	    String http_site = this.site_http_address;
-	    String http_collection = this.site_http_address +"/collect/"+this.cluster_name;
-	    for(int k=0; k<displaynodes.getLength(); k++) {
-		Element d = (Element) displaynodes.item(k);
-		String text = GSXML.getNodeText(d);
-		text = StringUtils.replace(text, "_httpsite_", http_site);
-		text = StringUtils.replace(text, "_httpcollection_", http_collection);
-		GSXML.setNodeText(d, text);
-	    }
-	}
-	return true;
-    }
-    /** 
-     * do a configure on only part of the collection
-     */
-    protected boolean configureSubset(String subset) {
-
-	// need the coll config files
-	Element coll_config_elem = loadCollConfigFile();
-	Element build_config_elem = loadBuildConfigFile();
-	if (coll_config_elem == null||build_config_elem == null) {
-	    // wont be able to do any of the requests
-	    return false;
-	}    
-	
-	if (subset.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
-	  return configureServiceRacks(coll_config_elem, build_config_elem);
+	/** 
+	* load in the collection build config file into a DOM Element 
+	*/        
+	protected Element loadBuildConfigFile() {
+		
+		File build_config_file = new File(GSFile.collectionBuildConfigFile(this.site_home, this.cluster_name));
+		if (!build_config_file.exists()) {
+			logger.error("Collection: couldn't configure collection: "+this.cluster_name+", "+build_config_file+" does not exist");
+			return null;
+		}
+		Document build_config_doc = this.converter.getDOM(build_config_file, CONFIG_ENCODING);
+		Element build_config_elem = null;
+		if (build_config_doc != null) {
+			build_config_elem = build_config_doc.getDocumentElement();
+		}
+
+		lastmodified = build_config_file.lastModified();
+
+		return build_config_elem;
+	}
+
+	/**
+	* find the metadata and display elems from the two config files and add it to the appropriate lists
+	*/
+	protected boolean findAndLoadInfo(Element coll_config_xml, 
+	Element build_config_xml){
+		
+		// metadata
+		Element meta_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+		addMetadata(meta_list);
+		meta_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+		addMetadata(meta_list);
+		
+		meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
+		GSXML.addMetadata(this.doc, meta_list, "httpPath", this.site_http_address+"/collect/"+this.cluster_name);
+		addMetadata(meta_list);
+		
+		// display stuff
+		Element display_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER);
+		if (display_list != null) {
+			resolveMacros(display_list);
+			addDisplayItems(display_list);
+		}
+		
+		//check whether the html are tidy or not
+		Element import_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.IMPORT_ELEM);
+		if (import_list != null) {
+			Element plugin_list = (Element)GSXML.getChildByTagName(import_list, GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
+			addPlugins(plugin_list);
+			if (plugin_list != null){
+				Element plugin_elem = (Element)GSXML.getNamedElement(plugin_list, GSXML.PLUGIN_ELEM, GSXML.NAME_ATT, "HTMLPlugin");
+				if (plugin_elem != null) {
+					//get the option
+					Element option_elem = (Element)GSXML.getNamedElement(plugin_elem, GSXML.PARAM_OPTION_ELEM, GSXML.NAME_ATT, "-use_realistic_book");
+					if (option_elem != null) {
+						useBook = true;
+					}
+				}
+			}
+		}
+		meta_list = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
+		if (useBook == true)
+		GSXML.addMetadata(this.doc, meta_list, "tidyoption", "tidy");
+		else
+		GSXML.addMetadata(this.doc, meta_list, "tidyoption", "untidy");
+		addMetadata(meta_list);
+		
+		// check whether we are public or not
+		if (meta_list != null) {
+			Element meta_elem = (Element) GSXML.getNamedElement(metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "public");
+			if (meta_elem != null) {
+				String value = GSXML.getValue(meta_elem).toLowerCase().trim();
+				if (value.equals("false")) {
+					is_public = false;
+				}
+			}
+		}
+		return true;
+
+	}
+
+	protected boolean configureServiceRacks(Element coll_config_xml, 
+	Element build_config_xml){
+		clearServices();
+		Element service_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
+		configureServiceRackList(service_list, coll_config_xml);
+		
+		// collection Config may also contain manually added service racks
+		service_list = (Element)GSXML.getChildByTagName(coll_config_xml, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
+		if (service_list != null) {
+			configureServiceRackList(service_list, build_config_xml);
+			
+			// Check for oai
+			Element oai_service_rack = GSXML.getNamedElement(service_list, GSXML.SERVICE_CLASS_ELEM, OAIXML.NAME, OAIXML.OAIPMH);
+			if (oai_service_rack == null) {
+				has_oai = false;
+				logger.info("No oai for collection: " + this.cluster_name);
+				
+			} else {
+				has_oai = true;
+				
+				// extract earliestDatestamp from the buildconfig.xml for OAI
+				Element metadata_list = (Element)GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+
+				if(metadata_list != null) {
+					NodeList children = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM); 
+					// can't do getChildNodes(), because whitespace, such as newlines, creates Text nodes
+					for (int i = 0; i < children.getLength(); i++) {
+						Element metadata = (Element)children.item(i);
+						if(metadata.getAttribute(GSXML.NAME_ATT).equals(OAIXML.EARLIEST_DATESTAMP)) {
+							String earliestDatestampStr = GSXML.getValue(metadata);
+							if(!earliestDatestampStr.equals("")) {
+								earliestDatestamp = Long.parseLong(earliestDatestampStr);
+							}
+							break; // found a metadata element with name=earliestDatestamp in buildconfig
+						}
+					}
+				}
+				
+				// If at the end of this, there is no value for earliestDatestamp, print out a warning
+				logger.warn("No earliestDatestamp in buildConfig.xml for collection: " + this.cluster_name + ". Defaulting to 0.");
+
+			}
+		} else { // no list of services (no ServiceRackList), so no oai_service_rack either
+			// explicitly set has_oai to false here, since it's initialised to true by default
+			has_oai = false;
+		}
+		return true;
+	}
+
+	protected boolean resolveMacros(Element display_list) {
+		if (display_list==null) return false;
+		NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
+		if (displaynodes.getLength()>0) { 
+			String http_site = this.site_http_address;
+			String http_collection = this.site_http_address +"/collect/"+this.cluster_name;
+			for(int k=0; k<displaynodes.getLength(); k++) {
+				Element d = (Element) displaynodes.item(k);
+				String text = GSXML.getNodeText(d);
+				text = StringUtils.replace(text, "_httpsite_", http_site);
+				text = StringUtils.replace(text, "_httpcollection_", http_collection);
+				GSXML.setNodeText(d, text);
+			}
+		}
+		return true;
+	}
+	/** 
+	* do a configure on only part of the collection
+	*/
+	protected boolean configureSubset(String subset) {
+
+		// need the coll config files
+		Element coll_config_elem = loadCollConfigFile();
+		Element build_config_elem = loadBuildConfigFile();
+		if (coll_config_elem == null||build_config_elem == null) {
+			// wont be able to do any of the requests
+			return false;
+		}    
+		
+		if (subset.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
+			return configureServiceRacks(coll_config_elem, build_config_elem);
+		} 
+
+		if (subset.equals(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER) || subset.equals(GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER) || subset.equals(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER)) {
+			return findAndLoadInfo(coll_config_elem, build_config_elem);
+			
+		}
+		
+		logger.error("Collection: cant process system request, configure "+subset);
+		return false;
 	} 
 
-	if (subset.equals(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER) || subset.equals(GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER) || subset.equals(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER)) {
-	    return findAndLoadInfo(coll_config_elem, build_config_elem);
-	    
-	}
-	
-	logger.error("Collection: cant process system request, configure "+subset);
-	return false;
-    } 
-
- /** handles requests made to the ServiceCluster itself 
-     *
-     * @param req - the request Element- <request>
-     * @return the result Element - should be <response>
-     */
-    protected Element processMessage(Element request) {
-
-    Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
-    response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
-    String type = request.getAttribute(GSXML.TYPE_ATT);
-    String lang = request.getAttribute(GSXML.LANG_ATT);
-    response.setAttribute(GSXML.TYPE_ATT, type);
-
-    logger.error("Collection received a message, attempting to process");
-
-    if (type.equals(GSXML.REQUEST_TYPE_FORMAT_STRING)) {
-        logger.error("Received format string request");
-
-        String subaction = request.getAttribute("subaction");
-        logger.error("Subaction is " + subaction);
-
-        String service = request.getAttribute("service");
-        logger.error("Service is " + service);
-
-        String classifier = null;
-        if(service.equals("ClassifierBrowse"))
-        {
-            classifier = request.getAttribute("classifier");
-            logger.error("Classifier is " + classifier);
-        }
-
-        Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM);
-        //String format_string = GSXML.getNodeText(format_element);
-        Element format_statement = (Element) format_element.getFirstChild();
-
-        //logger.error("Format string: " + format_string);
-        logger.error("Config file location = " + GSFile.collectionConfigFile(this.site_home, this.cluster_name));
-
-        // check for version file
-
-        String directory = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)).getParent() + File.separator;
-        logger.error("Directory is " + directory);
-
-        String version_filename = "";
-        if(service.equals("ClassifierBrowse"))
-            version_filename = directory + "browse_"+classifier+"_format_statement_version.txt";
-        else
-            version_filename = directory + "query_format_statement_version.txt";
-
-        File version_file = new File(version_filename);
-        logger.error("Version filename is " + version_filename);
-
-
-        if(subaction.equals("update"))
-        {
-            String version_number = "1";
-            BufferedWriter writer;
-
-            try{
-
-                if(version_file.exists())
-                {
-                    // Read version
-                    BufferedReader reader = new BufferedReader(new FileReader(version_filename));
-                    version_number = reader.readLine();
-                    int aInt = Integer.parseInt(version_number) + 1;
-                    version_number = Integer.toString(aInt);
-                    reader.close();
-                }
-                else{
-                    // Create
-                    version_file.createNewFile();
-                    writer = new BufferedWriter(new FileWriter(version_filename));
-                    writer.write(version_number);
-                    writer.close();
-                }
-
-                // Write version file
-                String format_statement_filename = "";
-
-                if(service.equals("ClassifierBrowse"))
-                    format_statement_filename = directory + "browse_"+classifier+"_format_statement_v" + version_number + ".txt";
-                else
-                    format_statement_filename = directory + "query_format_statement_v" + version_number + ".txt";
-
-                logger.error("Format statement filename is " + format_statement_filename);
-
-                // Write format statement
-                String format_string = this.converter.getString(format_statement); //GSXML.xmlNodeToString(format_statement);
-                writer = new BufferedWriter(new FileWriter(format_statement_filename));
-                writer.write(format_string);
-                writer.close();
-
-                // Update version number
-                writer = new BufferedWriter(new FileWriter(version_filename));
-                writer.write(version_number);
-                writer.close();
-
-            } catch (IOException e) {
-                logger.error("IO Exception "+e);
-            }
-        }
-
-        if(subaction.equals("save"))
-        {
-            logger.error("SAVE format statement");
-
-            try{
-
-                // Convert format string to a document
-                //DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-                //DocumentBuilder builder = factory.newDocumentBuilder();
-                //String input = "<html><head><title></title></head><body>" + format_string + "</body></html>";
-                //String input = format_string.substring(0,format_string.length()-1)+"</xml>";
-                //logger.error(input);
-                //InputSource is = new InputSource( new StringReader( input ) );
-                //logger.error("About to parse format string");
-                //Document format_statement = (Document) builder.parse( is );
-                //logger.error("Done parsing format string");
-
-                // open collectionConfig.xml and read in to w3 Document
-                String collection_config = directory + "collectionConfig.xml";
-                Document config = this.converter.getDOM(new File(collection_config), "UTF-8");
-           
-                //String tag_name = "";
-                int k;
-                int index;
-                Element elem;
-                // Try importing entire tree to this.doc so we can add and remove children at ease
-                //Node current_node = this.doc.importNode(GSXML.getChildByTagName(config, "CollectionConfig"),true);
-                Node current_node = GSXML.getChildByTagName(config, "CollectionConfig");
-                NodeList current_node_list;
-   
-                logger.error("Service is "+service);
-
-                if(service.equals("ClassifierBrowse"))
-                {
-                    //tag_name = "browse";
-                    // if CLX then need to look in <classifier> X then <format>
-                    // default is <browse><format>
-
-                    logger.error("Looking for browse");
-                    current_node = GSXML.getChildByTagName(current_node, "browse");
-
-                    // find CLX
-                    if(classifier != null)
-                    {
-                        logger.error("Classifier is not null");
-                        logger.error("Classifier is "+classifier);
-                        current_node_list = GSXML.getChildrenByTagName(current_node, "classifier");
-                        index = Integer.parseInt(classifier.substring(2)) - 1;
-                        logger.error("classifier index is "+index);
-                        // index should be given by X-1
-                        current_node = current_node_list.item(index);
-                        // what if classifier does not have a format tag?
-                        if(GSXML.getChildByTagName(current_node, "format") == null)
-                        {
-                            logger.error("ERROR: valid classifier but does not have a format child");
-                            // well then create a format tag
-                            Element format_tag = config.createElement("format");
-                            current_node = (Node) current_node.appendChild(format_tag);
-                            //current_node = (Node) format_tag;
-                        }
-                        
-                        else{
-                            current_node = GSXML.getChildByTagName(current_node, "format");
-                        }
-
-                    }
-                    else{
-                        logger.error("Classifier is null");
-                        // To support all classifiers, set classifier to null?  There is the chance here that the format tag does not exist
-                        if(GSXML.getChildByTagName(current_node, "format") == null)
-                        {
-                            logger.error("ERROR: classifier does not have a format child");
-                            // well then create a format tag
-                            Element format_tag = config.createElement("format");
-                            current_node = (Node) current_node.appendChild(format_tag);
-                            //current_node = (Node) format_tag;
-                        }
-                        else
-                            current_node = GSXML.getChildByTagName(current_node, "format");
-                    }
-                }
-                else if(service.equals("AllClassifierBrowse"))
-                {
-                    logger.error("Looking for browse");
-                    current_node = GSXML.getChildByTagName(current_node, "browse");
-                    if(GSXML.getChildByTagName(current_node, "format") == null)
-                    {
-                        logger.error("ERROR AllClassifierBrowse: all classifiers do not have a format child");
-                        // well then create a format tag
-                        Element format_tag = config.createElement("format");
-                        current_node = (Node) current_node.appendChild(format_tag);
-                        //current_node = (Node) format_tag;
-                    }
-                    else
-                        current_node = GSXML.getChildByTagName(current_node, "format");
-                }
-                else
-                {
-                    // look in <format> with no attributes
-                    logger.error("I presume this is search");
-            
-                    current_node_list = GSXML.getChildrenByTagName(current_node, "search");
-                    for(k=0; k<current_node_list.getLength(); k++) 
-                    {
-                        current_node = current_node_list.item(k);
-                        // if current_node has no attributes then break
-                        elem = (Element) current_node;
-                        if(elem.hasAttribute("name")==false)
-                            break;
-                    }
-                }
-
-                // Current_node should be a format tag
-                elem = (Element) current_node;
-    
-                logger.error("*Current_node = " + elem.getNodeName());
-
-                // seems we want to remove current child/ren and replace with format_statement's child/ren?
-
-                // remove existing
-                current_node_list = elem.getChildNodes();
-                logger.error("About to remove old children");
-                for(k=0; k<current_node_list.getLength(); k++)
-                {
-                    current_node = elem.removeChild(current_node_list.item(k));
-                }
-
-                logger.error("old nodes removed");
-
-                // append new but we have a string!
-                //GSXML.setNodeText(elem, "THIS IS A TEST");
-                //GSXML.setNodeText(elem, format_string);
-
-                current_node_list = format_statement.getChildNodes();
-                for(k=0; k<current_node_list.getLength(); k++)
-                {
-                    //if(transformed.getNodeType() == Node.DOCUMENT_NODE)
-                    //transformed = ((Document)transformed).getDocumentElement();
-                    //logger.error("Node type: "+current_node_list.item(k).getNodeType());
-                    if(current_node_list.item(k).getNodeType() != Node.PROCESSING_INSTRUCTION_NODE)
-                        elem.appendChild(config.importNode(current_node_list.item(k),true));
-                }
-                logger.error("new nodes added");
-
-                //String text = GSXML.getNodeText(elem);
-                //logger.error(text);
-                //text = text.replaceAll("_httpsite_", http_site);
-                //text = text.replaceAll("_httpcollection_", http_collection);
-                //GSXML.setNodeText(d, text);
-
-                // Now convert config document to string for writing to file
-                logger.error("Convert config to string");
-                String new_config = this.converter.getString(config);
-
-                new_config = StringUtils.replace(new_config, "&lt;", "<");
-                new_config = StringUtils.replace(new_config, "&gt;", ">");
-                new_config = StringUtils.replace(new_config, "&quot;", "\"");
-    
-                // Write to file (not original! for now)
-                BufferedWriter writer = new BufferedWriter(new FileWriter(collection_config+".new"));
-                writer.write(new_config);
-                writer.close();
-                logger.error("All is happy with collection");
-
-             } catch( Exception ex ) {
-                logger.error("There was an exception "+ex);
-
-                StringWriter sw = new StringWriter();
-                PrintWriter pw = new PrintWriter(sw, true);
-                ex.printStackTrace(pw);
-                pw.flush();
-                sw.flush();
-                logger.error(sw.toString());
-            }
-
-        }
-    }
-    else { // unknown type
-        return super.processMessage(request);
-
-    }
-    return response;
-    }
+	/** handles requests made to the ServiceCluster itself 
+	*
+	* @param req - the request Element- <request>
+	* @return the result Element - should be <response>
+	*/
+	protected Element processMessage(Element request) {
+
+		Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
+		response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
+		String type = request.getAttribute(GSXML.TYPE_ATT);
+		String lang = request.getAttribute(GSXML.LANG_ATT);
+		response.setAttribute(GSXML.TYPE_ATT, type);
+
+		logger.error("Collection received a message, attempting to process");
+
+		if (type.equals(GSXML.REQUEST_TYPE_FORMAT_STRING)) {
+			logger.error("Received format string request");
+
+			String subaction = request.getAttribute("subaction");
+			logger.error("Subaction is " + subaction);
+
+			String service = request.getAttribute("service");
+			logger.error("Service is " + service);
+
+			String classifier = null;
+			if(service.equals("ClassifierBrowse"))
+			{
+				classifier = request.getAttribute("classifier");
+				logger.error("Classifier is " + classifier);
+			}
+
+			Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM);
+			//String format_string = GSXML.getNodeText(format_element);
+			Element format_statement = (Element) format_element.getFirstChild();
+
+			//logger.error("Format string: " + format_string);
+			logger.error("Config file location = " + GSFile.collectionConfigFile(this.site_home, this.cluster_name));
+
+			// check for version file
+
+			String directory = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)).getParent() + File.separator;
+			logger.error("Directory is " + directory);
+
+			String version_filename = "";
+			if(service.equals("ClassifierBrowse"))
+			version_filename = directory + "browse_"+classifier+"_format_statement_version.txt";
+			else
+			version_filename = directory + "query_format_statement_version.txt";
+
+			File version_file = new File(version_filename);
+			logger.error("Version filename is " + version_filename);
+
+
+			if(subaction.equals("update"))
+			{
+				String version_number = "1";
+				BufferedWriter writer;
+
+				try{
+
+					if(version_file.exists())
+					{
+						// Read version
+						BufferedReader reader = new BufferedReader(new FileReader(version_filename));
+						version_number = reader.readLine();
+						int aInt = Integer.parseInt(version_number) + 1;
+						version_number = Integer.toString(aInt);
+						reader.close();
+					}
+					else{
+						// Create
+						version_file.createNewFile();
+						writer = new BufferedWriter(new FileWriter(version_filename));
+						writer.write(version_number);
+						writer.close();
+					}
+
+					// Write version file
+					String format_statement_filename = "";
+
+					if(service.equals("ClassifierBrowse"))
+					format_statement_filename = directory + "browse_"+classifier+"_format_statement_v" + version_number + ".txt";
+					else
+					format_statement_filename = directory + "query_format_statement_v" + version_number + ".txt";
+
+					logger.error("Format statement filename is " + format_statement_filename);
+
+					// Write format statement
+					String format_string = this.converter.getString(format_statement); //GSXML.xmlNodeToString(format_statement);
+					writer = new BufferedWriter(new FileWriter(format_statement_filename));
+					writer.write(format_string);
+					writer.close();
+
+					// Update version number
+					writer = new BufferedWriter(new FileWriter(version_filename));
+					writer.write(version_number);
+					writer.close();
+
+				} catch (IOException e) {
+					logger.error("IO Exception "+e);
+				}
+			}
+
+			if(subaction.equals("save"))
+			{
+				logger.error("SAVE format statement");
+
+				try{
+
+					// Convert format string to a document
+					//DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+					//DocumentBuilder builder = factory.newDocumentBuilder();
+					//String input = "<html><head><title></title></head><body>" + format_string + "</body></html>";
+					//String input = format_string.substring(0,format_string.length()-1)+"</xml>";
+					//logger.error(input);
+					//InputSource is = new InputSource( new StringReader( input ) );
+					//logger.error("About to parse format string");
+					//Document format_statement = (Document) builder.parse( is );
+					//logger.error("Done parsing format string");
+
+					// open collectionConfig.xml and read in to w3 Document
+					String collection_config = directory + "collectionConfig.xml";
+					Document config = this.converter.getDOM(new File(collection_config), "UTF-8");
+					
+					//String tag_name = "";
+					int k;
+					int index;
+					Element elem;
+					// Try importing entire tree to this.doc so we can add and remove children at ease
+					//Node current_node = this.doc.importNode(GSXML.getChildByTagName(config, "CollectionConfig"),true);
+					Node current_node = GSXML.getChildByTagName(config, "CollectionConfig");
+					NodeList current_node_list;
+
+					logger.error("Service is "+service);
+
+					if(service.equals("ClassifierBrowse"))
+					{
+						//tag_name = "browse";
+						// if CLX then need to look in <classifier> X then <format>
+						// default is <browse><format>
+
+						logger.error("Looking for browse");
+						current_node = GSXML.getChildByTagName(current_node, "browse");
+
+						// find CLX
+						if(classifier != null)
+						{
+							logger.error("Classifier is not null");
+							logger.error("Classifier is "+classifier);
+							current_node_list = GSXML.getChildrenByTagName(current_node, "classifier");
+							index = Integer.parseInt(classifier.substring(2)) - 1;
+							logger.error("classifier index is "+index);
+							// index should be given by X-1
+							current_node = current_node_list.item(index);
+							// what if classifier does not have a format tag?
+							if(GSXML.getChildByTagName(current_node, "format") == null)
+							{
+								logger.error("ERROR: valid classifier but does not have a format child");
+								// well then create a format tag
+								Element format_tag = config.createElement("format");
+								current_node = (Node) current_node.appendChild(format_tag);
+								//current_node = (Node) format_tag;
+							}
+							
+							else{
+								current_node = GSXML.getChildByTagName(current_node, "format");
+							}
+
+						}
+						else{
+							logger.error("Classifier is null");
+							// To support all classifiers, set classifier to null?  There is the chance here that the format tag does not exist
+							if(GSXML.getChildByTagName(current_node, "format") == null)
+							{
+								logger.error("ERROR: classifier does not have a format child");
+								// well then create a format tag
+								Element format_tag = config.createElement("format");
+								current_node = (Node) current_node.appendChild(format_tag);
+								//current_node = (Node) format_tag;
+							}
+							else
+							current_node = GSXML.getChildByTagName(current_node, "format");
+						}
+					}
+					else if(service.equals("AllClassifierBrowse"))
+					{
+						logger.error("Looking for browse");
+						current_node = GSXML.getChildByTagName(current_node, "browse");
+						if(GSXML.getChildByTagName(current_node, "format") == null)
+						{
+							logger.error("ERROR AllClassifierBrowse: all classifiers do not have a format child");
+							// well then create a format tag
+							Element format_tag = config.createElement("format");
+							current_node = (Node) current_node.appendChild(format_tag);
+							//current_node = (Node) format_tag;
+						}
+						else
+						current_node = GSXML.getChildByTagName(current_node, "format");
+					}
+					else
+					{
+						// look in <format> with no attributes
+						logger.error("I presume this is search");
+						
+						current_node_list = GSXML.getChildrenByTagName(current_node, "search");
+						for(k=0; k<current_node_list.getLength(); k++) 
+						{
+							current_node = current_node_list.item(k);
+							// if current_node has no attributes then break
+							elem = (Element) current_node;
+							if(elem.hasAttribute("name")==false)
+							break;
+						}
+					}
+
+					// Current_node should be a format tag
+					elem = (Element) current_node;
+					
+					logger.error("*Current_node = " + elem.getNodeName());
+
+					// seems we want to remove current child/ren and replace with format_statement's child/ren?
+
+					// remove existing
+					current_node_list = elem.getChildNodes();
+					logger.error("About to remove old children");
+					for(k=0; k<current_node_list.getLength(); k++)
+					{
+						current_node = elem.removeChild(current_node_list.item(k));
+					}
+
+					logger.error("old nodes removed");
+
+					// append new but we have a string!
+					//GSXML.setNodeText(elem, "THIS IS A TEST");
+					//GSXML.setNodeText(elem, format_string);
+
+					current_node_list = format_statement.getChildNodes();
+					for(k=0; k<current_node_list.getLength(); k++)
+					{
+						//if(transformed.getNodeType() == Node.DOCUMENT_NODE)
+						//transformed = ((Document)transformed).getDocumentElement();
+						//logger.error("Node type: "+current_node_list.item(k).getNodeType());
+						if(current_node_list.item(k).getNodeType() != Node.PROCESSING_INSTRUCTION_NODE)
+						elem.appendChild(config.importNode(current_node_list.item(k),true));
+					}
+					logger.error("new nodes added");
+
+					//String text = GSXML.getNodeText(elem);
+					//logger.error(text);
+					//text = text.replaceAll("_httpsite_", http_site);
+					//text = text.replaceAll("_httpcollection_", http_collection);
+					//GSXML.setNodeText(d, text);
+
+					// Now convert config document to string for writing to file
+					logger.error("Convert config to string");
+					String new_config = this.converter.getString(config);
+
+					new_config = StringUtils.replace(new_config, "&lt;", "<");
+					new_config = StringUtils.replace(new_config, "&gt;", ">");
+					new_config = StringUtils.replace(new_config, "&quot;", "\"");
+					
+					// Write to file (not original! for now)
+					BufferedWriter writer = new BufferedWriter(new FileWriter(collection_config+".new"));
+					writer.write(new_config);
+					writer.close();
+					logger.error("All is happy with collection");
+
+				} catch( Exception ex ) {
+					logger.error("There was an exception "+ex);
+
+					StringWriter sw = new StringWriter();
+					PrintWriter pw = new PrintWriter(sw, true);
+					ex.printStackTrace(pw);
+					pw.flush();
+					sw.flush();
+					logger.error(sw.toString());
+				}
+
+			}
+		}
+		else { // unknown type
+			return super.processMessage(request);
+
+		}
+		return response;
+	}
 
 }
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/ServiceCluster.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/ServiceCluster.java	(revision 24220)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/ServiceCluster.java	(revision 24221)
@@ -1,20 +1,20 @@
 /*
- *    ServiceCluster.java
- *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
- *
- *    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.
- */
+*    ServiceCluster.java
+*    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+*
+*    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.
+*/
 // leave the package name as is for now - should be changed to something better
 // cluster? groups?
@@ -41,738 +41,741 @@
 
 /* ServiceCluster - a groups of services that are related in some way
- * Implements ModuleInterface. Contains a list of services provided by the cluster, along with metadata about the cluster itself.
- * a collection is a special type of cluster
- *  @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
- *  @version $Revision$
- *  @see ModuleInterface
- */
+* Implements ModuleInterface. Contains a list of services provided by the cluster, along with metadata about the cluster itself.
+* a collection is a special type of cluster
+*  @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
+*  @version $Revision$
+*  @see ModuleInterface
+*/
 public class ServiceCluster  
-    implements ModuleInterface {
-
-    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.ServiceCluster.class.getName()); 
-
-    protected static final String CONFIG_ENCODING = "utf-8";
-
-    protected static final String DEFAULT_LANG = "en"; // hack for now, should be read from the coll cfg file? or site cfg file for cluster
-    
-    /** base directory for the site that this cluster belongs to*/
-    protected String site_home = null;
-    /** http address of the site that this cluster belongs to */
-    protected String site_http_address = null;
-    /** The name of the cluster - for a collection, this is the collection name*/
-    protected String cluster_name = null;
-    /** collection type : mg or mgpp */
-    protected String col_type = "";
-
-    /** a reference to the message router */
-    protected MessageRouter router = null;
-    /** The map of services.
-     *
-     * Maps Services to ServiceRack objects
-     * @see ServiceRack
-     *
-     */
-    protected HashMap service_map=null;
-    /** maps pseudo service names to real service names - needed if we have two services with the same name for one collection */
-    protected HashMap service_name_map=null;
-    
-    /** XML converter for String to DOM and vice versa */
-    protected XMLConverter converter=null;
-
-    /** container doc for description elements */
-    protected Document doc = null;
-    /** list of services */
-    protected Element service_list = null;
-    /** list of metadata - all metadata, regardless of language goes in here */
-    protected Element metadata_list = null;
-    /** language specific stuff */
-    //protected Element lang_specific_metadata_list = null;
-    protected Element display_item_list = null;
-    /** the element that will have any descriptions passed back in */
-    protected Element description = null;
-
-    /** list of plugin */
-    protected Element plugin_item_list = null;
-    
-    public void setSiteHome(String home) {
-	this.site_home = home;
-    }
-
-    public void setSiteAddress(String address) {
-	this.site_http_address = address;
-    }
-
-    public void cleanUp() {
-	Iterator i = this.service_map.values().iterator();
-	while (i.hasNext()) {
-	    ServiceRack s = (ServiceRack)i.next();
-	    s.cleanUp();
-	}
-    }
-    public void setClusterName(String name) {
-	this.cluster_name = name;	
-	this.description.setAttribute(GSXML.NAME_ATT, name);
-    }
-
-    public void setMessageRouter(MessageRouter m) {
-	this.router = m;
-    }
-
-    public ServiceCluster() {
-	this.service_map = new HashMap();
-	this.service_name_map = new HashMap();
-	this.converter = new XMLConverter();
-	this.doc = this.converter.newDOM();
-	this.description = this.doc.createElement(GSXML.CLUSTER_ELEM);
-	this.display_item_list = this.doc.createElement(GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER);
-	this.metadata_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-	this.plugin_item_list = this.doc.createElement(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
-    }
-
-    /**
-     * Configures the cluster.
-     *
-     * gsdlHome and clusterName must be set before configure is called.
-     *
-     * reads the site configuration file, and configures itself
-     * this calls configure(Element) with the XML element node from the config
-     * file.
-     * configure(Element) should be used if the config file has already been 
-     * parsed.  This method will work with any subclass.
-     * 
-     * @return true if configure successful, false otherwise.
-     */
-    public boolean configure() {
-
-	if (this.site_home == null || this.cluster_name== null) {
-	    logger.error("site_home and cluster_name must be set before configure called!");
-	    return false;
-	}
-	logger.info("configuring service cluster");
-	// read the site configuration file
-	File config_file = new File(GSFile.siteConfigFile(this.site_home));
-
-	if (!config_file.exists()) {
-	    logger.error("couldn't configure cluster: "+this.cluster_name +", "+config_file+" does not exist");
-	    return false;
-	}
-
-	Document doc = this.converter.getDOM(config_file, CONFIG_ENCODING);
-	if (doc == null) {
-	    logger.error("couldn't parse config file "+config_file.getPath());
-	    return false;
-	}
-	
-	// get the appropriate service cluster element
-	Element cluster_list = (Element)GSXML.getChildByTagName(doc.getDocumentElement(), GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER);
-	Element sc = GSXML.getNamedElement(cluster_list, GSXML.CLUSTER_ELEM,
-					   GSXML.NAME_ATT, this.cluster_name);
-	
-	return this.configure(sc);
-    }
-    
-    
-    public boolean configure(Element service_cluster_info) {
-    
-	// get the metadata - for now just add it to the list
-	Element meta_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-	if (meta_list !=null) {
-	    if (!addMetadata(meta_list)) {
-		
-		logger.error(" couldn't configure the metadata");
-	    }
-	}
-	
-	// get the display info
-	Element display_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER);
-	if (display_list !=null) {
-	    if (!addDisplayItems(display_list)) {
-		
-		logger.error("couldn't configure the display items");
-	    }
-	}
-	
-	//get the plugin info
-	Element import_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.IMPORT_ELEM);
-	if (import_list != null)
-	{
-		Element plugin_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
-		if (plugin_list !=null) {
-	   	 	if (!addPlugins(plugin_list)) {
-		
-				logger.error("couldn't configure the plugins");
-	    		}
-		}
-	}	
-	
-	// do the service racks
-	// empty the service map in case this is a reconfigure
-	clearServices();
-	Element service_rack_list = (Element)GSXML.getChildByTagName(service_cluster_info, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
-	if (service_rack_list == null) {
-	    // is this an error? could you ever have a service cluster
-	    // without service racks???
-	    logger.error("cluster has no service racks!!");
-	} else {
-	    
-	    if (!configureServiceRackList(service_rack_list, null)) {
-		logger.error("couldn't configure the  service racks!!");
-		return false;
-	    }
-	}
-
-	return true;
-    }
-    
-    /** adds metadata from a metadataList into the metadata_list xml 
-     */
-    protected boolean addMetadata(Element metadata_list) {
-	if (metadata_list == null) return false;
-	NodeList metanodes = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM);
-	if (metanodes.getLength()>0) { 	
-	    for(int k=0; k<metanodes.getLength(); k++) {
-		this.metadata_list.appendChild(this.doc.importNode(metanodes.item(k), true));
-	    }
-	}
-	
-	return true;
-    }
-
-    protected boolean addDisplayItems(Element display_list) {
-	
-	if (display_list==null) return false;
-	NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
-	if (displaynodes.getLength()>0) { 	
-	    for(int k=0; k<displaynodes.getLength(); k++) {
-		Element d = (Element) displaynodes.item(k);
-		String lang = d.getAttribute(GSXML.LANG_ATT);
-		if (lang==null||lang.equals("")) {
-		    //set the lang to teh default
-		    d.setAttribute(GSXML.LANG_ATT, DEFAULT_LANG);
-		}
-		String name = d.getAttribute(GSXML.NAME_ATT);
-		Element this_item = GSXML.getNamedElement(this.display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.NAME_ATT, name);
-		if (this_item==null) {
-		    this_item = this.doc.createElement(GSXML.DISPLAY_TEXT_ELEM);
-		    this_item.setAttribute(GSXML.NAME_ATT, name);
-		    this.display_item_list.appendChild(this_item);
-		}
-		
-		this_item.appendChild(this.doc.importNode(d, true));
-	    }
-	}
-	
-	return true;
-    }
-    
-    protected boolean addPlugins(Element plugin_list) {
-    	if (plugin_list == null) return false;
-	NodeList pluginNodes = plugin_list.getElementsByTagName(GSXML.PLUGIN_ELEM);
-	if (pluginNodes.getLength() > 0) {
-		for (int k = 0; k < pluginNodes.getLength(); k++)
+implements ModuleInterface {
+
+	static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.ServiceCluster.class.getName()); 
+
+	protected static final String CONFIG_ENCODING = "utf-8";
+
+	protected static final String DEFAULT_LANG = "en"; // hack for now, should be read from the coll cfg file? or site cfg file for cluster
+	
+	/** base directory for the site that this cluster belongs to*/
+	protected String site_home = null;
+	/** http address of the site that this cluster belongs to */
+	protected String site_http_address = null;
+	/** The name of the cluster - for a collection, this is the collection name*/
+	protected String cluster_name = null;
+	/** collection type : mg, mgpp or lucene */
+	protected String col_type = "";
+	/** database type : gdbm, jdbm or sqlite*/
+	protected String db_type = "";
+	
+	/** a reference to the message router */
+	protected MessageRouter router = null;
+	/** The map of services.
+	*
+	* Maps Services to ServiceRack objects
+	* @see ServiceRack
+	*
+	*/
+	protected HashMap service_map=null;
+	/** maps pseudo service names to real service names - needed if we have two services with the same name for one collection */
+	protected HashMap service_name_map=null;
+	
+	/** XML converter for String to DOM and vice versa */
+	protected XMLConverter converter=null;
+
+	/** container doc for description elements */
+	protected Document doc = null;
+	/** list of services */
+	protected Element service_list = null;
+	/** list of metadata - all metadata, regardless of language goes in here */
+	protected Element metadata_list = null;
+	/** language specific stuff */
+	//protected Element lang_specific_metadata_list = null;
+	protected Element display_item_list = null;
+	/** the element that will have any descriptions passed back in */
+	protected Element description = null;
+
+	/** list of plugin */
+	protected Element plugin_item_list = null;
+	
+	public void setSiteHome(String home) {
+		this.site_home = home;
+	}
+
+	public void setSiteAddress(String address) {
+		this.site_http_address = address;
+	}
+
+	public void cleanUp() {
+		Iterator i = this.service_map.values().iterator();
+		while (i.hasNext()) {
+			ServiceRack s = (ServiceRack)i.next();
+			s.cleanUp();
+		}
+	}
+	public void setClusterName(String name) {
+		this.cluster_name = name;	
+		this.description.setAttribute(GSXML.NAME_ATT, name);
+	}
+
+	public void setMessageRouter(MessageRouter m) {
+		this.router = m;
+	}
+
+	public ServiceCluster() {
+		this.service_map = new HashMap();
+		this.service_name_map = new HashMap();
+		this.converter = new XMLConverter();
+		this.doc = this.converter.newDOM();
+		this.description = this.doc.createElement(GSXML.CLUSTER_ELEM);
+		this.display_item_list = this.doc.createElement(GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER);
+		this.metadata_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+		this.plugin_item_list = this.doc.createElement(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
+	}
+
+	/**
+	* Configures the cluster.
+	*
+	* gsdlHome and clusterName must be set before configure is called.
+	*
+	* reads the site configuration file, and configures itself
+	* this calls configure(Element) with the XML element node from the config
+	* file.
+	* configure(Element) should be used if the config file has already been 
+	* parsed.  This method will work with any subclass.
+	* 
+	* @return true if configure successful, false otherwise.
+	*/
+	public boolean configure() {
+
+		if (this.site_home == null || this.cluster_name== null) {
+			logger.error("site_home and cluster_name must be set before configure called!");
+			return false;
+		}
+		logger.info("configuring service cluster");
+		// read the site configuration file
+		File config_file = new File(GSFile.siteConfigFile(this.site_home));
+
+		if (!config_file.exists()) {
+			logger.error("couldn't configure cluster: "+this.cluster_name +", "+config_file+" does not exist");
+			return false;
+		}
+
+		Document doc = this.converter.getDOM(config_file, CONFIG_ENCODING);
+		if (doc == null) {
+			logger.error("couldn't parse config file "+config_file.getPath());
+			return false;
+		}
+		
+		// get the appropriate service cluster element
+		Element cluster_list = (Element)GSXML.getChildByTagName(doc.getDocumentElement(), GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER);
+		Element sc = GSXML.getNamedElement(cluster_list, GSXML.CLUSTER_ELEM,
+		GSXML.NAME_ATT, this.cluster_name);
+		
+		return this.configure(sc);
+	}
+	
+	
+	public boolean configure(Element service_cluster_info) {
+		
+		// get the metadata - for now just add it to the list
+		Element meta_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+		if (meta_list !=null) {
+			if (!addMetadata(meta_list)) {
+				
+				logger.error(" couldn't configure the metadata");
+			}
+		}
+		
+		// get the display info
+		Element display_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER);
+		if (display_list !=null) {
+			if (!addDisplayItems(display_list)) {
+				
+				logger.error("couldn't configure the display items");
+			}
+		}
+		
+		//get the plugin info
+		Element import_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.IMPORT_ELEM);
+		if (import_list != null)
 		{
-			this.plugin_item_list.appendChild(this.doc.importNode(pluginNodes.item(k), true));
-		}
-	}
-	
-	return true;
-    }
-
-    
-  protected void clearServices() {
-    service_map.clear();
-    this.service_list = this.doc.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
-  }
-    /** creates and configures all the services - extra_info is some more xml 
+			Element plugin_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
+			if (plugin_list !=null) {
+				if (!addPlugins(plugin_list)) {
+					
+					logger.error("couldn't configure the plugins");
+				}
+			}
+		}	
+		
+		// do the service racks
+		// empty the service map in case this is a reconfigure
+		clearServices();
+		Element service_rack_list = (Element)GSXML.getChildByTagName(service_cluster_info, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
+		if (service_rack_list == null) {
+			// is this an error? could you ever have a service cluster
+			// without service racks???
+			logger.error("cluster has no service racks!!");
+		} else {
+			
+			if (!configureServiceRackList(service_rack_list, null)) {
+				logger.error("couldn't configure the  service racks!!");
+				return false;
+			}
+		}
+
+		return true;
+	}
+	
+	/** adds metadata from a metadataList into the metadata_list xml 
+	*/
+	protected boolean addMetadata(Element metadata_list) {
+		if (metadata_list == null) return false;
+		NodeList metanodes = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM);
+		if (metanodes.getLength()>0) { 	
+			for(int k=0; k<metanodes.getLength(); k++) {
+				this.metadata_list.appendChild(this.doc.importNode(metanodes.item(k), true));
+			}
+		}
+		
+		return true;
+	}
+
+	protected boolean addDisplayItems(Element display_list) {
+		
+		if (display_list==null) return false;
+		NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
+		if (displaynodes.getLength()>0) { 	
+			for(int k=0; k<displaynodes.getLength(); k++) {
+				Element d = (Element) displaynodes.item(k);
+				String lang = d.getAttribute(GSXML.LANG_ATT);
+				if (lang==null||lang.equals("")) {
+					//set the lang to teh default
+					d.setAttribute(GSXML.LANG_ATT, DEFAULT_LANG);
+				}
+				String name = d.getAttribute(GSXML.NAME_ATT);
+				Element this_item = GSXML.getNamedElement(this.display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.NAME_ATT, name);
+				if (this_item==null) {
+					this_item = this.doc.createElement(GSXML.DISPLAY_TEXT_ELEM);
+					this_item.setAttribute(GSXML.NAME_ATT, name);
+					this.display_item_list.appendChild(this_item);
+				}
+				
+				this_item.appendChild(this.doc.importNode(d, true));
+			}
+		}
+		
+		return true;
+	}
+	
+	protected boolean addPlugins(Element plugin_list) {
+		if (plugin_list == null) return false;
+		NodeList pluginNodes = plugin_list.getElementsByTagName(GSXML.PLUGIN_ELEM);
+		if (pluginNodes.getLength() > 0) {
+			for (int k = 0; k < pluginNodes.getLength(); k++)
+			{
+				this.plugin_item_list.appendChild(this.doc.importNode(pluginNodes.item(k), true));
+			}
+		}
+		
+		return true;
+	}
+
+	
+	protected void clearServices() {
+		service_map.clear();
+		this.service_list = this.doc.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
+	}
+	/** creates and configures all the services - extra_info is some more xml 
 that is passed to teh service  - eg used for coll config files for Collection
-    */
-    protected boolean configureServiceRackList(Element service_rack_list, 
-					   Element extra_info) {
-
-	// create all the services
-	NodeList nodes = service_rack_list.getElementsByTagName(GSXML.SERVICE_CLASS_ELEM);
-	if (nodes.getLength()==0) {
-	    logger.error("ServiceCluster configuration error: cluster "+this.cluster_name+" has no service modules!");
-	    return false;
-	}
-
-	for(int i=0; i<nodes.getLength(); i++) {
-	
-	    // the xml request to send to the serviceRack to query what
-	    // services it provides
-	    Element message = this.doc.createElement(GSXML.MESSAGE_ELEM);
-	    Element request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", "", "");
-	    message.appendChild(request);
-
-	    Element n = (Element)nodes.item(i);
-	    String servicetype = n.getAttribute(GSXML.NAME_ATT);
-	    
-	    ServiceRack s = null;
-	    
-	    try {
-		// try for a default service in standard package
-		s = (ServiceRack)Class.forName("org.greenstone.gsdl3.service."+servicetype).newInstance();
-		
-	    } catch (Exception e) {}
-	    if (s == null) {
-		try {
-		    // name as is, in case package is already specified
-		    s = (ServiceRack)Class.forName(servicetype).newInstance();
-		} catch (Exception e) {}
-	    }
-
-	    if (s == null) {
-		logger.error("Couldn't get an instance of class "+servicetype+", or org.greenstone.gsdl3.service."+servicetype);
-		continue;
-	    }
-
-	    
-	    s.setSiteHome(this.site_home);
-	    s.setSiteAddress(this.site_http_address);
-	    s.setClusterName(this.cluster_name);
-	    s.setMessageRouter(this.router);
-	    // pass the xml node to the service for configuration
-	    if (s.configure(n, extra_info)) {
-		
-		// find out the supported service types for this service module
-		Node types = s.process(message);
-		NodeList typenodes = ((Element)types).getElementsByTagName(GSXML.SERVICE_ELEM);	   
-		
-		for (int j=0; j<typenodes.getLength();j++) {
-		    String service = ((Element) typenodes.item(j)).getAttribute(GSXML.NAME_ATT);	   
-		    if (service_map.get(service)!=null) {
-			char extra = '0';
-			String new_service = service+extra;	   
-			
-			while (service_map.get(new_service)!=null) {
-			    extra++;
-			    new_service = service+extra;
-			}
-			this.service_name_map.put(new_service, service);
-			service=new_service;
-			((Element) typenodes.item(j)).setAttribute(GSXML.NAME_ATT, service);
-		    }
-		    this.service_map.put(service, s);
-		    // also add info to the ServiceInfo XML element
-		    this.service_list.appendChild(this.doc.importNode(typenodes.item(j), true));
-		}
-	    }
+	*/
+	protected boolean configureServiceRackList(Element service_rack_list, 
+	Element extra_info) {
+
+		// create all the services
+		NodeList nodes = service_rack_list.getElementsByTagName(GSXML.SERVICE_CLASS_ELEM);
+		if (nodes.getLength()==0) {
+			logger.error("ServiceCluster configuration error: cluster "+this.cluster_name+" has no service modules!");
+			return false;
+		}
+
+		for(int i=0; i<nodes.getLength(); i++) {
+			
+			// the xml request to send to the serviceRack to query what
+			// services it provides
+			Element message = this.doc.createElement(GSXML.MESSAGE_ELEM);
+			Element request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", "", "");
+			message.appendChild(request);
+
+			Element n = (Element)nodes.item(i);
+			String servicetype = n.getAttribute(GSXML.NAME_ATT);
+			
+			ServiceRack s = null;
+			
+			try {
+				// try for a default service in standard package
+				s = (ServiceRack)Class.forName("org.greenstone.gsdl3.service."+servicetype).newInstance();
+				
+			} catch (Exception e) {}
+			if (s == null) {
+				try {
+					// name as is, in case package is already specified
+					s = (ServiceRack)Class.forName(servicetype).newInstance();
+				} catch (Exception e) {}
+			}
+
+			if (s == null) {
+				logger.error("Couldn't get an instance of class "+servicetype+", or org.greenstone.gsdl3.service."+servicetype);
+				continue;
+			}
+
+			
+			s.setSiteHome(this.site_home);
+			s.setSiteAddress(this.site_http_address);
+			s.setClusterName(this.cluster_name);
+			s.setMessageRouter(this.router);
+			// pass the xml node to the service for configuration
+			if (s.configure(n, extra_info)) {
+				
+				// find out the supported service types for this service module
+				Node types = s.process(message);
+				NodeList typenodes = ((Element)types).getElementsByTagName(GSXML.SERVICE_ELEM);	   
+				
+				for (int j=0; j<typenodes.getLength();j++) {
+					String service = ((Element) typenodes.item(j)).getAttribute(GSXML.NAME_ATT);	   
+					if (service_map.get(service)!=null) {
+						char extra = '0';
+						String new_service = service+extra;	   
+						
+						while (service_map.get(new_service)!=null) {
+							extra++;
+							new_service = service+extra;
+						}
+						this.service_name_map.put(new_service, service);
+						service=new_service;
+						((Element) typenodes.item(j)).setAttribute(GSXML.NAME_ATT, service);
+					}
+					this.service_map.put(service, s);
+					// also add info to the ServiceInfo XML element
+					this.service_list.appendChild(this.doc.importNode(typenodes.item(j), true));
+				}
+			}
+		} 
+		
+		return true;
+		
+		
+	}
+
+
+	/**
+	* Process an XML document - uses Strings 
+	*  just calls process(Node).
+	*
+	* @param in the Document to process - a string
+	* @return the resultant document as a string - contains any error messages
+	* @see String
+	*/
+	public String process(String in) {
+
+		Document doc = this.converter.getDOM(in);
+		
+		Node res = process(doc);
+		return this.converter.getString(res);
+		
+	}
+	
+	/** process XML as Node
+	*
+	*/
+	public Node process(Node message_node) {
+
+		Element message = this.converter.nodeToElement(message_node);
+
+		NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM);
+		Document mess_doc = message.getOwnerDocument();
+		Element mainResult = this.doc.createElement(GSXML.MESSAGE_ELEM);
+		if (requests.getLength()==0) {
+			logger.error("no requests for cluster:"+this.cluster_name);
+			// no requests
+			return mainResult; // for now
+		}
+		for (int i=0; i<requests.getLength(); i++) {
+			Element request = (Element)requests.item(i);
+			String to = request.getAttribute(GSXML.TO_ATT);
+
+			// the cluster name should be first, check, then remove
+			String clustername = GSPath.getFirstLink(to);
+			if (!clustername.equals(this.cluster_name)){ 
+				logger.error("cluster name wrong! was "+clustername+" should have been "+this.cluster_name);
+				continue; // ignore this request
+			}
+			to = GSPath.removeFirstLink(to);
+			request.setAttribute(GSXML.TO_ATT, to);
+			
+			if (to.equals("")) { // this command is for me
+				Element response = processMessage(request);
+				mainResult.appendChild(response);
+				
+			} else { // the request is for one of my services
+				String service = GSPath.getFirstLink(to);
+				
+				if (!this.service_map.containsKey(service)) {
+					logger.error("non-existant service, "+service+", specified!");
+					continue;
+				}
+				String real_service = service;
+				if (this.service_name_map.containsKey(service)) {
+					real_service = (String)this.service_name_map.get(service);
+					// need to change the to att in the request - give the real service name
+					to = request.getAttribute(GSXML.TO_ATT);
+					String old_to = to;
+					to = GSPath.replaceFirstLink(to, real_service);
+					request.setAttribute(GSXML.TO_ATT, to);
+				}
+				// have to pass the request to the service
+				Element single_message = mess_doc.createElement(GSXML.MESSAGE_ELEM);
+				single_message.appendChild(request);
+				Node response_message = ((ModuleInterface)this.service_map.get(service)).process(single_message);
+				if (response_message != null) {
+					Element response = (Element) GSXML.getChildByTagName(response_message, GSXML.RESPONSE_ELEM);
+					String from = response.getAttribute(GSXML.FROM_ATT);
+					if (!real_service.equals(service)) {
+						// replace the real service name with the pseudo service name
+						from = GSPath.replaceFirstLink(from, service);
+						// also need to do it in the service itself
+						// shoudl this be done here??
+						Element service_elem = (Element) GSXML.getChildByTagName(response, GSXML.SERVICE_ELEM);
+						if (service_elem!= null) {
+							service_elem.setAttribute(GSXML.NAME_ATT, service);
+						}
+					}
+					from = GSPath.prependLink(from, this.cluster_name);
+					response.setAttribute(GSXML.FROM_ATT, from);
+					mainResult.appendChild(this.doc.importNode(response, true));
+				}
+				
+			} // else
+			
+			
+		} // for each request
+		return mainResult;
+	}
+
+	/** handles requests made to the ServiceCluster itself 
+	*
+	* @param req - the request Element- <request>
+	* @return the result Element - should be <response>
+	*/
+	protected Element processMessage(Element request) {
+
+		Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
+		response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
+		String type = request.getAttribute(GSXML.TYPE_ATT);
+		String lang = request.getAttribute(GSXML.LANG_ATT);
+		response.setAttribute(GSXML.TYPE_ATT, type);
+		
+		if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) {
+			// create the collection element
+			Element description = (Element)this.description.cloneNode(false);
+			// set collection type : mg or mgpp
+			description.setAttribute(GSXML.TYPE_ATT, col_type);
+			description.setAttribute(GSXML.DB_TYPE_ATT, db_type);
+
+			response.appendChild(description);
+			// check the param list
+			Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+			if (param_list == null) {	    	    
+				addAllDisplayInfo(description, lang);				
+				description.appendChild(this.service_list);
+				description.appendChild(this.metadata_list);
+				description.appendChild(this.plugin_item_list);
+				return response;
+			}
+			
+			// go through the param list and see what components are wanted
+			NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
+			for (int i=0; i<params.getLength(); i++) {	    
+				
+				Element param = (Element)params.item(i);				
+				// Identify the structure information desired
+				if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM)) {
+					String info = param.getAttribute(GSXML.VALUE_ATT);
+					if (info.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
+						description.appendChild(this.service_list);
+					} else if (info.equals(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER)) {
+						description.appendChild(metadata_list);
+					} else if (info.equals(GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER)) {
+						addAllDisplayInfo(description, lang);
+					} else if (info.equals(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER)) {
+						description.appendChild(plugin_item_list);
+					}
+				}
+			}
+			return response;
+		}
+		/*
+	if (type.equals(GSXML.REQUEST_TYPE_FORMAT_STRING)) {
+		logger.error("Received format string request");
+		String service = request.getAttribute("service");
+		logger.error("Service is " + service);
+		String classifier = null;
+		if(service.equals("ClassifierBrowse"))
+		{
+			classifier = request.getAttribute("classifier");
+			logger.error("Classifier is " + classifier);
+		}
+		Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM);
+		String format_string = GSXML.getNodeText(format_element);
+		logger.error("Format string: " + format_string);
+		logger.error("Config file location = " + GSFile.collectionConfigFile(this.site_home, this.cluster_name));
+
+		// check for version file
+
+		String directory = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)).getParent() + File.pathSeparator;
+		logger.error("Directory is " + directory);
+
+		String version_filename = "";
+
+		if(service.equals("ClassifierBrowse"))
+			version_filename = directory + "browse_"+classifier+"_format_statement_version.txt";
+		else
+			version_filename = directory + "query_format_statement_version.txt";
+
+		File version_file = new File(version_filename);
+		logger.error("Version filename is " + version_filename);
+
+		String version_number = "1";
+		BufferedWriter writer; // = new BufferedWriter(new FileWriter(version_filename));
+		//RandomAccessFile version_file_random_access;
+
+		try{
+
+			if(version_file.exists())
+			{
+				// Read version
+				BufferedReader reader = new BufferedReader(new FileReader(version_filename));
+				//version_file_random_access = new RandomAccessFile(version_file, "r");
+				//logger.error("
+				//version_number = version_file_random_access.readInt();
+				version_number = reader.readLine();
+				int aInt = Integer.parseInt(version_number) + 1;
+				version_number = Integer.toString(aInt);
+				reader.close();
+				//version_file_random_access.close();
+			}
+			else{
+				// Create
+				version_file.createNewFile(); 
+				// write 1 to file
+				writer = new BufferedWriter(new FileWriter(version_filename));
+				//version_file_random_access = new RandomAccessFile(version_file, "w");
+				//version_file_random_access.writeInt(version_number);
+				writer.write(version_number);
+				writer.close();
+				//version_file_random_access.close();
+			}
+
+			// Write version file
+			String format_statement_filename = "";
+
+			if(service.equals("ClassifierBrowse"))
+				format_statement_filename = directory + "browse_"+classifier+"_format_statement_v" + version_number + ".txt"; 
+			else
+				format_statement_filename = directory + "query_format_statement_v" + version_number + ".txt";
+
+			logger.error("Format statement filename is " + format_statement_filename);
+
+			writer = new BufferedWriter(new FileWriter(format_statement_filename));
+			writer.write(format_string);
+			writer.close();
+
+			// Update version number
+			//version_file_random_access = new RandomAccessFile(version_file, "w");
+			//version_file_random_access.writeInt(version_number);
+			//version_file_random_access.close();
+
+			writer = new BufferedWriter(new FileWriter(version_filename));
+			//version_file_random_access = new RandomAccessFile(version_file, "w");
+			//version_file_random_access.writeInt(version_number);
+			writer.write(version_number);
+			writer.close();
+
+
+
+		} catch (IOException e) {
+			logger.error("IO Exception "+e);
+			//System.exit(1);
+		}
+
+
+	}*/
+		if (type.equals(GSXML.REQUEST_TYPE_SYSTEM)) {
+			response = processSystemRequest(request);
+		} else { // unknown type
+			logger.error("cant handle request of type "+ type);
+			
+		}
+		return response;
+	}
+
+	protected Element processSystemRequest(Element request) {
+
+		Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
+		response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
+		response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_SYSTEM);
+
+		// a list of system requests - should put any error messages
+		// or success messages into response
+		NodeList commands = request.getElementsByTagName(GSXML.SYSTEM_ELEM);
+		String message=null;	
+		for (int i=0; i<commands.getLength(); i++) {
+			// all the commands should be Elements
+			Element elem = (Element)commands.item(i);
+			String action = elem.getAttribute(GSXML.TYPE_ATT);
+			if (action.equals(GSXML.SYSTEM_TYPE_CONFIGURE)) {
+				String subset = elem.getAttribute(GSXML.SYSTEM_SUBSET_ATT);
+				if (subset.equals("")) {
+					// need to reconfigure the service cluster
+					
+					if (this.configure()) {
+						Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, this.cluster_name + " reconfigured");
+						response.appendChild(s);
+						
+					} else {
+						Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, this.cluster_name + " could not be reconfigured");
+						response.appendChild(s); 
+					}
+				} else if (this.configureSubset(subset)) {
+					Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, this.cluster_name + " "+subset+" reconfigured");
+					response.appendChild(s);
+				} else {
+					Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, this.cluster_name + " "+subset + " could not be reconfigured");
+					response.appendChild(s); 
+				}
+				continue;
+			} // configure action
+			
+			String module_name = elem.getAttribute(GSXML.SYSTEM_MODULE_NAME_ATT);
+			String module_type = elem.getAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT);
+			if (action.equals(GSXML.SYSTEM_TYPE_ACTIVATE)) {
+				Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, "activate action not yet implemented - does it even make sense in this context??");
+				response.appendChild(s);
+			} else if (action.equals(GSXML.SYSTEM_TYPE_DEACTIVATE)) {
+				if (module_type.equals(GSXML.SERVICE_ELEM)) {
+					// deactivate the service
+					// remove from service_map
+					this.service_map.remove(module_name);
+					Element service_elem = GSXML.getNamedElement(this.service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT, module_name);
+					service_list.removeChild(service_elem);		    
+					message = module_type+": "+module_name+" deactivated";
+				} else {
+					message = "can't deactivate "+module_type+" type modules!";}
+				Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, message);
+				response.appendChild(s);
+			} else {
+				logger.error("cant process system request, action "+action);
+				continue;
+			}
+		} // for each command
+		return response;
+	}
+
+	/** 
+	* do a configure on only part of the collection
+	*/
+	protected boolean configureSubset(String subset) {
+		
+		File configFile = new File(GSFile.siteConfigFile(this.site_home));
+		if (!configFile.exists() ) {
+			logger.error("site config file: "+configFile.getPath()+" not found!");
+			// wont be able to do any of the requests
+			return false;
+			
+		}
+		
+		Document site_config_doc  = this.converter.getDOM(configFile);
+		if (site_config_doc == null) {
+			logger.error("could not read in site config file: "+configFile.getPath());
+			return false;
+		}
+		
+		Element site_config_elem = site_config_doc.getDocumentElement();
+		Element cluster_config_elem = GSXML.getNamedElement((Element)GSXML.getChildByTagName(site_config_elem, GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER), GSXML.CLUSTER_ELEM, GSXML.NAME_ATT, this.cluster_name);
+		if (cluster_config_elem == null) {
+			logger.error("site config file: "+configFile.getPath()+" has no element for cluster "+this.cluster_name);
+			// wont be able to do any of teh requests
+			return false;
+			
+		}
+		if (subset.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
+			Element service_rack_list = (Element)GSXML.getChildByTagName(cluster_config_elem, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
+			clearServices();
+			return configureServiceRackList(service_rack_list, null);
+		} else if (subset.equals(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER)) {
+			this.metadata_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+			Element metadata_list = (Element)GSXML.getChildByTagName(cluster_config_elem, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+			return addMetadata(metadata_list);
+		} else if (subset.equals(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER)) {
+			this.plugin_item_list = this.doc.createElement(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
+			Element import_list = (Element)GSXML.getChildByTagName(cluster_config_elem,GSXML.IMPORT_ELEM);
+			if (import_list != null)
+			{
+				Element plugin_item_list = (Element)GSXML.getChildByTagName(cluster_config_elem,GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
+				return addPlugins(plugin_item_list);
+			}
+			else
+			return false;
+		} else {
+			logger.error("cannot process system request, configure "+subset);
+			return false;
+		} 
+
 	} 
-	
-	return true;
-	
-	
-    }
-
-
-    /**
-     * Process an XML document - uses Strings 
-     *  just calls process(Node).
-     *
-     * @param in the Document to process - a string
-     * @return the resultant document as a string - contains any error messages
-     * @see String
-     */
-    public String process(String in) {
-
-	Document doc = this.converter.getDOM(in);
-	
-	Node res = process(doc);
-	return this.converter.getString(res);
-	
-    }
-    
-    /** process XML as Node
-     *
-     */
-    public Node process(Node message_node) {
-
-	Element message = this.converter.nodeToElement(message_node);
-
-	NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM);
-	Document mess_doc = message.getOwnerDocument();
-	Element mainResult = this.doc.createElement(GSXML.MESSAGE_ELEM);
-	if (requests.getLength()==0) {
-	    logger.error("no requests for cluster:"+this.cluster_name);
-	    // no requests
-	    return mainResult; // for now
-	}
-	for (int i=0; i<requests.getLength(); i++) {
-	    Element request = (Element)requests.item(i);
-	    String to = request.getAttribute(GSXML.TO_ATT);
-
-	    // the cluster name should be first, check, then remove
-	    String clustername = GSPath.getFirstLink(to);
-	    if (!clustername.equals(this.cluster_name)){ 
-		logger.error("cluster name wrong! was "+clustername+" should have been "+this.cluster_name);
-		continue; // ignore this request
-	    }
-	    to = GSPath.removeFirstLink(to);
-	    request.setAttribute(GSXML.TO_ATT, to);
-	   
-	    if (to.equals("")) { // this command is for me
-		Element response = processMessage(request);
-		mainResult.appendChild(response);
-		
-	    } else { // the request is for one of my services
-		String service = GSPath.getFirstLink(to);
-		
-		if (!this.service_map.containsKey(service)) {
-		    logger.error("non-existant service, "+service+", specified!");
-		    continue;
-		}
-		String real_service = service;
-		if (this.service_name_map.containsKey(service)) {
-		    real_service = (String)this.service_name_map.get(service);
-		    // need to change the to att in the request - give the real service name
-		    to = request.getAttribute(GSXML.TO_ATT);
-		    String old_to = to;
-		    to = GSPath.replaceFirstLink(to, real_service);
-		    request.setAttribute(GSXML.TO_ATT, to);
-		}
-		// have to pass the request to the service
-		Element single_message = mess_doc.createElement(GSXML.MESSAGE_ELEM);
-		single_message.appendChild(request);
-		Node response_message = ((ModuleInterface)this.service_map.get(service)).process(single_message);
-		if (response_message != null) {
-		    Element response = (Element) GSXML.getChildByTagName(response_message, GSXML.RESPONSE_ELEM);
-		    String from = response.getAttribute(GSXML.FROM_ATT);
-		    if (!real_service.equals(service)) {
-			// replace the real service name with the pseudo service name
-			from = GSPath.replaceFirstLink(from, service);
-			// also need to do it in the service itself
-			// shoudl this be done here??
-			Element service_elem = (Element) GSXML.getChildByTagName(response, GSXML.SERVICE_ELEM);
-			if (service_elem!= null) {
-			    service_elem.setAttribute(GSXML.NAME_ATT, service);
-			}
-		    }
-		    from = GSPath.prependLink(from, this.cluster_name);
-		    response.setAttribute(GSXML.FROM_ATT, from);
-		    mainResult.appendChild(this.doc.importNode(response, true));
-		}
-		  
-	    } // else
-		
-	   
-	} // for each request
-	return mainResult;
-    }
-
-    /** handles requests made to the ServiceCluster itself 
-     *
-     * @param req - the request Element- <request>
-     * @return the result Element - should be <response>
-     */
-    protected Element processMessage(Element request) {
-
-	Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
-	response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
-	String type = request.getAttribute(GSXML.TYPE_ATT);
-	String lang = request.getAttribute(GSXML.LANG_ATT);
-	response.setAttribute(GSXML.TYPE_ATT, type);
-	
-	if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) {
-	    // create the collection element
-	    Element description = (Element)this.description.cloneNode(false);
-	    // set collection type : mg or mgpp
-	    description.setAttribute(GSXML.TYPE_ATT, col_type);
-
-	    response.appendChild(description);
-	    // check the param list
-	    Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	    if (param_list == null) {	    	    
-		addAllDisplayInfo(description, lang);				
-		description.appendChild(this.service_list);
-		description.appendChild(this.metadata_list);
-		description.appendChild(this.plugin_item_list);
-		return response;
-	    }
-	    
-	    // go through the param list and see what components are wanted
-	    NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
-	    for (int i=0; i<params.getLength(); i++) {	    
-		
-		Element param = (Element)params.item(i);				
-		// Identify the structure information desired
-		if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM)) {
-		    String info = param.getAttribute(GSXML.VALUE_ATT);
-		    if (info.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
-			description.appendChild(this.service_list);
-		    } else if (info.equals(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER)) {
-			description.appendChild(metadata_list);
-		    } else if (info.equals(GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER)) {
-			addAllDisplayInfo(description, lang);
-		    } else if (info.equals(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER)) {
-		    	description.appendChild(plugin_item_list);
-		    }
-		}
-	    }
-	    return response;
-	}
-    /*
-    if (type.equals(GSXML.REQUEST_TYPE_FORMAT_STRING)) {
-        logger.error("Received format string request");
-        String service = request.getAttribute("service");
-        logger.error("Service is " + service);
-        String classifier = null;
-        if(service.equals("ClassifierBrowse"))
-        {
-            classifier = request.getAttribute("classifier");
-            logger.error("Classifier is " + classifier);
-        }
-        Element format_element = (Element) GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM);
-        String format_string = GSXML.getNodeText(format_element);
-        logger.error("Format string: " + format_string);
-        logger.error("Config file location = " + GSFile.collectionConfigFile(this.site_home, this.cluster_name));
-
-        // check for version file
-
-        String directory = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)).getParent() + File.pathSeparator;
-        logger.error("Directory is " + directory);
-
-        String version_filename = "";
-
-        if(service.equals("ClassifierBrowse"))
-            version_filename = directory + "browse_"+classifier+"_format_statement_version.txt";
-        else
-            version_filename = directory + "query_format_statement_version.txt";
-
-        File version_file = new File(version_filename);
-        logger.error("Version filename is " + version_filename);
-
-        String version_number = "1";
-        BufferedWriter writer; // = new BufferedWriter(new FileWriter(version_filename));
-        //RandomAccessFile version_file_random_access;
-
-        try{
-
-            if(version_file.exists())
-            {
-                // Read version
-                 BufferedReader reader = new BufferedReader(new FileReader(version_filename));
-                 //version_file_random_access = new RandomAccessFile(version_file, "r");
-                 //logger.error("
-                 //version_number = version_file_random_access.readInt();
-                 version_number = reader.readLine();
-                 int aInt = Integer.parseInt(version_number) + 1;
-                 version_number = Integer.toString(aInt);
-                 reader.close();
-                 //version_file_random_access.close();
-            }
-            else{
-                // Create
-                version_file.createNewFile(); 
-                // write 1 to file
-                writer = new BufferedWriter(new FileWriter(version_filename));
-                //version_file_random_access = new RandomAccessFile(version_file, "w");
-                //version_file_random_access.writeInt(version_number);
-                writer.write(version_number);
-                writer.close();
-                //version_file_random_access.close();
-            }
-
-            // Write version file
-            String format_statement_filename = "";
-
-            if(service.equals("ClassifierBrowse"))
-                format_statement_filename = directory + "browse_"+classifier+"_format_statement_v" + version_number + ".txt"; 
-            else
-                format_statement_filename = directory + "query_format_statement_v" + version_number + ".txt";
-
-            logger.error("Format statement filename is " + format_statement_filename);
-
-            writer = new BufferedWriter(new FileWriter(format_statement_filename));
-            writer.write(format_string);
-            writer.close();
-
-            // Update version number
-            //version_file_random_access = new RandomAccessFile(version_file, "w");
-            //version_file_random_access.writeInt(version_number);
-            //version_file_random_access.close();
-
-            writer = new BufferedWriter(new FileWriter(version_filename));
-            //version_file_random_access = new RandomAccessFile(version_file, "w");
-            //version_file_random_access.writeInt(version_number);
-            writer.write(version_number);
-            writer.close();
-
-
-
-        } catch (IOException e) {
-            logger.error("IO Exception "+e);
-            //System.exit(1);
-        }
-
-
-    }*/
-	if (type.equals(GSXML.REQUEST_TYPE_SYSTEM)) {
-	    response = processSystemRequest(request);
-	} else { // unknown type
-	    logger.error("cant handle request of type "+ type);
-	    
-	}
-	return response;
-    }
-
-    protected Element processSystemRequest(Element request) {
-
-	Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
-	response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
-	response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_SYSTEM);
-
-	// a list of system requests - should put any error messages
-	// or success messages into response
-	NodeList commands = request.getElementsByTagName(GSXML.SYSTEM_ELEM);
-	String message=null;	
-	for (int i=0; i<commands.getLength(); i++) {
-	    // all the commands should be Elements
-	    Element elem = (Element)commands.item(i);
-	    String action = elem.getAttribute(GSXML.TYPE_ATT);
-	    if (action.equals(GSXML.SYSTEM_TYPE_CONFIGURE)) {
-		String subset = elem.getAttribute(GSXML.SYSTEM_SUBSET_ATT);
-		if (subset.equals("")) {
-		    // need to reconfigure the service cluster
-		    
-		    if (this.configure()) {
-			Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, this.cluster_name + " reconfigured");
-			response.appendChild(s);
-			
-		    } else {
-			Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, this.cluster_name + " could not be reconfigured");
-			response.appendChild(s); 
-		    }
-		} else if (this.configureSubset(subset)) {
-		    Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, this.cluster_name + " "+subset+" reconfigured");
-		    response.appendChild(s);
-		} else {
-		    Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, this.cluster_name + " "+subset + " could not be reconfigured");
-		    response.appendChild(s); 
-		}
-		continue;
-	    } // configure action
-	    
-	    String module_name = elem.getAttribute(GSXML.SYSTEM_MODULE_NAME_ATT);
-	    String module_type = elem.getAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT);
-	    if (action.equals(GSXML.SYSTEM_TYPE_ACTIVATE)) {
-		Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, "activate action not yet implemented - does it even make sense in this context??");
-		response.appendChild(s);
-	    } else if (action.equals(GSXML.SYSTEM_TYPE_DEACTIVATE)) {
-		if (module_type.equals(GSXML.SERVICE_ELEM)) {
-		    // deactivate the service
-		    // remove from service_map
-		    this.service_map.remove(module_name);
-		    Element service_elem = GSXML.getNamedElement(this.service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT, module_name);
-		    service_list.removeChild(service_elem);		    
-		    message = module_type+": "+module_name+" deactivated";
-		} else {
-		    message = "can't deactivate "+module_type+" type modules!";}
-		Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, message);
-		response.appendChild(s);
-	    } else {
-		logger.error("cant process system request, action "+action);
-		continue;
-	    }
-	} // for each command
-	return response;
-    }
-
-    /** 
-     * do a configure on only part of the collection
-     */
-    protected boolean configureSubset(String subset) {
-	
-	File configFile = new File(GSFile.siteConfigFile(this.site_home));
-	if (!configFile.exists() ) {
-	    logger.error("site config file: "+configFile.getPath()+" not found!");
-	    // wont be able to do any of the requests
-	    return false;
-	    
-	}
-	
-	Document site_config_doc  = this.converter.getDOM(configFile);
-	if (site_config_doc == null) {
-	    logger.error("could not read in site config file: "+configFile.getPath());
-	    return false;
-	}
-	
-	Element site_config_elem = site_config_doc.getDocumentElement();
-	Element cluster_config_elem = GSXML.getNamedElement((Element)GSXML.getChildByTagName(site_config_elem, GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER), GSXML.CLUSTER_ELEM, GSXML.NAME_ATT, this.cluster_name);
-	if (cluster_config_elem == null) {
-	    logger.error("site config file: "+configFile.getPath()+" has no element for cluster "+this.cluster_name);
-	    // wont be able to do any of teh requests
-	    return false;
-	    
-	}
-	if (subset.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
-	    Element service_rack_list = (Element)GSXML.getChildByTagName(cluster_config_elem, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
-	    clearServices();
-	    return configureServiceRackList(service_rack_list, null);
-	} else if (subset.equals(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER)) {
-	    this.metadata_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-	    Element metadata_list = (Element)GSXML.getChildByTagName(cluster_config_elem, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-	    return addMetadata(metadata_list);
-	} else if (subset.equals(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER)) {
-	    this.plugin_item_list = this.doc.createElement(GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
-	    Element import_list = (Element)GSXML.getChildByTagName(cluster_config_elem,GSXML.IMPORT_ELEM);
-	    if (import_list != null)
-	    {
-	    	Element plugin_item_list = (Element)GSXML.getChildByTagName(cluster_config_elem,GSXML.PLUGIN_ELEM+GSXML.LIST_MODIFIER);
-	    	return addPlugins(plugin_item_list);
-            }
-	    else
-	    	return false;
-	} else {
-	    logger.error("cannot process system request, configure "+subset);
-	    return false;
-	} 
-
-    } 
-
-
-    protected boolean addAllDisplayInfo(Element description, String lang) {
-	
-	NodeList items = this.display_item_list.getChildNodes();
-	for (int i=0; i<items.getLength(); i++) { // for each key
-	    Element m = (Element) items.item(i);
-	    // find the child with the correct language
-	    Element new_m = GSXML.getNamedElement(m, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, lang);
-	    if (new_m==null && lang != DEFAULT_LANG) {
-		// use the default lang
-		new_m = GSXML.getNamedElement(m, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, DEFAULT_LANG);
-	    }
-	    if (new_m==null) {
-		// just get the first one
-		new_m = (Element)GSXML.getChildByTagName(m, GSXML.DISPLAY_TEXT_ELEM);
-	    }
-	    description.appendChild(new_m.cloneNode(true));
-	}
-	return true;
-	
-    }
-
-    
-    protected Element getDisplayTextElement(String key, String lang) {
-	
-	Element this_item = GSXML.getNamedElement(this.display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.NAME_ATT, key);
-	if (this_item == null) {
-	    return null;
-	}
-
-	Element this_lang = GSXML.getNamedElement(this_item, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, lang);
-	if (this_lang == null && lang != DEFAULT_LANG) {
-	    // try the default
-	    this_lang = GSXML.getNamedElement(this_item, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, DEFAULT_LANG);
-	}
-	if (this_lang == null) {
-	    // just return the first one
-	    return GSXML.getFirstElementChild(this_item);//(Element)this_item.getFirstChild().cloneNode(true);
-	}
-	return (Element)this_lang.cloneNode(true);
-	
-    }
-    public HashMap getServiceMap() {
-    	return service_map;
-    }
+
+
+	protected boolean addAllDisplayInfo(Element description, String lang) {
+		
+		NodeList items = this.display_item_list.getChildNodes();
+		for (int i=0; i<items.getLength(); i++) { // for each key
+			Element m = (Element) items.item(i);
+			// find the child with the correct language
+			Element new_m = GSXML.getNamedElement(m, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, lang);
+			if (new_m==null && lang != DEFAULT_LANG) {
+				// use the default lang
+				new_m = GSXML.getNamedElement(m, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, DEFAULT_LANG);
+			}
+			if (new_m==null) {
+				// just get the first one
+				new_m = (Element)GSXML.getChildByTagName(m, GSXML.DISPLAY_TEXT_ELEM);
+			}
+			description.appendChild(new_m.cloneNode(true));
+		}
+		return true;
+		
+	}
+
+	
+	protected Element getDisplayTextElement(String key, String lang) {
+		
+		Element this_item = GSXML.getNamedElement(this.display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.NAME_ATT, key);
+		if (this_item == null) {
+			return null;
+		}
+
+		Element this_lang = GSXML.getNamedElement(this_item, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, lang);
+		if (this_lang == null && lang != DEFAULT_LANG) {
+			// try the default
+			this_lang = GSXML.getNamedElement(this_item, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, DEFAULT_LANG);
+		}
+		if (this_lang == null) {
+			// just return the first one
+			return GSXML.getFirstElementChild(this_item);//(Element)this_item.getFirstChild().cloneNode(true);
+		}
+		return (Element)this_lang.cloneNode(true);
+		
+	}
+	public HashMap getServiceMap() {
+		return service_map;
+	}
 }
 
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ArchiveRetrieve.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ArchiveRetrieve.java	(revision 24220)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ArchiveRetrieve.java	(revision 24221)
@@ -1,4 +1,4 @@
 /*
-*    AbstractDocumentRetrieve.java
+*    ArchiveRetrieve.java
 *    a base class for retrieval services
 
@@ -21,4 +21,5 @@
 package org.greenstone.gsdl3.service;
 
+import org.greenstone.gsdl3.util.DBInfo;
 import org.greenstone.gsdl3.util.GSPath;
 import org.greenstone.gsdl3.util.GSXML;
@@ -31,27 +32,21 @@
 import java.io.File;
 import java.util.HashMap;
-
-/** Abstract class for Document Retrieval Services
-*
-* @author <a href="mailto:greenstone@cs.waikato.ac.nz">Katherine Don</a>
-*/
-
-public class ArchiveRetrieve extends ServiceRack {
-
+import java.util.Vector;
+
+public class ArchiveRetrieve extends ServiceRack 
+{
 	static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.ArchiveRetrieve.class.getName());
 
-	protected static final String ARCHIVE_FILE_PATH_RETRIEVE_SERVICE = "ArchiveFilePathRetrieve";
+	protected static final String DOCUMENT_FILE_PATH_RETRIEVE_SERVICE = "DocumentFilePathRetrieve";
+	protected static final String ASSOCIATED_IMPORT_FILES_RETRIEVE_SERVICE = "AssociatedImportFilesRetrieve";
+	protected static final String SOURCE_FILE_OID_RETRIEVE = "SourceFileOIDRetrieve";
 	
 	protected SimpleCollectionDatabase coll_db = null;
-	
-	/** constructor */
-	public ArchiveRetrieve()
-	{
-	}
 
 	/** configure this service */
 	public boolean configure(Element info, Element extra_info)
 	{
-		if (!super.configure(info, extra_info)){
+		if (!super.configure(info, extra_info))
+		{
 			return false;
 		}
@@ -60,8 +55,18 @@
 		this.config_info = info;
 		
-		Element archiveFilePathRetrieveService = this.doc.createElement(GSXML.SERVICE_ELEM);
-		archiveFilePathRetrieveService.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
-		archiveFilePathRetrieveService.setAttribute(GSXML.NAME_ATT, ARCHIVE_FILE_PATH_RETRIEVE_SERVICE);
-		this.short_service_info.appendChild(archiveFilePathRetrieveService);
+		Element documentFilePathRetrieveService = this.doc.createElement(GSXML.SERVICE_ELEM);
+		documentFilePathRetrieveService.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
+		documentFilePathRetrieveService.setAttribute(GSXML.NAME_ATT, DOCUMENT_FILE_PATH_RETRIEVE_SERVICE);
+		this.short_service_info.appendChild(documentFilePathRetrieveService);
+		
+		Element associatedImportFilesRetrieveService = this.doc.createElement(GSXML.SERVICE_ELEM);
+		associatedImportFilesRetrieveService.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
+		associatedImportFilesRetrieveService.setAttribute(GSXML.NAME_ATT, ASSOCIATED_IMPORT_FILES_RETRIEVE_SERVICE);
+		this.short_service_info.appendChild(associatedImportFilesRetrieveService);
+		
+		Element sourceFileDocIDRetrieveService = this.doc.createElement(GSXML.SERVICE_ELEM);
+		sourceFileDocIDRetrieveService.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
+		sourceFileDocIDRetrieveService.setAttribute(GSXML.NAME_ATT, SOURCE_FILE_OID_RETRIEVE);
+		this.short_service_info.appendChild(sourceFileDocIDRetrieveService);
 		
 		return true;
@@ -70,15 +75,33 @@
 	protected Element getServiceDescription(String service_id, String lang, String subset) 
 	{
-		Element service_elem = this.doc.createElement(GSXML.SERVICE_ELEM);
-		service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
-		service_elem.setAttribute(GSXML.NAME_ATT, ARCHIVE_FILE_PATH_RETRIEVE_SERVICE);
-		return service_elem;
-	}
-	
-	protected Element processArchiveFilePathRetrieve(Element request)
+		if (service_id.equals(DOCUMENT_FILE_PATH_RETRIEVE_SERVICE)) 
+		{
+			Element service_elem = this.doc.createElement(GSXML.SERVICE_ELEM);
+			service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
+			service_elem.setAttribute(GSXML.NAME_ATT, DOCUMENT_FILE_PATH_RETRIEVE_SERVICE);
+			return service_elem;
+		}
+		else if (service_id.equals(ASSOCIATED_IMPORT_FILES_RETRIEVE_SERVICE)) 
+		{
+			Element service_elem = this.doc.createElement(GSXML.SERVICE_ELEM);
+			service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
+			service_elem.setAttribute(GSXML.NAME_ATT, ASSOCIATED_IMPORT_FILES_RETRIEVE_SERVICE);
+			return service_elem;
+		}
+		else if (service_id.equals(SOURCE_FILE_OID_RETRIEVE))
+		{
+			Element service_elem = this.doc.createElement(GSXML.SERVICE_ELEM);
+			service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
+			service_elem.setAttribute(GSXML.NAME_ATT, SOURCE_FILE_OID_RETRIEVE);
+			return service_elem;
+		}
+		return null;
+	}
+	
+	protected Element processDocumentFilePathRetrieve(Element request)
 	{
 		// Create a new (empty) result message
 		Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
-		result.setAttribute(GSXML.FROM_ATT, ARCHIVE_FILE_PATH_RETRIEVE_SERVICE);
+		result.setAttribute(GSXML.FROM_ATT, DOCUMENT_FILE_PATH_RETRIEVE_SERVICE);
 		result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
 		
@@ -89,13 +112,13 @@
 		Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
 		if (param_list == null) {
-			GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: missing "+ GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
+			GSXML.addError(this.doc, result, "DocumentFilePathRetrieve: missing "+ GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
 			return result;  
 		}
 		HashMap params = GSXML.extractParams(param_list, false);
 		
-		String docID = (String) params.get("docID");
+		String oid = (String) params.get("oid");
 		String collection = (String) params.get("c");
 		
-		String assocFilePath = getAssocFilePathFromDocID(docID, collection, lang, uid);
+		String assocFilePath = getAssocFilePathFromDocID(oid, collection, lang, uid);
 		
 		String docFilePath = this.site_home + File.separatorChar + 
@@ -105,58 +128,171 @@
 			assocFilePath + File.separatorChar + 
 			"doc.xml";
-		
-		Element metaElem = this.doc.createElement(GSXML.METADATA_ELEM);
-		metaElem.setAttribute("name", "docFilePath");
-		metaElem.setAttribute("value", docFilePath);
-		
-		logger.error("DOCFILEPATH = " + docFilePath);
-		
-		result.appendChild(metaElem);
+
+		Element metadataList = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
+		metadataList.appendChild(createMetadataElement("docfilepath", docFilePath));
+		result.appendChild(metadataList);
 		
 		return result;
 	}
 	
-	protected Element processArchiveAssociatedImportFilesRetrieve(Element request)
-	{
-		// find out what kind of database we have
-		//Element database_type_elem = (Element) GSXML.getChildByTagName(this.config_info, GSXML.DATABASE_TYPE_ELEM);
-		//String database_type = "jdbm";
-		/*if (database_type_elem != null) {
-			database_type = database_type_elem.getAttribute(GSXML.NAME_ATT);
-		}
-		if (database_type == null || database_type.equals("")) {
-			database_type = "gdbm"; // the default
-		}
-		
-		String db_ext = null;
-		if (database_type.equalsIgnoreCase("jdbm")) {
-			db_ext = ".jdb";
-		} else {
-			db_ext = ".gdb"; // assume gdbm
-		}
-		
-		
-				coll_db = new SimpleCollectionDatabase(database_type);
-		if (!coll_db.databaseOK()) {
-			logger.error("Couldn't create the collection database of type "+database_type);
+	protected Element processSourceFileOIDRetrieveService(Element request)
+	{
+		//Create a new (empty) result message
+		Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
+		result.setAttribute(GSXML.FROM_ATT, SOURCE_FILE_OID_RETRIEVE);
+		result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
+		
+		String lang = request.getAttribute(GSXML.LANG_ATT);
+		String uid = request.getAttribute(GSXML.USER_ID_ATT);
+		
+		// Get the parameters of the request
+		Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+		if (param_list == null) 
+		{
+			GSXML.addError(this.doc, result, "DocumentFilePathRetrieve: missing "+ GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
+			return result;  
+		}
+		HashMap params = GSXML.extractParams(param_list, false);
+		
+		String srcFile = (String) params.get("srcfile");
+		String collection = (String) params.get("c");
+		
+		//Find out what kind of database we have
+		String databaseType = getDatabaseTypeFromCollection(collection, lang, uid);
+		if (databaseType == null || databaseType.equals("")) 
+		{
+			databaseType = "gdbm"; // the default
+		}
+		
+		String dbExt = null;
+		if (databaseType.equalsIgnoreCase("jdbm")) 
+		{
+			dbExt = ".jdb";
+		} 
+		else 
+		{
+			dbExt = ".gdb"; // assume gdbm
+		}
+		
+		coll_db = new SimpleCollectionDatabase(databaseType);
+		if (!coll_db.databaseOK()) 
+		{
+			logger.error("Couldn't create the collection database of type "+databaseType);
 			return null;
 		}
-		*/
-	
-			/*coll_db.openDatabase(
+
+		coll_db.openDatabase
+		(
 			this.site_home + File.separatorChar + 
 			"collect" + File.separatorChar +
 			collection + File.separatorChar + 
 			"archives" + File.separatorChar + 
-			"archiveinf-doc" + db_ext, 
-			SimpleCollectionDatabase.READ);
-		
-		logger.error("STUFF " + coll_db.getInfo(docID));
-		
-		coll_db.getInfo(docID);*/
-		return null;
-	}
-	
-	public String getAssocFilePathFromDocID(String docID, String collection, String lang, String uid)
+			"archiveinf-src" + dbExt, 
+			SimpleCollectionDatabase.READ
+		);
+		
+		DBInfo info = coll_db.getInfo(srcFile);
+		
+		if (info == null)
+		{
+			return result;
+		}
+		
+		String oid = info.getInfo("oid");
+		
+		Element metadataList = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
+		metadataList.appendChild(createMetadataElement("oid", oid));
+		result.appendChild(metadataList);
+		
+		return result;
+	}
+	
+	protected Element processAssociatedImportFilesRetrieve(Element request)
+	{
+		//Create a new (empty) result message
+		Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
+		result.setAttribute(GSXML.FROM_ATT, ASSOCIATED_IMPORT_FILES_RETRIEVE_SERVICE);
+		result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
+		
+		String lang = request.getAttribute(GSXML.LANG_ATT);
+		String uid = request.getAttribute(GSXML.USER_ID_ATT);
+		
+		// Get the parameters of the request
+		Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+		if (param_list == null) 
+		{
+			GSXML.addError(this.doc, result, "AssociatedImportFilesRetrieve: missing "+ GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
+			return result;  
+		}
+		HashMap params = GSXML.extractParams(param_list, false);
+		
+		String oid = (String) params.get("oid");
+		String collection = (String) params.get("c");
+		
+		String databaseType = getDatabaseTypeFromCollection(collection, lang, uid);
+		if (databaseType == null || databaseType.equals("")) 
+		{
+			databaseType = "gdbm"; // the default
+		}
+		
+		String dbExt = null;
+		if (databaseType.equalsIgnoreCase("jdbm")) 
+		{
+			dbExt = ".jdb";
+		} 
+		else 
+		{
+			dbExt = ".gdb"; // assume gdbm
+		}
+		
+		coll_db = new SimpleCollectionDatabase(databaseType);
+		if (!coll_db.databaseOK()) 
+		{
+			logger.error("Couldn't create the collection database of type "+databaseType);
+			return null;
+		}
+
+		coll_db.openDatabase
+		(
+			this.site_home + File.separatorChar + 
+			"collect" + File.separatorChar +
+			collection + File.separatorChar + 
+			"archives" + File.separatorChar + 
+			"archiveinf-doc" + dbExt, 
+			SimpleCollectionDatabase.READ
+		);
+		
+		DBInfo info = coll_db.getInfo(oid);
+		
+		if (info == null)
+		{
+			return result;
+		}
+		
+		String srcFile = info.getInfo("src-file");
+		Vector data = info.getMultiInfo("assoc-file");
+		
+		Element metadataList = this.doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
+		metadataList.appendChild(createMetadataElement("srcfile", srcFile));
+		
+		for (int i = 0; i < data.size(); i++)
+		{
+			metadataList.appendChild(createMetadataElement("assocfile", (String)data.get(i)));
+		}
+		
+		result.appendChild(metadataList);
+		
+		return result;
+	}
+	
+	public Element createMetadataElement(String name, String value)
+	{
+		Element metaElem = this.doc.createElement(GSXML.METADATA_ELEM);
+		metaElem.setAttribute("name", name);
+		metaElem.setAttribute("value", value);
+		return metaElem;
+	}
+	
+	public String getAssocFilePathFromDocID(String oid, String collection, String lang, String uid)
 	{
 		Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
@@ -165,17 +301,13 @@
 		
 		Element paramList = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-
-		Element assocParam = this.doc.createElement(GSXML.PARAM_ELEM);
-		assocParam.setAttribute("name", "metadata");
-		assocParam.setAttribute("value", "assocfilepath");
-		paramList.appendChild(assocParam);
+		paramList.appendChild(createMetadataElement("metadata", "assocfilepath"));
 		
 		mr_query_request.appendChild(paramList);
 
-		Element docList = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
-		Element doc = this.doc.createElement(GSXML.DOC_NODE_ELEM);
-		doc.setAttribute(GSXML.NODE_ID_ATT, docID);
-		docList.appendChild(doc);
-		mr_query_request.appendChild(docList);
+		Element docListElem = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
+		Element docElem = this.doc.createElement(GSXML.DOC_NODE_ELEM);
+		docElem.setAttribute(GSXML.NODE_ID_ATT, oid);
+		docListElem.appendChild(docElem);
+		mr_query_request.appendChild(docListElem);
 
 		Element response = (Element) this.router.process(mr_query_message);
@@ -189,3 +321,21 @@
 		return metadataElem.getFirstChild().getNodeValue();
 	}
+	
+	public String getDatabaseTypeFromCollection(String collection, String lang, String uid)
+	{
+		//Find out what kind of database we have
+		Element dbTypeMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
+		Element dbTypeRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, collection, lang, uid);
+		dbTypeMessage.appendChild(dbTypeRequest);
+		Element dbTypeResponse = (Element)this.router.process(dbTypeMessage);
+		
+		String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.COLLECTION_ELEM);
+		Element collectionElem = (Element) GSXML.getNodeByPath(dbTypeResponse, path);
+		
+		if (collectionElem != null)
+		{
+			return collectionElem.getAttribute(GSXML.DB_TYPE_ATT);
+		}
+		return null;
+	}
 }   
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/BerryBasket.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/BerryBasket.java	(revision 24220)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/BerryBasket.java	(revision 24221)
@@ -287,6 +287,4 @@
 	// Get the parameters of the request
 	Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-        
-        //GSXML.printXMLNode(param_list);
 
 	if (param_list == null) {
@@ -336,6 +334,4 @@
 	// Get the parameters of the request
 	Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-        
-        //GSXML.printXMLNode(param_list);
 
 	if (param_list == null) {
@@ -375,5 +371,4 @@
 
     protected Element processItemNum(Element request){
-        // GSXML.printXMLNode(request);
 	Hashtable docsMap = updateDocMap(request);
 
@@ -489,6 +484,4 @@
 		// Get the parameters of the request
 		Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-		
-		GSXML.printXMLNode(param_list);
 		
 		if (param_list == null) {
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java	(revision 24220)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java	(revision 24221)
@@ -85,4 +85,5 @@
   public static final String DOC_TYPE_ELEM = "docType";
   public static final String SEARCH_ELEM = "search";
+  public static final String INFODB_ELEM = "infodb";
   public static final String INDEX_ELEM = "index";
   public static final String INDEX_STEM_ELEM = "indexStem";
@@ -125,4 +126,5 @@
   public static final String LANG_ATT = "lang";
   public static final String TYPE_ATT = "type";
+  public static final String DB_TYPE_ATT = "dbType";
   public static final String VALUE_ATT = "value";
   public static final String DEFAULT_ATT = "default";
@@ -920,6 +922,6 @@
   }
   
-  public static void printXMLNode(Node e) {
-    printXMLNode(e, 0) ;
+  public static void printXMLNode(Node e, boolean printText) {
+    printXMLNode(e, 0, printText) ;
   }
   
@@ -977,12 +979,18 @@
   }
   
-  public static void printXMLNode(Node e, int depth) { //recursive method call using DOM API...
-    
+  public static void printXMLNode(Node e, int depth, boolean printText) { //recursive method call using DOM API...
+    
+	if(e == null){return;}
+	
     for (int i=0 ; i<depth ; i++)
       System.out.print(' ') ;
     
     if (e.getNodeType() == Node.TEXT_NODE){
-      // shouldn't we actually print the text here????
-      System.out.println("text") ;
+      if(printText){
+        System.out.println(e.getNodeValue());
+	  }
+	  else {
+        System.out.println("text");
+	  }
       return ;
     }
@@ -1014,5 +1022,5 @@
       int len = children.getLength();
       for (int i = 0; i < len; i++) {
-        printXMLNode(children.item(i), depth + 1);
+        printXMLNode(children.item(i), depth + 1, printText);
       }
       
