diff --git a/libxslt/imports.c b/libxslt/imports.c
index 9277b4f..4069975 100644
--- a/libxslt/imports.c
+++ b/libxslt/imports.c
@@ -400,19 +400,12 @@ xsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name,
 	return(NULL);
     style = ctxt->style;
     while (style != NULL) {
-	cur = style->templates;
-	while (cur != NULL) {
-	    if (xmlStrEqual(name, cur->name)) {
-		if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
-		    ((nameURI != NULL) && (cur->nameURI != NULL) &&
-		     (xmlStrEqual(nameURI, cur->nameURI)))) {
-		    return(cur);
-		}
-	    }
-	    cur = cur->next;
-	}
-
-	style = xsltNextImport(style);
+        if(style->namedTemplatesHash != NULL){
+            cur = (xsltTemplatePtr) xmlHashLookup2(style->namedTemplatesHash, name, nameURI);
+            if(cur != NULL)
+                return (cur);
+        }
+        style = xsltNextImport(style);
     }
     return(NULL);
 }
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
index 57f8b9f..c81c791 100644
--- a/libxslt/pattern.c
+++ b/libxslt/pattern.c
@@ -2090,7 +2090,22 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
     const xmlChar *name = NULL;
     float priority;              /* the priority */
 
-    if ((style == NULL) || (cur == NULL) || (cur->match == NULL))
+    if ((style == NULL) || (cur == NULL))
+	return(-1);
+
+    /* register named template for future error validation */
+    if (cur->name != NULL && cur->nameURI != NULL){
+        if (style->namedTemplatesHash == NULL ){
+            style->namedTemplatesHash = xmlHashCreate(8);
+        }
+        if (style->namedTemplatesHash == NULL){
+            xmlGenericError(NULL, "malloc failed !\n");
+            return (-1);
+        }
+        xmlHashAddEntry2(style->namedTemplatesHash, cur->name, cur->nameURI, cur);
+    }
+
+    if (cur->match == NULL)
 	return(-1);
 
     priority = cur->priority;
diff --git a/libxslt/xslt.c b/libxslt/xslt.c
index 972a38e..c516778 100644
--- a/libxslt/xslt.c
+++ b/libxslt/xslt.c
@@ -1006,6 +1006,8 @@ xsltFreeStylesheet(xsltStylesheetPtr style)
         xsltFreeAVTList(style->attVTs);
     if (style->imports != NULL)
         xsltFreeStylesheetList(style->imports);
+    if (style->namedTemplatesHash != NULL)
+        xmlHashFree(style->namedTemplatesHash, NULL);
 
 #ifdef XSLT_REFACTORED
     /*
@@ -5133,6 +5135,27 @@ error:
     }
 }
 
+/**
+ * xsltHasNamedTemplate
+ * @style: an XSLT stylesheet
+ * @name: a template name
+ * @URI: a template URI
+ * Returns -1 if the named template was already compiled.
+ * Returns 0 if the template has not been compiled yet.
+ */
+static int
+xsltHasNamedTemplate(xsltStylesheetPtr style,
+                    const xmlChar * name,
+                    const xmlChar * URI){
+    if(style->namedTemplatesHash != NULL){
+        xsltTemplatePtr list = (xsltTemplatePtr)
+                xmlHashLookup2(style->namedTemplatesHash, name, URI);
+        if (list != NULL)
+            return -1;
+    }
+    return 0;
+}
+
 #ifdef XSLT_REFACTORED
 /**
  * xsltParseXSLTTemplate:
@@ -5405,20 +5428,15 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
 		ret->nameURI = xmlDictLookup(style->dict, BAD_CAST URI, -1);
 	    else
 		ret->nameURI = NULL;
-	    cur = ret->next;
-	    while (cur != NULL) {
-	        if ((URI != NULL && xmlStrEqual(cur->name, ret->name) &&
-				xmlStrEqual(cur->nameURI, URI) ) ||
-		    (URI == NULL && cur->nameURI == NULL &&
-				xmlStrEqual(cur->name, ret->name))) {
-		    xsltTransformError(NULL, style, template,
-		        "xsl:template: error duplicate name '%s'\n", ret->name);
-		    style->errors++;
-		    goto error;
-		}
-		cur = cur->next;
-	    }
+        /* validate that the named template exists only once */
+        if(xsltHasNamedTemplate(style, ret->name, ret->nameURI)){
+             xsltTransformError(NULL, style, template,
+                                 "xsl:template: error duplicate name '%s'\n", ret->name);
+             style->errors++;
+             goto error;
+        }
 	}
+
     }
 
     /*
diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
index 95e8fe6..5aa6e83 100644
--- a/libxslt/xsltInternals.h
+++ b/libxslt/xsltInternals.h
@@ -1639,6 +1639,7 @@ struct _xsltStylesheet {
      * Forwards-compatible processing
      */
     int forwards_compatible;
+    void *namedTemplatesHash;	/* hash table on named templates */
 };
 
 typedef struct _xsltTransformCache xsltTransformCache;
diff --git a/tests/REC/test-6.1.err b/tests/REC/test-6.1.err
new file mode 100644
index 0000000..2bf9165
--- /dev/null
+++ b/tests/REC/test-6.1.err
@@ -0,0 +1,2 @@
+compilation error: file test-6.1.xsl line 11 element template
+xsl:template: error duplicate name 'duplicateTemplateName'
diff --git a/tests/REC/test-6.1.xsl b/tests/REC/test-6.1.xsl
new file mode 100644
index 0000000..1be9d97
--- /dev/null
+++ b/tests/REC/test-6.1.xsl
@@ -0,0 +1,14 @@
+<xsl:stylesheet version="1.0"
+      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!-- reject this XSLT named templates should have unique template name + nameURI combinations -->
+
+<xsl:template match="doc">
+    <xsl:call-template name="duplicateTemplateName"/>
+</xsl:template>
+<xsl:template name="duplicateTemplateName">
+<xsl:text>XSLT should be rejected</xsl:text>
+</xsl:template>
+<xsl:template name="duplicateTemplateName">
+<xsl:text>XSLT should be rejected</xsl:text>
+</xsl:template>
+</xsl:stylesheet>
