Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXSLT.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXSLT.java	(revision 25656)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXSLT.java	(revision 25820)
@@ -43,5 +43,8 @@
 	 * takes a stylesheet Document, and adds in any child nodes from extra_xsl
 	 * named templates overwrite any existing one, while match templates are
-	 * just added to the end of teh stylesheet
+	 * just added to the end of the stylesheet
+
+	 * elements are added in following order, and added to preserve original order with imported ones coming after existing ones
+	 * import, include, output, variable, template
 	 */
 	public static void mergeStylesheetsDebug(Document main_xsl, Element extra_xsl, boolean overwrite, boolean debug, String firstDocFileName, String secondDocFileName)
@@ -54,24 +57,20 @@
 
 		Element main = main_xsl.getDocumentElement();
-
-		NodeList children = GSXML.getChildrenByTagName(extra_xsl, "xsl:variable");
-		for (int i = 0; i < children.getLength(); i++)
-		{
-			Node node = children.item(i);
+		Node insertion_point = null;
+		  Element last_import = GSXML.getLastElementByTagNameNS(main, "http://www.w3.org/1999/XSL/Transform", "import");
+		  if (last_import != null) {
+		    insertion_point = last_import.getNextSibling();
+		  } else {
+		    insertion_point = main.getFirstChild();
+		  }
+		
+		// imports
+		NodeList children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "import");
+		for (int i = 0; i < children.getLength(); i++)
+		{
+		  Element node = (Element) children.item(i);
 			// If the new xsl:import element is identical (in terms of href attr value) 
 			// to any in the merged document, don't copy it over
-			if (!isDuplicateElement(main, node, "xsl:variable", "name"))
-			{
-				main.appendChild(main_xsl.importNode(node, true));
-			}
-		}
-
-		children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "import");
-		for (int i = 0; i < children.getLength(); i++)
-		{
-			Node node = children.item(i);
-			// If the new xsl:import element is identical (in terms of href attr value) 
-			// to any in the merged document, don't copy it over
-			if (!isDuplicateElement(main, node, "xsl:import", "href"))
+			if (GSXML.getNamedElementNS(main, "http://www.w3.org/1999/XSL/Transform", "import", "href", node.getAttribute("href")) == null)
 			{
 				// Import statements should be the first children of an xsl:stylesheet element
@@ -79,29 +78,60 @@
 				// Although Node.insertBefore() will first remove identical nodes before inserting, we check
 				// only the href attribute to see if they're "identical" to any pre-existing <xsl:import>
-				main.insertBefore(main_xsl.importNode(node, true), main.getFirstChild());
-			}
-		}
-
+				//main.insertBefore(main_xsl.importNode(node, true), main.getFirstChild());
+			  main.insertBefore(main_xsl.importNode(node, true), insertion_point);
+			  
+			}
+		}
+	
+		  // do we have a new insertion point??
+		   Element last_include = GSXML.getLastElementByTagNameNS(main, "http://www.w3.org/1999/XSL/Transform", "include");
+		   if (last_include != null) {				
+		     insertion_point = last_include.getNextSibling();
+		   }
+	
+		// includes
 		children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "include");
 		for (int i = 0; i < children.getLength(); i++)
 		{
-			Node node = children.item(i);
+		  Element node = (Element)children.item(i);
 			// If the new xsl:include element is identical (in terms of href attr value)
 			// to any in the merged document, don't copy it over
 			// Although Node.appendChild() will first remove identical nodes before appending, we check
 			// only the href attribute to see if they're "identical" to any pre-existing <xsl:include>
-			if (!isDuplicateElement(main, node, "xsl:include", "href"))
-			{
-				main.appendChild(main_xsl.importNode(node, true));
-			}
-		}
-
+			if (GSXML.getNamedElementNS(main, "http://www.w3.org/1999/XSL/Transform", "include", "href", node.getAttribute("href"))==null)
+			{
+			  //main.appendChild(main_xsl.importNode(node, true));
+			  main.insertBefore(main_xsl.importNode(node, true), insertion_point);
+			}
+		} // for each include
+		
+		  // do we have a new insertion point??
+		   Element last_output = GSXML.getLastElementByTagNameNS(main, "http://www.w3.org/1999/XSL/Transform", "output");
+		   if (last_output != null) {				
+		     insertion_point = last_output.getNextSibling();
+		   }
+
+		// outputs
 		children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "output");
 		for (int i = 0; i < children.getLength(); i++)
 		{
-			Node node = children.item(i);
+		  Element node = (Element)children.item(i);
 			// If the new xsl:output element is identical (in terms of the value for the method attr) 
 			// to any in the merged document, don't copy it over
-			if (!isDuplicateElement(main, node, "xsl:output", "method"))
+			if (GSXML.getNamedElementNS(main, "http://www.w3.org/1999/XSL/Transform", "output", "method", node.getAttribute("method"))==null)
+			{
+				main.insertBefore(main_xsl.importNode(node, true), insertion_point);
+			}
+		}
+
+		// variables - only top level ones!!
+		// append to end of document
+		children = GSXML.getChildrenByTagNameNS(extra_xsl, "http://www.w3.org/1999/XSL/Transform", "variable");
+		for (int i = 0; i < children.getLength(); i++)
+		{
+		  Element node = (Element)children.item(i);
+			// If the new xsl:import element is identical (in terms of href attr value) 
+			// to any in the merged document, don't copy it over
+			if (GSXML.getNamedElementNS(main, "http://www.w3.org/1999/XSL/Transform","variable", "name", node.getAttribute("name"))==null)
 			{
 				main.appendChild(main_xsl.importNode(node, true));
@@ -109,21 +139,39 @@
 		}
 
+		// templates
+		// append to end of document
 		children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "template");
 		for (int i = 0; i < children.getLength(); i++)
 		{
-			Node node = children.item(i);
-			// remove any previous occurrences of xsl:template with the same value for name
-			// or even the same value for match (should we use priorities for match?)
+		  Element node = (Element) children.item(i);
+			System.err.println("node name="+node.getNodeName()+", local name="+node.getLocalName()+", uri="+node.getNamespaceURI());
+			// remove any previous occurrences of xsl:template with the same value for name or match 
+			  String template_match = node.getAttribute("match");
+			  String template_name = node.getAttribute("name");
 
 			if (overwrite)
 			{
-				removeDuplicateElementsFrom(main, node, "xsl:template", "name");
-				removeDuplicateElementsFrom(main, node, "xsl:template", "match");
+			  // if we have a name attribute, remove any other similarly named template
+			  if (!template_name.equals("")) {
+			    GSXML.removeNamedElementNS(main, "http://www.w3.org/1999/XSL/Transform", "template", "name", template_name);
+			  }
+			  // if we have a match attribute, remove other templates that match - 
+			  if (!template_match.equals("")) {
+			    GSXML.removeNamedElementsNS(main, "http://www.w3.org/1999/XSL/Transform", "template", "match", template_match);
+			  }
+			  // now add our good template in
+			  main.appendChild(main_xsl.importNode(node, true));
+			}
+			else 
+			  {
+			// if overwrite is false, then we only add in templates if they don't match something else.
+			// In this case (eg from expanding imported stylesheets)
+			// there can't be any duplicate named templates, so just look for matches
+			    // we already have the one with highest import precedence (from the top most level) so don't add any more in
+			    if (GSXML.getNamedElementNS(main, "http://www.w3.org/1999/XSL/Transform","template", "match", template_match) == null)
+			{
 				main.appendChild(main_xsl.importNode(node, true));
 			}
-			else if (!isDuplicateElement(main, node, "xsl:template", "name"))
-			{
-				main.appendChild(main_xsl.importNode(node, true));
-			}
+			  }
 		}
 
