Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/action/Action.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/action/Action.java	(revision 9264)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/action/Action.java	(revision 9874)
@@ -52,7 +52,11 @@
     public String process(String xml_in) {
        
-	Element message = this.converter.getDOM(xml_in).getDocumentElement();
-	
-	Element result = process(message);
+	Document message_doc = this.converter.getDOM(xml_in);
+	if (message_doc == null) {
+	    System.err.println("Action.process(String) Error: Couldn't parse request");
+	    System.err.println(xml_in);
+	    return null;
+	}
+	Element result = process(message_doc.getDocumentElement());
 	return this.converter.getString(result);
     }
@@ -115,4 +119,15 @@
     }
 
+    protected boolean processErrorElements(Element message, Element page) {
+	NodeList error_nodes = message.getElementsByTagName(GSXML.ERROR_ELEM);
+	if (error_nodes.getLength()==0) {
+	    return false;
+	}
+	Document owner = page.getOwnerDocument();
+	for (int i=0; i<error_nodes.getLength(); i++) {
+	    page.appendChild(owner.importNode(error_nodes.item(i), true));
+	}
+	return true;
+    }
 }
 
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/action/DocumentAction.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/action/DocumentAction.java	(revision 9264)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/action/DocumentAction.java	(revision 9874)
@@ -209,5 +209,8 @@
 	    // Process the document structure retrieve message
 	    Element ds_response_message = (Element) this.mr.process(ds_message);
-	    
+	    if (processErrorElements(ds_response_message, page_response)) {
+		return result;
+	    }
+
 	    // get the info and print out
 	    String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
@@ -309,4 +312,7 @@
 	doc_list.appendChild(doc_node);
 	Element dm_response_message = (Element) this.mr.process(dm_message);
+	if (processErrorElements(dm_response_message, page_response)) {
+	    return result;
+	}
 
 	String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
@@ -348,4 +354,8 @@
 	System.err.println("request = "+converter.getString(dc_message));
 	Element dc_response_message = (Element) this.mr.process(dc_message);
+	if (processErrorElements(dc_response_message, page_response)) {
+	    return result;
+	}
+
 	Element dc_response_doc_list = (Element) GSXML.getNodeByPath(dc_response_message, path);
 
@@ -536,6 +546,9 @@
 	HashMap params = GSXML.extractParams(cgi_param_list, false);
 	
-	
-	String service_name = (String)((HashMap)params.get("p")).get(GSParams.SERVICE);
+	HashMap previous_params = (HashMap)params.get("p");
+	if (previous_params == null) {
+	    return dc_response_doc_content;
+	}
+       	String service_name = (String)previous_params.get(GSParams.SERVICE);
 	if (service_name == null || !service_name.endsWith("Query")) { // hack for now - we only do highlighting if we were in a query last - ie not if we were in a browse thingy
 	    System.err.println("DocumentAction: invalid service, not doing highlighting");
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/action/GS2BrowseAction.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/action/GS2BrowseAction.java	(revision 9264)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/action/GS2BrowseAction.java	(revision 9874)
@@ -126,10 +126,11 @@
 	    horizontal_at_top = true;
 	}
-	if (top_id.equals(classifier_node) && horizontal_at_top) {
+	// *** TODO need to fix this
+	//if (top_id.equals(classifier_node) && horizontal_at_top) {
 	    // we have asked for a top node - if the first list is horizontal, we will select the first element of that list
-	    // this is a hack. also it craps out if the classifier really isn't horizontalAtTop.
-	    classifier_node = classifier_node+".1";
+	    // this is a hack. also it craps out if the classifier really isn't horizontalAtTop. - 
+	    //classifier_node = classifier_node+".1";
 		    
-	}
+	//}
 
 	// get the browse structure for the selected node
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/action/QueryAction.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/action/QueryAction.java	(revision 9264)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/action/QueryAction.java	(revision 9874)
@@ -60,30 +60,86 @@
 	String to = GSPath.appendLink(collection, service_name);
 	
