Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GS2MacroResolver.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GS2MacroResolver.java	(revision 23790)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GS2MacroResolver.java	(revision 23791)
@@ -24,4 +24,9 @@
 import java.net.URLDecoder;
 
+// Apache Commons
+import org.apache.commons.lang3.*;
+
+import java.util.Stack;
+
 public class GS2MacroResolver 
     extends MacroResolver
@@ -29,4 +34,6 @@
 
     protected SimpleCollectionDatabase coll_db = null;
+
+    private static Pattern p_back_slash = Pattern.compile("\\\"");// create a pattern "\\\"", but it matches both " and \"
     
     // need to make it not add macros if they are already present
@@ -58,5 +65,5 @@
 	} 
 
-	ArrayList macros;
+	Stack macros;//ArrayList macros;
 	if (scope.equals(SCOPE_TEXT)) {
 	    macros = text_macros;
@@ -64,7 +71,8 @@
 	    macros = metadata_macros;
 	}
-	for (int i=0; i<macros.size(); i++) {
+	//for (int i=0; i<macros.size(); i++) {
+	while(!macros.empty()) {
 	    String new_text = null;
-	    Macro m = (Macro)macros.get(i);
+	    Macro m = (Macro)macros.pop();//.get(i);
 	    switch (m.type) {
 	    case TYPE_DICT:
@@ -76,5 +84,5 @@
 		// otherwise we can't cache the answer because it might be 
 		// document specific
-		text = text.replaceAll(m.macro, m.text);
+		text = StringUtils.replace(text, m.macro, m.text);
 		break;
 	    case TYPE_TEXT:
@@ -83,7 +91,11 @@
 		// doesn't necessarily match line breaks
 		//if (text.matches("(?s).*"+m.macro+".*")) {
-		Pattern p_text = Pattern.compile(".*" + m.macro + ".*",Pattern.DOTALL);
-		Matcher match_text = p_text.matcher(text);
-		if (match_text.matches()) {
+		
+		/*Pattern p_text = Pattern.compile(".*" + m.macro + ".*",Pattern.DOTALL);
+		Matcher match_text = p_text.matcher(text);*/
+
+		// sm252
+		// String.contains is far faster than regex!
+		if (text.contains(m.macro)) { //match_text.matches()) { //text.matches("(?s).*"+m.macro+".*")) {
 		    if (m.resolve) {
 			new_text = this.resolve(m.text, lang, scope, doc_oid);
@@ -91,7 +103,7 @@
 			new_text = m.text;
 		    }
-		    text = text.replaceAll(m.macro, new_text);
+		    text = StringUtils.replace(text, m.macro, new_text);
 		    if (m.macro.endsWith("\\\\")){ // to get rid of "\" from the string likes: "src="http://www.greenstone.org:80/.../mw.gif\">"
-			Pattern p_back_slash = Pattern.compile("\\\"");// create a pattern "\\\"", but it matches both " and \"
+			
 			Matcher m_slash = p_back_slash.matcher(text);
 			String clean_str = "";
@@ -111,7 +123,8 @@
 		break;
 	    case TYPE_META:
-		Pattern p = Pattern.compile(".*" + m.macro + ".*",Pattern.DOTALL);
-		Matcher match = p.matcher(text);
-		if (match.matches()) {
+		//Pattern p = Pattern.compile(".*" + m.macro + ".*",Pattern.DOTALL);
+		//Matcher match = p.matcher(text);
+		// sm252
+		if (text.contains(m.macro)) { //(match.matches()) { //text.matches("(?s).*"+m.macro+".*")) {
 		    if (node_info == null) {
 			node_info = coll_db.getInfo(doc_oid);
@@ -133,5 +146,5 @@
 			    new_text = this.resolve(new_text, lang, scope, doc_oid);
 			}
-			text = text.replaceAll(m.macro, new_text);
+			text =  StringUtils.replace(text, m.macro, new_text);
 		    }
 		    
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSConstants.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSConstants.java	(revision 23790)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSConstants.java	(revision 23791)
@@ -27,5 +27,5 @@
     public static final String LIBRARY_NAME = "library_name";
     public static final String DEFAULT_LANG = "default_lang";
-
+	public static final String ALLOW_CLIENT_SIDE_XSLT = "allow_client_side_xslt";
 
     public static final String META_RELATION_SEP = "_";
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java	(revision 23790)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java	(revision 23791)
@@ -264,8 +264,12 @@
   }
   
+  public static HashMap extractParams(Element xml, boolean deep) {
+	return extractParams(xml, deep, null);
+  }
+
   /** takes a paramList element, and gets a HashMap of name-value pairs
    * if deep=true, extracts embedded params, otherwise just top level
    * params*/
-  public static HashMap extractParams(Element xml, boolean deep) {
+  public static HashMap extractParams(Element xml, boolean deep, String toFind) {
     
     if (!xml.getNodeName().equals(PARAM_ELEM+LIST_MODIFIER)) {
@@ -286,4 +290,13 @@
         String name=param.getAttribute(NAME_ATT);
         String value=getValue(param); //att or content
+
+	// For only one parameter
+	if(toFind != null && name.equals(toFind)) {
+		param_map.put(name, value);
+		return param_map;
+	}		
+	else if(toFind != null)
+		continue;
+
         int pos = name.indexOf('.');
         if (pos == -1) { // a base param
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java	(revision 23790)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java	(revision 23791)
@@ -21,4 +21,6 @@
 import org.apache.log4j.*;
 
+import org.apache.commons.lang3.StringUtils;
+
 public class SimpleCollectionDatabase implements OID.OIDTranslatable {
   
@@ -104,5 +106,5 @@
     DBInfo info = new DBInfo();
     
-    String [] lines = key_info.split("\n");
+    String [] lines = StringUtils.split(key_info, "\n");
     String key;
     String value;
@@ -193,6 +195,6 @@
       return top;
     }
-    contains = contains.replaceAll("\"", doc_id);
-    String [] children = contains.split(";");
+    contains = StringUtils.replace(contains, "\"", doc_id);
+    String [] children = StringUtils.split(contains, ";");
     if (suff.equals("fc")) {
       return children[0];
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLConverter.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLConverter.java	(revision 23790)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLConverter.java	(revision 23791)
@@ -41,6 +41,13 @@
 import java.io.FileInputStream;
 import java.io.FileReader;
+import java.util.regex.*;
 
 import org.apache.log4j.*;
+
+// Apache Commons
+import org.apache.commons.lang3.*;
+
+import java.util.*;
+import java.lang.reflect.*;
 
 /** XMLConverter - utility class for greenstone
@@ -59,5 +66,4 @@
 
     private static boolean outputEscaping = true;
-
 
      /** the no-args constructor */
@@ -216,4 +222,15 @@
     }
 
+    /* For the purposes of logger.debug statements, where this is called and hence outputted,
+	returns an empty string if debugging is not enabled */
+    public static String getPrettyStringLogger(Node xmlNode, Logger log) {
+
+	if(log.isDebugEnabled())
+		return getPrettyString(xmlNode);
+	
+	return "";
+
+    }
+
     private static void getString(Node xmlNode, StringBuffer xmlRepresentation, 
 			     int depth, boolean pretty)
@@ -242,5 +259,6 @@
 		String sid  = dt.getSystemId();
 		
-		String doctype_str = "<!DOCTYPE " + dt.getName() + " PUBLIC \"" + pid + "\" \"" + sid + "\">\n";
+		// Use previously assigned name, not dt.getName() again
+		String doctype_str = "<!DOCTYPE " + name + " PUBLIC \"" + pid + "\" \"" + sid + "\">\n";
 		
 		xmlRepresentation.append(doctype_str);
@@ -321,14 +339,17 @@
 
 	    // Perform output escaping, if required
+	    // Apache Commons replace method is far superior to String.replaceAll - very fast!
 	    if (outputEscaping) {
-		text = text.replaceAll("&", "&amp;");  // Must be done first!!
-		text = text.replaceAll("<", "&lt;");
-		text = text.replaceAll(">", "&gt;");
-		text = text.replaceAll("\"", "&quot;");
-		text = text.replaceAll("\'", "&apos;");
+
+		text = StringUtils.replace(text, "&", "&amp;");
+		text = StringUtils.replace(text, "<", "&lt;");
+		text = StringUtils.replace(text, ">", "&gt;");
+		text = StringUtils.replace(text, "'", "&apos;");
+		text = StringUtils.replace(text, "\"", "&quot;");
 	    }
 
 	    // Remove any control-C characters
-	    text = text.replaceAll("" + (char) 3, "");
+	    text = StringUtils.replace(text, "" + (char)3, "");
+
 	    xmlRepresentation.append(text);
 	}
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java	(revision 23790)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java	(revision 23791)
@@ -28,4 +28,6 @@
 import org.w3c.dom.Node; 
 
+import org.apache.commons.lang3.StringUtils;
+
 /** a class to contain various static methods that are used by the xslt
  * stylesheets
@@ -88,5 +90,5 @@
 
     public static String getNumberedItem(String list, int number) {
-	String [] items = list.split(",", -1);	
+	String [] items = StringUtils.split(list, ",", -1);	
 	if (items.length > number) {
 	    return items[number];
@@ -112,5 +114,5 @@
 	String [] args = null;
 	if (args_str!=null && !args_str.equals("")) {
-	    args = args_str.split(";");
+	    args = StringUtils.split(args_str, ";");
 	}
 	Dictionary dict = new Dictionary("interface_"+interface_name, lang);