@@ -266,38 +314,6 @@
 	}
 
-	// In element main, tries to find any previous occurrence of elements with xsl-template-name=templateName, 
-	// and whose named attribute (attributeName) has the same value as the same attribute in node.
-	// If this is the case, such a previous occurrence is removed from element main, since
-	// the new node will contain a more specific redefinition of this element.
-	public static void removeDuplicateElementsFrom(Element main, Node node, String templateName, String attrName)
-	{
-		String attr = ((Element) node).getAttribute(attrName);
-		if (!attr.equals(""))
-		{
-			Element old_template = GSXML.getNamedElement(main, templateName, attrName, attr);
-			if (old_template != null)
-			{
-				main.removeChild(old_template);
-			}
-		}
-	}
-
-	// Call this method on elements like xsl:include, xsl:import and xsl:output
-	// In element main, tries to find any previous occurrence of elements with xsl-element-name=xslName, 
-	// and whose named attribute (attributeName) has the same value as the same attribute in node.
-	// If this is the case, it returns true, since the element would a complete duplicate for our intents.
-	public static boolean isDuplicateElement(Element main, Node node, String xslName, String attrName)
-	{
-		String attr = ((Element) node).getAttribute(attrName);
-		if (!attr.equals(""))
-		{
-			Element old_element = GSXML.getNamedElement(main, xslName, attrName, attr);
-			if (old_element != null)
-			{
-				return true;
-			}
-		}
-		return false;
-	}
+
+
 
 	/**