-	// part of the response is the service description 
-	// for now get this again from the service. 
-	// this will probably need to be cached somehow later on. 
-	Element mr_info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
-	Element mr_info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE,  to, lang, uid);
-	mr_info_message.appendChild(mr_info_request);
-
+	if (request_type.indexOf("d")!=-1) {
+	    // we have been asked for the service description
+	    Element mr_info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
+	    Element mr_info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE,  to, lang, uid);
+	    mr_info_message.appendChild(mr_info_request);
+	    
+	    // process the message
+	    Element mr_info_response = (Element) this.mr.process(mr_info_message);
+	    // the response
+	    Element service_response = (Element)GSXML.getChildByTagName(mr_info_response, GSXML.RESPONSE_ELEM);
+	    
+	    Element service_description = (Element)this.doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true);
+	    page_response.appendChild(service_description);
+	}
+	
+	if (request_type.indexOf("r") == -1) {
+	    // just a display request, no actual processing to do
+	    return page_response;
+	}
+	
+	// check that we have some service params
+	HashMap service_params = (HashMap)params.get("s1");
+	if (service_params == null) { // no query
+	    return page_response;
+	}
+
+	// create the query request
+	Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
+	Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
+	mr_query_message.appendChild(mr_query_request);
+	
+	Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
+	GSXML.addParametersToList(this.doc, query_param_list, service_params);
+	mr_query_request.appendChild(query_param_list);
+	
 	// also get the format stuff now if there is some
 	Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid);
-	mr_info_message.appendChild(format_request);
-
-	// process the messages
-	Element mr_info_response = (Element) this.mr.process(mr_info_message);
-	
-	// the two responses
-	NodeList responses = mr_info_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
-	Element service_response = (Element)responses.item(0);
-	Element format_response = (Element)responses.item(1);
-	
-	Element service_description = (Element)this.doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true);
-	page_response.appendChild(service_description);
-	
-	if (request_type.equals("d")) {// just a display request
-	    return page_response;
-	}
-	
+	mr_query_message.appendChild(format_request);
+
+	// do the query
+       	Element mr_query_response = (Element)this.mr.process(mr_query_message);
+
+	// check for errors
+	if (processErrorElements(mr_query_response, page_response)) {
+	    return page_response;
+	}
+	
+	NodeList responses = mr_query_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
+	Element query_response = (Element) responses.item(0);
+	Element format_response = (Element) responses.item(1);
+	
+	Element query_result_metadata_list = (Element) GSXML.getChildByTagName(query_response, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+	if (query_result_metadata_list == null) {
+	    System.err.println("QueryAction: Warning: No query result metadata.\n");
+	} else { // add it into the page response
+	    page_response.appendChild(this.doc.importNode(query_result_metadata_list, true)); 
+	}
+	
+	Element query_term_info_list = (Element) GSXML.getChildByTagName(query_response, GSXML.TERM_ELEM+GSXML.LIST_MODIFIER);
+	if (query_term_info_list == null) {
+	    System.err.println("QueryAction: Warning: No query term information.\n");
+	} else { // add it into the page response
+	    page_response.appendChild(this.doc.importNode(query_term_info_list, true));
+	}
+	
+	// check that there are some documents - for now check the list, but later should use a numdocs metadata elem	
+	Element document_list = (Element)GSXML.getChildByTagName(query_response, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
+	// documentList not present if no docs found
+	if (document_list == null) {
+	    return page_response;
+	}
+
+	// now we check to see if there is metadata already - some search services return predefined metadata. if there is some, don't do a metadata request
+	NodeList doc_metadata = document_list.getElementsByTagName(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+	if (doc_metadata.getLength()>0) {
+	    System.err.println("have already found metadata!");
+	    // append the doc list to the result
+	    page_response.appendChild(this.doc.importNode(document_list, true));
+	    return page_response;
+	}
+	
+	// get the metadata elements needed from the format statement if any
 	HashSet metadata_names = new HashSet();
 	metadata_names.add("Title");
@@ -98,69 +154,8 @@
 	    extractMetadataNames(format_elem, metadata_names);
 	} 
-
-	// do the query
-	Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
-	Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
-	mr_query_message.appendChild(mr_query_request);
-	
-	// paramList
-	HashMap service_params = (HashMap)params.get("s1");
-	if (service_params == null) { // no query
-	    return page_response;
-	}
-	Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
-	GSXML.addParametersToList(this.doc, query_param_list, service_params);
-	///ystem.out.println("service params are "+this.converter.getString(query_param_list));
-	mr_query_request.appendChild(query_param_list);
-
-	// do the query
-       	Element mr_query_response = (Element)this.mr.process(mr_query_message);
-
-	//. check for errors
-	String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.ERROR_ELEM);
-	Element error_elem = (Element) GSXML.getNodeByPath(mr_query_response, path);
-	if (error_elem != null) {
-	    // should we continue?? perhaps have a kind of error - information vs fatal??
-	    System.err.println("found an error elem");
-	    page_response.appendChild(this.doc.importNode(error_elem, true));
-	    return page_response;
-	}
-	path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-	Element query_result_metadata_list = (Element) GSXML.getNodeByPath(mr_query_response, path);
-	if (query_result_metadata_list == null) {
-	    System.err.println("QueryAction: Warning: No query result metadata.\n");
-	} else { // add it into the page response
-	    page_response.appendChild(this.doc.importNode(query_result_metadata_list, true)); 
-	}
-	
-	path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.TERM_ELEM+GSXML.LIST_MODIFIER);
-	Element query_term_info_list = (Element) GSXML.getNodeByPath(mr_query_response, path);
-	if (query_term_info_list == null) {
-	    System.err.println("QueryAction: Warning: No query term information.\n");
-	} else { // add it into the page response
-	    page_response.appendChild(this.doc.importNode(query_term_info_list, true));
-	}
-
-	// check that there are some documents - for now check the list, but later should use a numdocs metadata elem
-	path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
-	
-	Element document_list = (Element)GSXML.getNodeByPath(mr_query_response,
-							     path); 
-	// documentList not present if no docs found
-	if (document_list == null) {
-	    return page_response;
-	}
 	
 	// paging of the results is done here - we filter the list to remove unwanted entries before retrieving metadata
