diff --git a/HTMLparser.c b/HTMLparser.c
index b05358bded284dd0edcc3f271586d2c938ed50f0_SFRNTHBhcnNlci5j..1423fc7a81896c3b1804b53d9e90abd6f86badc3_SFRNTHBhcnNlci5j 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -5028,6 +5028,8 @@
 /**
  * htmlInitParserCtxt:
  * @ctxt:  an HTML parser context
+ * @sax:  SAX handler
+ * @userData:  user data
  *
  * Initialize a parser context
  *
@@ -5035,5 +5037,5 @@
  */
 
 static int
-htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
+htmlInitParserCtxt(htmlParserCtxtPtr ctxt, htmlSAXHandler *sax, void *userData)
 {
@@ -5039,6 +5041,4 @@
 {
-    htmlSAXHandler *sax;
-
     if (ctxt == NULL) return(-1);
     memset(ctxt, 0, sizeof(htmlParserCtxt));
 
@@ -5047,8 +5047,10 @@
         htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
 	return(-1);
     }
-    sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
-    if (sax == NULL) {
+
+    if (ctxt->sax == NULL)
+        ctxt->sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
+    if (ctxt->sax == NULL) {
         htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
 	return(-1);
     }
@@ -5052,7 +5054,14 @@
         htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
 	return(-1);
     }
-    memset(sax, 0, sizeof(htmlSAXHandler));
+    if (sax == NULL) {
+        memset(ctxt->sax, 0, sizeof(htmlSAXHandler));
+        xmlSAX2InitHtmlDefaultSAXHandler(ctxt->sax);
+        ctxt->userData = ctxt;
+    } else {
+        memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
+        ctxt->userData = userData ? userData : ctxt;
+    }
 
     /* Allocate the Input stack */
     ctxt->inputTab = (htmlParserInputPtr *)
@@ -5111,10 +5120,6 @@
     ctxt->nodeInfoNr  = 0;
     ctxt->nodeInfoMax = 0;
 
-    ctxt->sax = sax;
-    xmlSAX2InitHtmlDefaultSAXHandler(sax);
-
-    ctxt->userData = ctxt;
     ctxt->myDoc = NULL;
     ctxt->wellFormed = 1;
     ctxt->replaceEntities = 0;
@@ -5158,6 +5163,22 @@
 htmlParserCtxtPtr
 htmlNewParserCtxt(void)
 {
+    return(htmlNewSAXParserCtxt(NULL, NULL));
+}
+
+/**
+ * htmlNewSAXParserCtxt:
+ * @sax:  SAX handler
+ * @userData:  user data
+ *
+ * Allocate and initialize a new parser context.
+ *
+ * Returns the htmlParserCtxtPtr or NULL in case of allocation error
+ */
+
+htmlParserCtxtPtr
+htmlNewSAXParserCtxt(htmlSAXHandlerPtr sax, void *userData)
+{
     xmlParserCtxtPtr ctxt;
 
     ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
@@ -5166,7 +5187,7 @@
 	return(NULL);
     }
     memset(ctxt, 0, sizeof(xmlParserCtxt));
-    if (htmlInitParserCtxt(ctxt) < 0) {
+    if (htmlInitParserCtxt(ctxt, sax, userData) < 0) {
         htmlFreeParserCtxt(ctxt);
 	return(NULL);
     }
@@ -6326,10 +6347,10 @@
     buf = xmlAllocParserInputBuffer(enc);
     if (buf == NULL) return(NULL);
 
-    ctxt = htmlNewParserCtxt();
+    ctxt = htmlNewSAXParserCtxt(sax, user_data);
     if (ctxt == NULL) {
 	xmlFreeParserInputBuffer(buf);
 	return(NULL);
     }
     if(enc==XML_CHAR_ENCODING_UTF8 || buf->encoder)
 	ctxt->charset=XML_CHAR_ENCODING_UTF8;
@@ -6330,24 +6351,9 @@
     if (ctxt == NULL) {
 	xmlFreeParserInputBuffer(buf);
 	return(NULL);
     }
     if(enc==XML_CHAR_ENCODING_UTF8 || buf->encoder)
 	ctxt->charset=XML_CHAR_ENCODING_UTF8;
-    if (sax != NULL) {
-#ifdef LIBXML_SAX1_ENABLED
-	if (ctxt->sax != (xmlSAXHandlerPtr) &htmlDefaultSAXHandler)
-#endif
-	    xmlFree(ctxt->sax);
-	ctxt->sax = (htmlSAXHandlerPtr) xmlMalloc(sizeof(htmlSAXHandler));
-	if (ctxt->sax == NULL) {
-	    xmlFree(buf);
-	    xmlFree(ctxt);
-	    return(NULL);
-	}
-	memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
-	if (user_data != NULL)
-	    ctxt->userData = user_data;
-    }
     if (filename == NULL) {
 	ctxt->directory = NULL;
     } else {
diff --git a/doc/devhelp/libxml2-HTMLparser.html b/doc/devhelp/libxml2-HTMLparser.html
index b05358bded284dd0edcc3f271586d2c938ed50f0_ZG9jL2RldmhlbHAvbGlieG1sMi1IVE1McGFyc2VyLmh0bWw=..1423fc7a81896c3b1804b53d9e90abd6f86badc3_ZG9jL2RldmhlbHAvbGlieG1sMi1IVE1McGFyc2VyLmh0bWw= 100644
--- a/doc/devhelp/libxml2-HTMLparser.html
+++ b/doc/devhelp/libxml2-HTMLparser.html
@@ -78,6 +78,7 @@
 int	<a href="#htmlIsAutoClosed">htmlIsAutoClosed</a>		(<a href="libxml2-HTMLparser.html#htmlDocPtr">htmlDocPtr</a> doc, <br/>					 <a href="libxml2-HTMLparser.html#htmlNodePtr">htmlNodePtr</a> elem);
 int	<a href="#htmlIsScriptAttribute">htmlIsScriptAttribute</a>		(const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
 <a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a>	<a href="#htmlNewParserCtxt">htmlNewParserCtxt</a>	(void);
+<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a>	<a href="#htmlNewSAXParserCtxt">htmlNewSAXParserCtxt</a>	(<a href="libxml2-HTMLparser.html#htmlSAXHandlerPtr">htmlSAXHandlerPtr</a> sax, <br/>						 void * userData);
 <a href="libxml2-HTMLparser.html#htmlStatus">htmlStatus</a>	<a href="#htmlNodeStatus">htmlNodeStatus</a>		(const <a href="libxml2-HTMLparser.html#htmlNodePtr">htmlNodePtr</a> node, <br/>					 int legacy);
 int	<a href="#htmlParseCharRef">htmlParseCharRef</a>		(<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt);
 int	<a href="#htmlParseChunk">htmlParseChunk</a>			(<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt, <br/>					 const char * chunk, <br/>					 int size, <br/>					 int terminate);
@@ -298,6 +299,10 @@
 </pre><p>Allocate and initialize a new parser context.</p>
 <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the <a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> or NULL in case of allocation error</td></tr></tbody></table></div></div>
         <hr/>
+        <div class="refsect2" lang="en"><h3><a name="htmlNewSAXParserCtxt"/>htmlNewSAXParserCtxt ()</h3><pre class="programlisting"><a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a>	htmlNewSAXParserCtxt	(<a href="libxml2-HTMLparser.html#htmlSAXHandlerPtr">htmlSAXHandlerPtr</a> sax, <br/>						 void * userData)<br/>
+</pre><p>Allocate and initialize a new parser context.</p>
+<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>sax</tt></i>:</span></td><td>SAX handler</td></tr><tr><td><span class="term"><i><tt>userData</tt></i>:</span></td><td>user data</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the <a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> or NULL in case of allocation error</td></tr></tbody></table></div></div>
+        <hr/>
         <div class="refsect2" lang="en"><h3><a name="htmlNodeStatus"/>htmlNodeStatus ()</h3><pre class="programlisting"><a href="libxml2-HTMLparser.html#htmlStatus">htmlStatus</a>	htmlNodeStatus		(const <a href="libxml2-HTMLparser.html#htmlNodePtr">htmlNodePtr</a> node, <br/>					 int legacy)<br/>
 </pre><p>Checks whether the tree node is valid. Experimental (the author only uses the HTML enhancements in a SAX parser)</p>
 <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>node</tt></i>:</span></td><td>an <a href="libxml2-HTMLparser.html#htmlNodePtr">htmlNodePtr</a> in a tree</td></tr><tr><td><span class="term"><i><tt>legacy</tt></i>:</span></td><td>whether to allow deprecated elements (YES is faster here for Element nodes)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>for Element nodes, a return from <a href="libxml2-HTMLparser.html#htmlElementAllowedHere">htmlElementAllowedHere</a> (if legacy allowed) or <a href="libxml2-HTMLparser.html#htmlElementStatusHere">htmlElementStatusHere</a> (otherwise). for Attribute nodes, a return from <a href="libxml2-HTMLparser.html#htmlAttrAllowed">htmlAttrAllowed</a> for other nodes, <a href="libxml2-HTMLparser.html#HTML_NA">HTML_NA</a> (no checks performed)</td></tr></tbody></table></div></div>
diff --git a/doc/devhelp/libxml2-parser.html b/doc/devhelp/libxml2-parser.html
index b05358bded284dd0edcc3f271586d2c938ed50f0_ZG9jL2RldmhlbHAvbGlieG1sMi1wYXJzZXIuaHRtbA==..1423fc7a81896c3b1804b53d9e90abd6f86badc3_ZG9jL2RldmhlbHAvbGlieG1sMi1wYXJzZXIuaHRtbA== 100644
--- a/doc/devhelp/libxml2-parser.html
+++ b/doc/devhelp/libxml2-parser.html
@@ -119,6 +119,7 @@
 <a href="libxml2-tree.html#xmlParserInputPtr">xmlParserInputPtr</a>	<a href="#xmlLoadExternalEntity">xmlLoadExternalEntity</a>	(const char * URL, <br/>						 const char * ID, <br/>						 <a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt);
 <a href="libxml2-tree.html#xmlParserInputPtr">xmlParserInputPtr</a>	<a href="#xmlNewIOInputStream">xmlNewIOInputStream</a>	(<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br/>						 <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a> input, <br/>						 <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
 <a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>	<a href="#xmlNewParserCtxt">xmlNewParserCtxt</a>	(void);
+<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>	<a href="#xmlNewSAXParserCtxt">xmlNewSAXParserCtxt</a>	(<a href="libxml2-tree.html#xmlSAXHandlerPtr">xmlSAXHandlerPtr</a> sax, <br/>						 void * userData);
 int	<a href="#xmlParseBalancedChunkMemory">xmlParseBalancedChunkMemory</a>	(<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br/>					 <a href="libxml2-tree.html#xmlSAXHandlerPtr">xmlSAXHandlerPtr</a> sax, <br/>					 void * user_data, <br/>					 int depth, <br/>					 const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * string, <br/>					 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> * lst);
 int	<a href="#xmlParseBalancedChunkMemoryRecover">xmlParseBalancedChunkMemoryRecover</a>	(<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br/>						 <a href="libxml2-tree.html#xmlSAXHandlerPtr">xmlSAXHandlerPtr</a> sax, <br/>						 void * user_data, <br/>						 int depth, <br/>						 const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * string, <br/>						 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> * lst, <br/>						 int recover);
 int	<a href="#xmlParseChunk">xmlParseChunk</a>			(<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br/>					 const char * chunk, <br/>					 int size, <br/>					 int terminate);
@@ -580,7 +581,7 @@
 </div>
         <hr/>
         <div class="refsect2" lang="en"><h3><a name="xmlInitParserCtxt"/>xmlInitParserCtxt ()</h3><pre class="programlisting">int	xmlInitParserCtxt		(<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt)<br/>
-</pre><p>Initialize a parser context</p>
+</pre><p>DEPRECATED: Internal function which will be made private in a future version. Initialize a parser context</p>
 <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>ctxt</tt></i>:</span></td><td>an XML parser context</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success and -1 in case of error</td></tr></tbody></table></div></div>
         <hr/>
         <div class="refsect2" lang="en"><h3><a name="xmlKeepBlanksDefault"/>xmlKeepBlanksDefault ()</h3><pre class="programlisting">int	xmlKeepBlanksDefault		(int val)<br/>
@@ -603,6 +604,10 @@
 </pre><p>Allocate and initialize a new parser context.</p>
 <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the <a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> or NULL</td></tr></tbody></table></div></div>
         <hr/>
+        <div class="refsect2" lang="en"><h3><a name="xmlNewSAXParserCtxt"/>xmlNewSAXParserCtxt ()</h3><pre class="programlisting"><a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>	xmlNewSAXParserCtxt	(<a href="libxml2-tree.html#xmlSAXHandlerPtr">xmlSAXHandlerPtr</a> sax, <br/>						 void * userData)<br/>
+</pre><p>Allocate and initialize a new SAX parser context.</p>
+<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>sax</tt></i>:</span></td><td>SAX handler</td></tr><tr><td><span class="term"><i><tt>userData</tt></i>:</span></td><td>user data</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the <a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> or NULL</td></tr></tbody></table></div></div>
+        <hr/>
         <div class="refsect2" lang="en"><h3><a name="xmlParseBalancedChunkMemory"/>xmlParseBalancedChunkMemory ()</h3><pre class="programlisting">int	xmlParseBalancedChunkMemory	(<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br/>					 <a href="libxml2-tree.html#xmlSAXHandlerPtr">xmlSAXHandlerPtr</a> sax, <br/>					 void * user_data, <br/>					 int depth, <br/>					 const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * string, <br/>					 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> * lst)<br/>
 </pre><p>Parse a well-balanced chunk of an XML document called by the parser The allowed sequence for the Well Balanced Chunk is the one defined by the content production in the XML grammar: [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*</p>
 <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>doc</tt></i>:</span></td><td>the document the chunk pertains to (must not be NULL)</td></tr><tr><td><span class="term"><i><tt>sax</tt></i>:</span></td><td>the SAX handler block (possibly NULL)</td></tr><tr><td><span class="term"><i><tt>user_data</tt></i>:</span></td><td>The user data returned on SAX callbacks (possibly NULL)</td></tr><tr><td><span class="term"><i><tt>depth</tt></i>:</span></td><td>Used for loop detection, use 0</td></tr><tr><td><span class="term"><i><tt>string</tt></i>:</span></td><td>the input string in UTF8 or ISO-Latin (zero terminated)</td></tr><tr><td><span class="term"><i><tt>lst</tt></i>:</span></td><td>the return value for the set of parsed nodes</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 if the chunk is well balanced, -1 in case of args problem and the parser error code otherwise</td></tr></tbody></table></div></div>
diff --git a/doc/devhelp/libxml2.devhelp2 b/doc/devhelp/libxml2.devhelp2
index b05358bded284dd0edcc3f271586d2c938ed50f0_ZG9jL2RldmhlbHAvbGlieG1sMi5kZXZoZWxwMg==..1423fc7a81896c3b1804b53d9e90abd6f86badc3_ZG9jL2RldmhlbHAvbGlieG1sMi5kZXZoZWxwMg== 100644
--- a/doc/devhelp/libxml2.devhelp2
+++ b/doc/devhelp/libxml2.devhelp2
@@ -1997,6 +1997,7 @@
     <keyword type="function" name="htmlNewDoc ()" link="libxml2-HTMLtree.html#htmlNewDoc"/>
     <keyword type="function" name="htmlNewDocNoDtD ()" link="libxml2-HTMLtree.html#htmlNewDocNoDtD"/>
     <keyword type="function" name="htmlNewParserCtxt ()" link="libxml2-HTMLparser.html#htmlNewParserCtxt"/>
+    <keyword type="function" name="htmlNewSAXParserCtxt ()" link="libxml2-HTMLparser.html#htmlNewSAXParserCtxt"/>
     <keyword type="function" name="htmlNodeDump ()" link="libxml2-HTMLtree.html#htmlNodeDump"/>
     <keyword type="function" name="htmlNodeDumpFile ()" link="libxml2-HTMLtree.html#htmlNodeDumpFile"/>
     <keyword type="function" name="htmlNodeDumpFileFormat ()" link="libxml2-HTMLtree.html#htmlNodeDumpFileFormat"/>
@@ -2563,6 +2564,7 @@
     <keyword type="function" name="xmlNewProp ()" link="libxml2-tree.html#xmlNewProp"/>
     <keyword type="function" name="xmlNewRMutex ()" link="libxml2-threads.html#xmlNewRMutex"/>
     <keyword type="function" name="xmlNewReference ()" link="libxml2-tree.html#xmlNewReference"/>
+    <keyword type="function" name="xmlNewSAXParserCtxt ()" link="libxml2-parser.html#xmlNewSAXParserCtxt"/>
     <keyword type="function" name="xmlNewStringInputStream ()" link="libxml2-parserInternals.html#xmlNewStringInputStream"/>
     <keyword type="function" name="xmlNewText ()" link="libxml2-tree.html#xmlNewText"/>
     <keyword type="function" name="xmlNewTextChild ()" link="libxml2-tree.html#xmlNewTextChild"/>
diff --git a/doc/libxml2-api.xml b/doc/libxml2-api.xml
index b05358bded284dd0edcc3f271586d2c938ed50f0_ZG9jL2xpYnhtbDItYXBpLnhtbA==..1423fc7a81896c3b1804b53d9e90abd6f86badc3_ZG9jL2xpYnhtbDItYXBpLnhtbA== 100644
--- a/doc/libxml2-api.xml
+++ b/doc/libxml2-api.xml
@@ -62,6 +62,7 @@
      <exports symbol='htmlIsAutoClosed' type='function'/>
      <exports symbol='htmlIsScriptAttribute' type='function'/>
      <exports symbol='htmlNewParserCtxt' type='function'/>
+     <exports symbol='htmlNewSAXParserCtxt' type='function'/>
      <exports symbol='htmlNodeStatus' type='function'/>
      <exports symbol='htmlParseCharRef' type='function'/>
      <exports symbol='htmlParseChunk' type='function'/>
@@ -813,6 +814,7 @@
      <exports symbol='xmlLoadExternalEntity' type='function'/>
      <exports symbol='xmlNewIOInputStream' type='function'/>
      <exports symbol='xmlNewParserCtxt' type='function'/>
+     <exports symbol='xmlNewSAXParserCtxt' type='function'/>
      <exports symbol='xmlParseBalancedChunkMemory' type='function'/>
      <exports symbol='xmlParseBalancedChunkMemoryRecover' type='function'/>
      <exports symbol='xmlParseChunk' type='function'/>
@@ -7628,6 +7630,13 @@
       <info>Allocate and initialize a new parser context.</info>
       <return type='htmlParserCtxtPtr' info='the htmlParserCtxtPtr or NULL in case of allocation error'/>
     </function>
+    <function name='htmlNewSAXParserCtxt' file='HTMLparser' module='HTMLparser'>
+      <cond>defined(LIBXML_HTML_ENABLED)</cond>
+      <info>Allocate and initialize a new parser context.</info>
+      <return type='htmlParserCtxtPtr' info='the htmlParserCtxtPtr or NULL in case of allocation error'/>
+      <arg name='sax' type='htmlSAXHandlerPtr' info='SAX handler'/>
+      <arg name='userData' type='void *' info='user data'/>
+    </function>
     <function name='htmlNodeDump' file='HTMLtree' module='HTMLtree'>
       <cond>defined(LIBXML_HTML_ENABLED) &amp;&amp; defined(LIBXML_OUTPUT_ENABLED)</cond>
       <info>Dump an HTML node, recursive behaviour,children are printed too, and formatting returns are added.</info>
@@ -10582,7 +10591,7 @@
       <return type='void'/>
     </function>
     <function name='xmlInitParserCtxt' file='parser' module='parserInternals'>
-      <info>Initialize a parser context</info>
+      <info>DEPRECATED: Internal function which will be made private in a future version.  Initialize a parser context</info>
       <return type='int' info='0 in case of success and -1 in case of error'/>
       <arg name='ctxt' type='xmlParserCtxtPtr' info='an XML parser context'/>
     </function>
@@ -11596,6 +11605,12 @@
       <arg name='doc' type='const xmlDoc *' info='the document'/>
       <arg name='name' type='const xmlChar *' info='the reference name, or the reference string with &amp; and ;'/>
     </function>
+    <function name='xmlNewSAXParserCtxt' file='parser' module='parserInternals'>
+      <info>Allocate and initialize a new SAX parser context.</info>
+      <return type='xmlParserCtxtPtr' info='the xmlParserCtxtPtr or NULL'/>
+      <arg name='sax' type='xmlSAXHandlerPtr' info='SAX handler'/>
+      <arg name='userData' type='void *' info='user data'/>
+    </function>
     <function name='xmlNewStringInputStream' file='parserInternals' module='parserInternals'>
       <info>Create a new input stream based on a memory buffer.</info>
       <return type='xmlParserInputPtr' info='the new input stream'/>
diff --git a/doc/symbols.xml b/doc/symbols.xml
index b05358bded284dd0edcc3f271586d2c938ed50f0_ZG9jL3N5bWJvbHMueG1s..1423fc7a81896c3b1804b53d9e90abd6f86badc3_ZG9jL3N5bWJvbHMueG1s 100644
--- a/doc/symbols.xml
+++ b/doc/symbols.xml
@@ -1771,4 +1771,8 @@
   <release version="2.9.11">
     <symbol file="xmlIO">xmlPopOutputCallbacks</symbol>
   </release>
+  <release version="2.11.0">
+    <symbol file="HTMLparser">htmlNewSAXParserCtxt</symbol>
+    <symbol file="parser">xmlNewSAXParserCtxt</symbol>
+  </release>
 </symbols>
diff --git a/include/libxml/HTMLparser.h b/include/libxml/HTMLparser.h
index b05358bded284dd0edcc3f271586d2c938ed50f0_aW5jbHVkZS9saWJ4bWwvSFRNTHBhcnNlci5o..1423fc7a81896c3b1804b53d9e90abd6f86badc3_aW5jbHVkZS9saWJ4bWwvSFRNTHBhcnNlci5o 100644
--- a/include/libxml/HTMLparser.h
+++ b/include/libxml/HTMLparser.h
@@ -107,6 +107,9 @@
 
 XMLPUBFUN htmlParserCtxtPtr XMLCALL
 			htmlNewParserCtxt(void);
+XMLPUBFUN htmlParserCtxtPtr XMLCALL
+			htmlNewSAXParserCtxt(htmlSAXHandlerPtr sax,
+                                        void *userData);
 
 XMLPUBFUN htmlParserCtxtPtr XMLCALL
 			htmlCreateMemoryParserCtxt(const char *buffer,
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index b05358bded284dd0edcc3f271586d2c938ed50f0_aW5jbHVkZS9saWJ4bWwvcGFyc2VyLmg=..1423fc7a81896c3b1804b53d9e90abd6f86badc3_aW5jbHVkZS9saWJ4bWwvcGFyc2VyLmg= 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -975,6 +975,8 @@
  */
 XMLPUBFUN xmlParserCtxtPtr XMLCALL
 		xmlNewParserCtxt	(void);
+XMLPUBFUN xmlParserCtxtPtr XMLCALL
+		xmlNewSAXParserCtxt	(xmlSAXHandlerPtr sax, void *userData);
 XMLPUBFUN int XMLCALL
 		xmlInitParserCtxt	(xmlParserCtxtPtr ctxt);
 XMLPUBFUN void XMLCALL
diff --git a/libxml2.syms b/libxml2.syms
index b05358bded284dd0edcc3f271586d2c938ed50f0_bGlieG1sMi5zeW1z..1423fc7a81896c3b1804b53d9e90abd6f86badc3_bGlieG1sMi5zeW1z 100644
--- a/libxml2.syms
+++ b/libxml2.syms
@@ -2293,3 +2293,13 @@
   xmlPopOutputCallbacks;
 } LIBXML2_2.9.8;
 
+LIBXML2_2.11.0 {
+    global:
+
+# HTMLparser
+  htmlNewSAXParserCtxt;
+
+# parser
+  xmlNewSAXParserCtxt;
+} LIBXML2_2.9.11;
+
diff --git a/parser.c b/parser.c
index b05358bded284dd0edcc3f271586d2c938ed50f0_cGFyc2VyLmM=..1423fc7a81896c3b1804b53d9e90abd6f86badc3_cGFyc2VyLmM= 100644
--- a/parser.c
+++ b/parser.c
@@ -85,8 +85,9 @@
 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
 
 static xmlParserCtxtPtr
-xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
-	                  const xmlChar *base, xmlParserCtxtPtr pctx);
+xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
+        const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
+        xmlParserCtxtPtr pctx);
 
 static void xmlHaltParser(xmlParserCtxtPtr ctxt);
 
@@ -12447,10 +12448,10 @@
     buf = xmlAllocParserInputBuffer(enc);
     if (buf == NULL) return(NULL);
 
-    ctxt = xmlNewParserCtxt();
+    ctxt = xmlNewSAXParserCtxt(sax, user_data);
     if (ctxt == NULL) {
         xmlErrMemory(NULL, "creating parser: out of memory\n");
 	xmlFreeParserInputBuffer(buf);
 	return(NULL);
     }
     ctxt->dictNames = 1;
@@ -12451,29 +12452,9 @@
     if (ctxt == NULL) {
         xmlErrMemory(NULL, "creating parser: out of memory\n");
 	xmlFreeParserInputBuffer(buf);
 	return(NULL);
     }
     ctxt->dictNames = 1;
-    if (sax != NULL) {
-#ifdef LIBXML_SAX1_ENABLED
-	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
-#endif /* LIBXML_SAX1_ENABLED */
-	    xmlFree(ctxt->sax);
-	ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
-	if (ctxt->sax == NULL) {
-	    xmlErrMemory(ctxt, NULL);
-	    xmlFreeParserInputBuffer(buf);
-	    xmlFreeParserCtxt(ctxt);
-	    return(NULL);
-	}
-	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
-	if (sax->initialized == XML_SAX2_MAGIC)
-	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
-	else
-	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
-	if (user_data != NULL)
-	    ctxt->userData = user_data;
-    }
     if (filename == NULL) {
 	ctxt->directory = NULL;
     } else {
@@ -12609,8 +12590,8 @@
         return (NULL);
     }
 
-    ctxt = xmlNewParserCtxt();
+    ctxt = xmlNewSAXParserCtxt(sax, user_data);
     if (ctxt == NULL) {
 	xmlFreeParserInputBuffer(buf);
 	return(NULL);
     }
@@ -12613,27 +12594,7 @@
     if (ctxt == NULL) {
 	xmlFreeParserInputBuffer(buf);
 	return(NULL);
     }
-    if (sax != NULL) {
-#ifdef LIBXML_SAX1_ENABLED
-	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
-#endif /* LIBXML_SAX1_ENABLED */
-	    xmlFree(ctxt->sax);
-	ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
-	if (ctxt->sax == NULL) {
-	    xmlFreeParserInputBuffer(buf);
-	    xmlErrMemory(ctxt, NULL);
-	    xmlFreeParserCtxt(ctxt);
-	    return(NULL);
-	}
-	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
-	if (sax->initialized == XML_SAX2_MAGIC)
-	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
-	else
-	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
-	if (user_data != NULL)
-	    ctxt->userData = user_data;
-    }
 
     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
     if (inputStream == NULL) {
@@ -12675,7 +12636,7 @@
     if (input == NULL)
 	return(NULL);
 
-    ctxt = xmlNewParserCtxt();
+    ctxt = xmlNewSAXParserCtxt(sax, NULL);
     if (ctxt == NULL) {
         xmlFreeParserInputBuffer(input);
 	return(NULL);
@@ -12684,15 +12645,6 @@
     /* We are loading a DTD */
     ctxt->options |= XML_PARSE_DTDLOAD;
 
-    /*
-     * Set-up the SAX context
-     */
-    if (sax != NULL) {
-	if (ctxt->sax != NULL)
-	    xmlFree(ctxt->sax);
-        ctxt->sax = sax;
-        ctxt->userData = ctxt;
-    }
     xmlDetectSAX2(ctxt);
 
     /*
@@ -12701,7 +12653,6 @@
 
     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
     if (pinput == NULL) {
-        if (sax != NULL) ctxt->sax = NULL;
         xmlFreeParserInputBuffer(input);
 	xmlFreeParserCtxt(ctxt);
 	return(NULL);
@@ -12711,7 +12662,6 @@
      * plug some encoding conversion routines here.
      */
     if (xmlPushInput(ctxt, pinput) < 0) {
-        if (sax != NULL) ctxt->sax = NULL;
 	xmlFreeParserCtxt(ctxt);
 	return(NULL);
     }
@@ -12778,7 +12728,6 @@
         xmlFreeDoc(ctxt->myDoc);
         ctxt->myDoc = NULL;
     }
-    if (sax != NULL) ctxt->sax = NULL;
     xmlFreeParserCtxt(ctxt);
 
     return(ret);
@@ -12806,7 +12755,7 @@
 
     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
 
-    ctxt = xmlNewParserCtxt();
+    ctxt = xmlNewSAXParserCtxt(sax, NULL);
     if (ctxt == NULL) {
 	return(NULL);
     }
@@ -12815,16 +12764,6 @@
     ctxt->options |= XML_PARSE_DTDLOAD;
 
     /*
-     * Set-up the SAX context
-     */
-    if (sax != NULL) {
-	if (ctxt->sax != NULL)
-	    xmlFree(ctxt->sax);
-        ctxt->sax = sax;
-        ctxt->userData = ctxt;
-    }
-
-    /*
      * Canonicalise the system ID
      */
     systemIdCanonic = xmlCanonicPath(SystemID);
@@ -12841,7 +12780,6 @@
 	input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
 	                                 systemIdCanonic);
     if (input == NULL) {
-        if (sax != NULL) ctxt->sax = NULL;
 	xmlFreeParserCtxt(ctxt);
 	if (systemIdCanonic != NULL)
 	    xmlFree(systemIdCanonic);
@@ -12852,7 +12790,6 @@
      * plug some encoding conversion routines here.
      */
     if (xmlPushInput(ctxt, input) < 0) {
-        if (sax != NULL) ctxt->sax = NULL;
 	xmlFreeParserCtxt(ctxt);
 	if (systemIdCanonic != NULL)
 	    xmlFree(systemIdCanonic);
@@ -12880,7 +12817,6 @@
     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
     if (ctxt->myDoc == NULL) {
 	xmlErrMemory(ctxt, "New Doc failed");
-        if (sax != NULL) ctxt->sax = NULL;
 	xmlFreeParserCtxt(ctxt);
 	return(NULL);
     }
@@ -12909,7 +12845,6 @@
         xmlFreeDoc(ctxt->myDoc);
         ctxt->myDoc = NULL;
     }
-    if (sax != NULL) ctxt->sax = NULL;
     xmlFreeParserCtxt(ctxt);
 
     return(ret);
@@ -13000,7 +12935,6 @@
     xmlParserCtxtPtr ctxt;
     xmlDocPtr newDoc;
     xmlNodePtr newRoot;
-    xmlSAXHandlerPtr oldsax = NULL;
     xmlParserErrors ret = XML_ERR_OK;
     xmlChar start[4];
     xmlCharEncoding enc;
@@ -13018,6 +12952,6 @@
     if (doc == NULL)
 	return(XML_ERR_INTERNAL_ERROR);
 
-
-    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
+    ctxt = xmlCreateEntityParserCtxtInternal(sax, user_data, URL, ID, NULL,
+                                             oldctxt);
     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
@@ -13023,9 +12957,2 @@
     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
-    ctxt->userData = ctxt;
-    if (sax != NULL) {
-	oldsax = ctxt->sax;
-        ctxt->sax = sax;
-	if (user_data != NULL)
-	    ctxt->userData = user_data;
-    }
     xmlDetectSAX2(ctxt);
@@ -13031,4 +12958,5 @@
     xmlDetectSAX2(ctxt);
+
     newDoc = xmlNewDoc(BAD_CAST "1.0");
     if (newDoc == NULL) {
 	xmlFreeParserCtxt(ctxt);
@@ -13049,7 +12977,6 @@
     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
     if (newRoot == NULL) {
 	if (sax != NULL)
-	    ctxt->sax = oldsax;
 	xmlFreeParserCtxt(ctxt);
 	newDoc->intSubset = NULL;
 	newDoc->extSubset = NULL;
@@ -13190,8 +13117,6 @@
     if ((oldctxt != NULL) && (ctxt->lastError.code != XML_ERR_OK))
         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
 
-    if (sax != NULL)
-	ctxt->sax = oldsax;
     if (oldctxt != NULL) {
         ctxt->dict = NULL;
         ctxt->attsDefault = NULL;
@@ -13942,10 +13867,11 @@
  * Returns the new parser context or NULL
  */
 static xmlParserCtxtPtr
-xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
-	                  const xmlChar *base, xmlParserCtxtPtr pctx) {
+xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
+        const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
+        xmlParserCtxtPtr pctx) {
     xmlParserCtxtPtr ctxt;
     xmlParserInputPtr inputStream;
     char *directory = NULL;
     xmlChar *uri;
 
@@ -13947,9 +13873,9 @@
     xmlParserCtxtPtr ctxt;
     xmlParserInputPtr inputStream;
     char *directory = NULL;
     xmlChar *uri;
 
-    ctxt = xmlNewParserCtxt();
+    ctxt = xmlNewSAXParserCtxt(sax, userData);
     if (ctxt == NULL) {
 	return(NULL);
     }
@@ -14017,7 +13943,7 @@
 xmlParserCtxtPtr
 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
 	                  const xmlChar *base) {
-    return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
+    return xmlCreateEntityParserCtxtInternal(NULL, NULL, URL, ID, base, NULL);
 
 }
 
diff --git a/parserInternals.c b/parserInternals.c
index b05358bded284dd0edcc3f271586d2c938ed50f0_cGFyc2VySW50ZXJuYWxzLmM=..1423fc7a81896c3b1804b53d9e90abd6f86badc3_cGFyc2VySW50ZXJuYWxzLmM= 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -1439,6 +1439,8 @@
  ************************************************************************/
 
 /**
- * xmlInitParserCtxt:
- * @ctxt:  an XML parser context
+ * xmlInitSAXParserCtxt:
+ * @ctxt:  XML parser context
+ * @sax:  SAX handlert
+ * @userData:  user data
  *
@@ -1444,6 +1446,6 @@
  *
- * Initialize a parser context
+ * Initialize a SAX parser context
  *
  * Returns 0 in case of success and -1 in case of error
  */
 
@@ -1446,9 +1448,10 @@
  *
  * Returns 0 in case of success and -1 in case of error
  */
 
-int
-xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
+static int
+xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, xmlSAXHandlerPtr sax,
+                     void *userData)
 {
     xmlParserInputPtr input;
 
@@ -1473,5 +1476,6 @@
         xmlErrMemory(NULL, "cannot initialize parser context\n");
 	return(-1);
     }
-    else
+    if (sax == NULL) {
+	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
         xmlSAXVersion(ctxt->sax, 2);
@@ -1477,4 +1481,14 @@
         xmlSAXVersion(ctxt->sax, 2);
+        ctxt->userData = ctxt;
+    } else {
+	if (sax->initialized == XML_SAX2_MAGIC) {
+	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
+        } else {
+	    memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
+	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
+        }
+        ctxt->userData = userData ? userData : ctxt;
+    }
 
     ctxt->maxatts = 0;
     ctxt->atts = NULL;
@@ -1572,7 +1586,6 @@
     ctxt->spaceMax = 10;
     ctxt->spaceTab[0] = -1;
     ctxt->space = &ctxt->spaceTab[0];
-    ctxt->userData = ctxt;
     ctxt->myDoc = NULL;
     ctxt->wellFormed = 1;
     ctxt->nsWellFormed = 1;
@@ -1625,6 +1638,24 @@
 }
 
 /**
+ * xmlInitParserCtxt:
+ * @ctxt:  an XML parser context
+ *
+ * DEPRECATED: Internal function which will be made private in a future
+ * version.
+ *
+ * Initialize a parser context
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+
+int
+xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
+{
+    return(xmlInitSAXParserCtxt(ctxt, NULL, NULL));
+}
+
+/**
  * xmlFreeParserCtxt:
  * @ctxt:  an XML parser context
  *
@@ -1721,6 +1752,22 @@
 xmlParserCtxtPtr
 xmlNewParserCtxt(void)
 {
+    return(xmlNewSAXParserCtxt(NULL, NULL));
+}
+
+/**
+ * xmlNewSAXParserCtxt:
+ * @sax:  SAX handler
+ * @userData:  user data
+ *
+ * Allocate and initialize a new SAX parser context.
+ *
+ * Returns the xmlParserCtxtPtr or NULL
+ */
+
+xmlParserCtxtPtr
+xmlNewSAXParserCtxt(xmlSAXHandlerPtr sax, void *userData)
+{
     xmlParserCtxtPtr ctxt;
 
     ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
@@ -1729,7 +1776,7 @@
 	return(NULL);
     }
     memset(ctxt, 0, sizeof(xmlParserCtxt));
-    if (xmlInitParserCtxt(ctxt) < 0) {
+    if (xmlInitSAXParserCtxt(ctxt, sax, userData) < 0) {
         xmlFreeParserCtxt(ctxt);
 	return(NULL);
     }
diff --git a/testapi.c b/testapi.c
index b05358bded284dd0edcc3f271586d2c938ed50f0_dGVzdGFwaS5j..1423fc7a81896c3b1804b53d9e90abd6f86badc3_dGVzdGFwaS5j 100644
--- a/testapi.c
+++ b/testapi.c
@@ -464,8 +464,6 @@
         xmlFreeParserCtxt(val);
 }
 
-#if defined(LIBXML_PUSH_ENABLED) || defined(LIBXML_SAX1_ENABLED) || \
-    defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_VALID_ENABLED)
 #define gen_nb_xmlSAXHandlerPtr 2
 static xmlSAXHandlerPtr gen_xmlSAXHandlerPtr(int no, int nr ATTRIBUTE_UNUSED) {
     (void) no;
@@ -476,7 +474,6 @@
 }
 static void des_xmlSAXHandlerPtr(int no ATTRIBUTE_UNUSED, xmlSAXHandlerPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
 }
-#endif
 
 #define gen_nb_xmlValidCtxtPtr 2
 static xmlValidCtxtPtr gen_xmlValidCtxtPtr(int no, int nr ATTRIBUTE_UNUSED) {
@@ -2182,6 +2179,47 @@
 
 
 static int
+test_htmlNewSAXParserCtxt(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_HTML_ENABLED)
+    int mem_base;
+    htmlParserCtxtPtr ret_val;
+    htmlSAXHandlerPtr sax; /* SAX handler */
+    int n_sax;
+    void * userData; /* user data */
+    int n_userData;
+
+    for (n_sax = 0;n_sax < gen_nb_htmlSAXHandlerPtr;n_sax++) {
+    for (n_userData = 0;n_userData < gen_nb_userdata;n_userData++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_htmlSAXHandlerPtr(n_sax, 0);
+        userData = gen_userdata(n_userData, 1);
+
+        ret_val = htmlNewSAXParserCtxt(sax, userData);
+        desret_htmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_htmlSAXHandlerPtr(n_sax, sax, 0);
+        des_userdata(n_userData, userData, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in htmlNewSAXParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_userData);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
 test_htmlNodeStatus(void) {
     int test_ret = 0;
 
@@ -2786,7 +2824,7 @@
 test_HTMLparser(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing HTMLparser : 32 of 38 functions ...\n");
+    if (quiet == 0) printf("Testing HTMLparser : 33 of 39 functions ...\n");
     test_ret += test_UTF8ToHtml();
     test_ret += test_htmlAttrAllowed();
     test_ret += test_htmlAutoCloseTag();
@@ -2806,6 +2844,7 @@
     test_ret += test_htmlIsAutoClosed();
     test_ret += test_htmlIsScriptAttribute();
     test_ret += test_htmlNewParserCtxt();
+    test_ret += test_htmlNewSAXParserCtxt();
     test_ret += test_htmlNodeStatus();
     test_ret += test_htmlParseCharRef();
     test_ret += test_htmlParseChunk();
@@ -12764,6 +12803,45 @@
 }
 
 
+static int
+test_xmlNewSAXParserCtxt(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlParserCtxtPtr ret_val;
+    xmlSAXHandlerPtr sax; /* SAX handler */
+    int n_sax;
+    void * userData; /* user data */
+    int n_userData;
+
+    for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) {
+    for (n_userData = 0;n_userData < gen_nb_userdata;n_userData++) {
+        mem_base = xmlMemBlocks();
+        sax = gen_xmlSAXHandlerPtr(n_sax, 0);
+        userData = gen_userdata(n_userData, 1);
+
+        ret_val = xmlNewSAXParserCtxt(sax, userData);
+        desret_xmlParserCtxtPtr(ret_val);
+        call_tests++;
+        des_xmlSAXHandlerPtr(n_sax, sax, 0);
+        des_userdata(n_userData, userData, 1);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlNewSAXParserCtxt",
+	           xmlMemBlocks() - mem_base);
+	    test_ret++;
+            printf(" %d", n_sax);
+            printf(" %d", n_userData);
+            printf("\n");
+        }
+    }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
 #define gen_nb_xmlNodePtr_ptr 1
 #define gen_xmlNodePtr_ptr(no, nr) NULL
 #define des_xmlNodePtr_ptr(no, val, nr)
@@ -14587,7 +14665,7 @@
 test_parser(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing parser : 58 of 70 functions ...\n");
+    if (quiet == 0) printf("Testing parser : 59 of 71 functions ...\n");
     test_ret += test_xmlByteConsumed();
     test_ret += test_xmlClearNodeInfoSeq();
     test_ret += test_xmlClearParserCtxt();
@@ -14610,6 +14688,7 @@
     test_ret += test_xmlLoadExternalEntity();
     test_ret += test_xmlNewIOInputStream();
     test_ret += test_xmlNewParserCtxt();
+    test_ret += test_xmlNewSAXParserCtxt();
     test_ret += test_xmlParseBalancedChunkMemory();
     test_ret += test_xmlParseBalancedChunkMemoryRecover();
     test_ret += test_xmlParseChunk();
diff --git a/testlimits.c b/testlimits.c
index b05358bded284dd0edcc3f271586d2c938ed50f0_dGVzdGxpbWl0cy5j..1423fc7a81896c3b1804b53d9e90abd6f86badc3_dGVzdGxpbWl0cy5j 100644
--- a/testlimits.c
+++ b/testlimits.c
@@ -1261,8 +1261,7 @@
     int res = 0;
     xmlParserCtxtPtr ctxt;
     xmlDocPtr doc;
-    xmlSAXHandlerPtr old_sax;
 
     nb_tests++;
 
     maxlen = limit;
@@ -1265,9 +1264,9 @@
 
     nb_tests++;
 
     maxlen = limit;
-    ctxt = xmlNewParserCtxt();
+    ctxt = xmlNewSAXParserCtxt(callbackSAX2Handler, NULL);
     if (ctxt == NULL) {
         fprintf(stderr, "Failed to create parser context\n");
 	return(1);
     }
@@ -1270,10 +1269,7 @@
     if (ctxt == NULL) {
         fprintf(stderr, "Failed to create parser context\n");
 	return(1);
     }
-    old_sax = ctxt->sax;
-    ctxt->sax = callbackSAX2Handler;
-    ctxt->userData = NULL;
     doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
 
     if (doc != NULL) {
@@ -1296,7 +1292,6 @@
         } else
             res = 0;
     }
-    ctxt->sax = old_sax;
     xmlFreeParserCtxt(ctxt);
 
     return(res);
diff --git a/win32/libxml2.def.src b/win32/libxml2.def.src
index b05358bded284dd0edcc3f271586d2c938ed50f0_d2luMzIvbGlieG1sMi5kZWYuc3Jj..1423fc7a81896c3b1804b53d9e90abd6f86badc3_d2luMzIvbGlieG1sMi5kZWYuc3Jj 100644
--- a/win32/libxml2.def.src
+++ b/win32/libxml2.def.src
@@ -297,6 +297,9 @@
 htmlNewParserCtxt
 #endif
 #ifdef LIBXML_HTML_ENABLED
+htmlNewSAXParserCtxt
+#endif
+#ifdef LIBXML_HTML_ENABLED
 htmlNodeDump
 #endif
 #ifdef LIBXML_HTML_ENABLED
@@ -1214,6 +1217,7 @@
 xmlNewProp
 xmlNewRMutex
 xmlNewReference
+xmlNewSAXParserCtxt
 xmlNewStringInputStream
 xmlNewText
 xmlNewTextChild
diff --git a/xmllint.c b/xmllint.c
index b05358bded284dd0edcc3f271586d2c938ed50f0_eG1sbGludC5j..1423fc7a81896c3b1804b53d9e90abd6f86badc3_eG1sbGludC5j 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -1586,10 +1586,6 @@
 testSAX(const char *filename) {
     xmlSAXHandlerPtr handler;
     const char *user_data = "user_data"; /* mostly for debugging */
-    xmlParserInputBufferPtr buf = NULL;
-    xmlParserInputPtr inputStream;
-    xmlParserCtxtPtr ctxt = NULL;
-    xmlSAXHandlerPtr old_sax = NULL;
 
     callbacks = 0;
 
@@ -1603,15 +1599,7 @@
         handler = debugSAX2Handler;
     }
 
-    /*
-     * it's not the simplest code but the most generic in term of I/O
-     */
-    buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-    if (buf == NULL) {
-        goto error;
-    }
-
 #ifdef LIBXML_SCHEMAS_ENABLED
     if (wxschemas != NULL) {
         int ret;
 	xmlSchemaValidCtxtPtr vctxt;
@@ -1614,9 +1602,15 @@
 #ifdef LIBXML_SCHEMAS_ENABLED
     if (wxschemas != NULL) {
         int ret;
 	xmlSchemaValidCtxtPtr vctxt;
+        xmlParserInputBufferPtr buf;
+
+        buf = xmlParserInputBufferCreateFilename(filename,
+                XML_CHAR_ENCODING_NONE);
+        if (buf == NULL)
+            return;
 
 	vctxt = xmlSchemaNewValidCtxt(wxschemas);
         if (vctxt == NULL) {
             progresult = XMLLINT_ERR_MEM;
             xmlFreeParserInputBuffer(buf);
@@ -1618,9 +1612,9 @@
 
 	vctxt = xmlSchemaNewValidCtxt(wxschemas);
         if (vctxt == NULL) {
             progresult = XMLLINT_ERR_MEM;
             xmlFreeParserInputBuffer(buf);
-            goto error;
+            return;
         }
 	xmlSchemaSetValidErrors(vctxt, xmlGenericError, xmlGenericError, NULL);
 	xmlSchemaValidateSetFilename(vctxt, filename);
@@ -1645,6 +1639,8 @@
     } else
 #endif
     {
+        xmlParserCtxtPtr ctxt = NULL;
+
 	/*
 	 * Create the parser context amd hook the input
 	 */
@@ -1648,6 +1644,6 @@
 	/*
 	 * Create the parser context amd hook the input
 	 */
-	ctxt = xmlNewParserCtxt();
+	ctxt = xmlNewSAXParserCtxt(handler, (void *) user_data);
 	if (ctxt == NULL) {
             progresult = XMLLINT_ERR_MEM;
@@ -1652,5 +1648,4 @@
 	if (ctxt == NULL) {
             progresult = XMLLINT_ERR_MEM;
-	    xmlFreeParserInputBuffer(buf);
-	    goto error;
+	    return;
 	}
@@ -1656,19 +1651,8 @@
 	}
-	old_sax = ctxt->sax;
-	ctxt->sax = handler;
-	ctxt->userData = (void *) user_data;
-	inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
-	if (inputStream == NULL) {
-	    xmlFreeParserInputBuffer(buf);
-	    goto error;
-	}
-	inputPush(ctxt, inputStream);
-
-	/* do the parsing */
-	xmlParseDocument(ctxt);
+        xmlCtxtReadFile(ctxt, filename, NULL, options);
 
 	if (ctxt->myDoc != NULL) {
 	    fprintf(stderr, "SAX generated a doc !\n");
 	    xmlFreeDoc(ctxt->myDoc);
 	    ctxt->myDoc = NULL;
 	}
@@ -1669,14 +1653,9 @@
 
 	if (ctxt->myDoc != NULL) {
 	    fprintf(stderr, "SAX generated a doc !\n");
 	    xmlFreeDoc(ctxt->myDoc);
 	    ctxt->myDoc = NULL;
 	}
-    }
-
-error:
-    if (ctxt != NULL) {
-        ctxt->sax = old_sax;
         xmlFreeParserCtxt(ctxt);
     }
 }
diff --git a/xmlschemas.c b/xmlschemas.c
index b05358bded284dd0edcc3f271586d2c938ed50f0_eG1sc2NoZW1hcy5j..1423fc7a81896c3b1804b53d9e90abd6f86badc3_eG1sc2NoZW1hcy5j 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -29063,7 +29063,6 @@
                         xmlSAXHandlerPtr sax, void *user_data)
 {
     xmlSchemaSAXPlugPtr plug = NULL;
-    xmlSAXHandlerPtr old_sax = NULL;
     xmlParserCtxtPtr pctxt = NULL;
     xmlParserInputPtr inputStream = NULL;
     int ret;
@@ -29074,6 +29073,6 @@
     /*
      * prepare the parser
      */
-    pctxt = xmlNewParserCtxt();
+    pctxt = xmlNewSAXParserCtxt(sax, user_data);
     if (pctxt == NULL)
         return (-1);
@@ -29078,8 +29077,5 @@
     if (pctxt == NULL)
         return (-1);
-    old_sax = pctxt->sax;
-    pctxt->sax = sax;
-    pctxt->userData = user_data;
 #if 0
     if (options)
         xmlCtxtUseOptions(pctxt, options);
@@ -29125,7 +29121,6 @@
     }
     /* cleanup */
     if (pctxt != NULL) {
-	pctxt->sax = old_sax;
 	xmlFreeParserCtxt(pctxt);
     }
     return (ret);