-	Element filtered_doc_list = filterDocList(params, service_description, document_list);
-	
-	// now we check to see if there is metadata already - some search services return predefined metadata. if there is some, don't do a metadata request
-	NodeList doc_metadata = document_list.getElementsByTagName(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-	if (doc_metadata.getLength()>0) {
-	    System.err.println("have already found metadata!");
-	    // append the doc list to the result
-	    page_response.appendChild(this.doc.importNode(document_list, true));
-	    return page_response;
-	}
+	Element filtered_doc_list = filterDocList(params, service_params, document_list);
+	
 	// do the metadata request on the filtered list
 	Element mr_metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
@@ -176,38 +171,34 @@
 	mr_metadata_request.appendChild(dm_param_list);
 	
-	
 	// add in the doc node list too
 	mr_metadata_request.appendChild(filtered_doc_list);
 
 	Element mr_metadata_response = (Element) this.mr.process(mr_metadata_message);	
-	
-	path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
-	Element query_result_document_list = (Element) GSXML.getNodeByPath(mr_metadata_response, path);
-
+	// check for errors
+	processErrorElements(mr_metadata_response, page_response);
+	
+	Element metadata_response = (Element) GSXML.getChildByTagName(mr_metadata_response, GSXML.RESPONSE_ELEM);
+
+	Element query_result_document_list = (Element) GSXML.getChildByTagName(metadata_response, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
+	
 	if (query_result_document_list != null) {
 	    page_response.appendChild(this.doc.importNode(query_result_document_list, true));
 	}
-
-	System.out.println("Query page:\n" + this.converter.getPrettyString(page_response));
+	
+	///ystem.out.println("Query page:\n" + this.converter.getPrettyString(page_response));
 	return page_response;
     }
 
     /** this filters out some of the doc results for result paging */
-    protected Element filterDocList(HashMap params, Element service_description, Element orig_doc_list) {
-	
-	// check in the service descripiton to see if hitsPerpage is a param
-	Element service_p_list = (Element)GSXML.getChildByTagName(service_description, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	Element hits_param = GSXML.getNamedElement(service_p_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, "hitsPerPage");
-	
-	boolean service_paging = false;
-	if (hits_param != null) {
-	    service_paging = true;
-	}
-	if (service_paging) {
-	    // the service is doing the paging, so we want to display all of teh returned docs
+    protected Element filterDocList(HashMap params, HashMap service_params, Element orig_doc_list) {
+	
+	// check the hits_per_page param - is it a service param??
+	String hits_pp = (String) service_params.get("hitsPerPage");
+	if (hits_pp != null) {
+	    // the service is doing the paging, so we want to display all of the returned docs
 	    return (Element)this.doc.importNode(orig_doc_list, true);
 	}
 	
-	String hits_pp = (String)params.get("hitsPerPage");
+	hits_pp = (String)params.get("hitsPerPage");
 	int hits = 20;
 	if (hits_pp != null && !hits_pp.equals("")) {
