diff -ur -x *.manifest -x *.map tidycvs\include\tidyenum.h tidydev\include\tidyenum.h
--- tidycvs\include\tidyenum.h	Tue Jan 10 17:23:20 2012
+++ tidydev\include\tidyenum.h	Wed Jan 11 14:35:41 2012
@@ -204,6 +204,7 @@
   TidySortAttributes,      /**< Sort attributes */
   TidyMergeSpans,       /**< Merge multiple SPANs */
   TidyAnchorAsName,    /**< Define anchors as name attributes */
+  TidyNoEqWrap,        /**< Do not 'wrap' on equal(=), like in xml */
   N_TIDY_OPTIONS       /**< Must be last */
 } TidyOptionId;
 
diff -ur -x *.manifest -x *.map tidycvs\src\access.c tidydev\src\access.c
--- tidycvs\src\access.c	Wed Mar 25 23:04:35 2009
+++ tidydev\src\access.c	Mon Feb 08 19:57:39 2010
@@ -1580,6 +1580,21 @@
                     {
                         temp = TNode->content;
 
+                        if ( nodeIsTH(temp) )
+                        {
+                            AttVal* av;
+                            for (av = temp->attributes; av != NULL; av = av->next)
+                            {
+                                if ( attrIsROWSPAN(av) )
+                                {
+                                    if (atoi(av->value) > 1)
+                                    {
+                                        validColSpanRows = no;
+                                    }
+                                }
+                            }
+                        }
+
                         /* The number of TH elements found within TR element */
                         if (flag == 0)
                         {
diff -ur -x *.manifest -x *.map tidycvs\src\clean.c tidydev\src\clean.c
--- tidycvs\src\clean.c	Tue Oct 14 14:18:10 2008
+++ tidydev\src\clean.c	Mon Jan 19 14:50:51 2009
@@ -1670,7 +1670,8 @@
     return NULL;
 }
 
-/* node is <![if ...]> prune up to <![endif]> */
+/* node is <![if ...]> prune up to <![endif]>
+   BUG 2085175 - unless there is TEXT inbetween! */
 static Node* PruneSection( TidyDocImpl* doc, Node *node )
 {
     Lexer* lexer = doc->lexer;
@@ -1771,7 +1772,9 @@
             attrIsLANG(attr)  ||
              ( (attrIsHEIGHT(attr) || attrIsWIDTH(attr)) &&
                (nodeIsTD(node) || nodeIsTR(node) || nodeIsTH(node)) ) ||
-             (attr->attribute && TY_(tmbstrncmp)(attr->attribute, "x:", 2) == 0) )
+             (attr->attribute && (
+             ( TY_(tmbstrncmp)(attr->attribute, "x:", 2) == 0 ) ||
+             ( TY_(tmbstrncmp)(attr->attribute, "v:", 2) == 0 ) ))) 
         {
             if (prev)
                 prev->next = next;
@@ -1995,7 +1998,9 @@
         {
             AttVal *attr = TY_(AttrGetById)(node, TidyAttr_REL);
 
-            if (AttrValueIs(attr, "File-List"))
+            /* some <link rel="???" ...> to discard */
+            if ( AttrValueIs(attr, "File-List") ||
+                 AttrValueIs(attr, "Edit-Time-Data") )
             {
                 node = TY_(DiscardElement)( doc, node );
                 continue;
@@ -2089,7 +2094,7 @@
         if (!node)
             return;
 
-        /* strip out style and class attributes */
+        /* strip out style, class, ... and "x:", "v:" attributes */
         if (TY_(nodeIsElement)(node))
             PurgeWord2000Attributes( doc, node );
 
diff -ur -x *.manifest -x *.map tidycvs\src\clean.h tidydev\src\clean.h
--- tidycvs\src\clean.h	Tue Sep 12 17:14:44 2006
+++ tidydev\src\clean.h	Sat Aug 18 18:55:25 2007
@@ -58,7 +58,7 @@
  as inline.
 */
 void TY_(CleanWord2000)( TidyDocImpl* doc, Node *node);
-
+void TY_(CleanWord2003)( TidyDocImpl* doc, Node *node); /* new 20070523 */
 Bool TY_(IsWord2000)( TidyDocImpl* doc );
 
 /* where appropriate move object elements from head to body */
diff -ur -x *.manifest -x *.map tidycvs\src\config.c tidydev\src\config.c
--- tidycvs\src\config.c	Wed Jun 18 22:18:54 2008
+++ tidydev\src\config.c	Sun Mar 28 12:43:37 2010
@@ -315,6 +315,7 @@
   { TidySortAttributes,          PP, "sort-attributes",             IN, TidySortAttrNone,ParseSorter,       sorterPicks     },
   { TidyMergeSpans,              MU, "merge-spans",                 IN, TidyAutoState,   ParseAutoBool,     autoBoolPicks   },
   { TidyAnchorAsName,            MU, "anchor-as-name",              BL, yes,             ParseBool,         boolPicks       },
+  { TidyNoEqWrap,                MU, "no-equal-wrap",               BL, no,              ParseBool,         boolPicks       },
   { N_TIDY_OPTIONS,              XX, NULL,                          XY, 0,               NULL,              NULL            }
 };
 
diff -ur -x *.manifest -x *.map tidycvs\src\entities.c tidydev\src\entities.c
--- tidycvs\src\entities.c	Sat Aug 09 13:55:27 2008
+++ tidydev\src\entities.c	Fri Mar 13 12:22:57 2009
@@ -366,16 +366,18 @@
     if ( name[1] == '#' )
     {
         uint c = 0;  /* zero on missing/bad number */
-
+        int res;
         /* 'x' prefix denotes hexadecimal number format */
         if ( name[2] == 'x' || (!isXml && name[2] == 'X') )
-            sscanf( name+3, "%x", &c );
+            res = sscanf( name+3, "%x", &c );
         else
-            sscanf( name+2, "%u", &c );
-
-        *code = c;
-        *versions = VERS_ALL;
-        return yes;
+            res = sscanf( name+2, "%u", &c );
+        if ( res != -1 )
+        {
+           *code = c;
+           *versions = VERS_ALL;
+           return yes;
+        }
     }
 
     /* Named entity: name ="&" followed by a name */
diff -ur -x *.manifest -x *.map tidycvs\src\fileio.c tidydev\src\fileio.c
--- tidycvs\src\fileio.c	Wed May 30 18:47:31 2007
+++ tidydev\src\fileio.c	Sun Mar 28 11:13:08 2010
@@ -83,10 +83,77 @@
     tidyBufFree( &fin->unget );
     TidyFree( fin->unget.allocator, fin );
 }
+#ifndef NDEBUG
+#define MMXSB   32
+extern int __cdecl sprtf( char * pf, ... );
+static char _s_buf[MMXSB+4];
+static int _s_outcnt = 0;
+int InStr(char * lpb, char * lps)
+{
+   int   iRet = 0;
+   int   i, j, k, l, m;
+   char  c;
+   i = strlen(lpb);
+   j = strlen(lps);
+   if( i && j && ( i >= j ) ) {
+      c = *lps;   /* get the first char we are looking for... */
+      l = i - ( j - 1 );   /* get the maximum length to search */
+      for( k = 0; k < l; k++ ) {
+         if( lpb[k] == c ) {
+            /* found the FIRST char so check until end of compare string */
+            for( m = 1; m < j; m++ ) {
+               if( lpb[k+m] != lps[m] )   /* on first NOT equal */
+                  break;   /* out of here */
+            }
+            if( m == j ) {  /* if we reached the end of the search string */
+               iRet = k + 1;  /* return NUMERIC position (that is LOGICAL + 1) */
+               break;   /* and out of the outer search loop */
+            }
+         }
+      }  /* for the search length */
+   }
+   return iRet;
+}
+
+int debug_stop2(int len)
+{
+    int i;
+    i = len;
+    return i;
+}
+#endif
 
 void TIDY_CALL TY_(filesink_putByte)( void* sinkData, byte bv )
 {
   FILE* fout = (FILE*) sinkData;
+#ifndef NDEBUG
+  {
+     int i;
+     char * sb = _s_buf;
+     for (i = 0; i < MMXSB; i++)
+         sb[i] = sb[i+1];
+     sb[_s_outcnt++] = bv;
+     sb[_s_outcnt] = 0;
+     if (_s_outcnt > MMXSB)
+         _s_outcnt = MMXSB;
+     /* ======================= */
+     /* i = InStr(sb,"<dev>"); */
+     /* if (i == (MMXSB + 2 - 5)) */
+     i = InStr(sb,"antony/index.htm");
+     if (i == (MMXSB + 2 - 16))
+         debug_stop2(i);
+     /* ======================= */
+     if (bv >= ' ')
+        sprtf("%c",bv);
+     else
+     {
+        byte b = bv + '@';
+        sprtf("^%c",b);
+        if( bv == '\n' )
+           sprtf("\r\n");
+     }
+  }
+#endif
   fputc( bv, fout );
 }
 
diff -ur -x *.manifest -x *.map tidycvs\src\istack.c tidydev\src\istack.c
--- tidycvs\src\istack.c	Fri Dec 29 17:31:08 2006
+++ tidydev\src\istack.c	Wed Apr 16 11:37:38 2008
@@ -11,6 +11,9 @@
 
 */
 
+#ifndef NDEBUG
+#include "istack-dbg.c"
+#else /* is NDEBUG = normal */
 #include "tidy-int.h"
 #include "lexer.h"
 #include "attrs.h"
@@ -294,7 +297,8 @@
    but, like the browser, the second should be retained ...
    Like <b>bold <i>bold and italics</b> italics only</i>
    This function switches the tag positions on the stack,
-   returning 'yes' if both were found in the expected order.
+   returning 'yes' if both were found,
+   and swaps them if in the expected order.
 */
 Bool TY_(SwitchInline)( TidyDocImpl* doc, Node* element, Node* node )
 {
@@ -306,7 +310,7 @@
          && TY_(IsPushed)( doc, node ) 
          && ((lexer->istacksize - lexer->istackbase) >= 2) )
     {
-        /* we have a chance of succeeding ... */
+        /* we have every chance of succeeding ... */
         int i;
         for (i = (lexer->istacksize - lexer->istackbase - 1); i >= 0; --i)
         {
@@ -326,12 +330,12 @@
                 }
                 if ( istack2 )
                 {
-                    /* perform the swap */
+                    /* perform the swap if in expected order */
                     IStack tmp_istack = *istack2;
                     *istack2 = *istack1;
                     *istack1 = tmp_istack;
-                    return yes;
                 }
+                return yes;   /* and return success in any case */
             }
         }
     }
@@ -371,3 +375,6 @@
  * eval: (c-set-offset 'substatement-open 0)
  * end:
  */
+
+#endif /* is NDEBUG y/n */
+
diff -ur -x *.manifest -x *.map tidycvs\src\lexer.c tidydev\src\lexer.c
--- tidycvs\src\lexer.c	Tue Jan 10 17:23:20 2012
+++ tidydev\src\lexer.c	Wed Jan 11 14:53:37 2012
@@ -46,6 +46,9 @@
 #include "utf8.h"
 #include "streamio.h"
 
+#ifndef NDEBUG
+extern int __cdecl sprtf( char * pf, ... );
+#endif
 /* Forward references
 */
 /* swallows closing '>' */
@@ -782,6 +785,11 @@
 
 static void SetLexerLocus( TidyDocImpl* doc, Lexer *lexer )
 {
+#ifndef NDEBUG
+    sprtf("SetLexerLocus: From %d,%d to %d,%d\n",
+        lexer->lines, lexer->columns,
+        doc->docIn->curline, doc->docIn->curcol );
+#endif
     lexer->lines = doc->docIn->curline;
     lexer->columns = doc->docIn->curcol;
 }
@@ -1807,6 +1815,9 @@
     CDATA_ENDTAG
 } CDATAState;
 
+/* forward reference */
+Bool TY_(LexerInJavaComment)( TidyDocImpl* doc );
+
 static Node *GetCDATA( TidyDocImpl* doc, Node *container )
 {
     Lexer* lexer = doc->lexer;
@@ -1852,8 +1863,13 @@
                     return NULL;
                 }
                 TY_(AddCharToLexer)(lexer, c);
-                start = lexer->lexsize - 1;
-                state = CDATA_STARTTAG;
+                start = lexer->lexsize - 1;  /* set start of lexer to -> '<' char */
+                /* if javascript, only if NOT in a comment */
+                if ( TY_(IsJavaScript)( container ) &&
+                     !TY_(LexerInJavaComment)( doc ) )
+                {
+                    state = CDATA_STARTTAG;
+                }
             }
             else if (c == '/')
             {
@@ -1868,6 +1884,27 @@
                 }
                 TY_(UngetChar)(c, doc->docIn);
 
+                /* had < + / + letter */
+                if ( TY_(IsJavaScript)( container ) &&
+                     TY_(LexerInJavaComment)( doc ) )
+                {
+                   start = lexer->lexsize - 1;
+                   SetLexerLocus( doc, lexer );
+                   /* if javascript insert backslash before /
+                      EXCEPT if XHTML */
+                   if ( !( TY_(HTMLVersion)(doc) & (X10S|X10T) ) )
+                   {
+                       lexer->columns -= 3;
+                       TY_(ReportError)(doc, NULL, NULL, BAD_CDATA_CONTENT_INSERTED);
+                       for (i = lexer->lexsize; i > start; --i)
+                           lexer->lexbuf[i] = lexer->lexbuf[i-1];
+
+                       lexer->lexbuf[start] = '\\';
+                       lexer->lexsize++;
+                   }
+                   continue;
+                }
+
                 start = lexer->lexsize;
                 state = CDATA_ENDTAG;
             }
@@ -1895,7 +1932,11 @@
                 TY_(UngetChar)(c, doc->docIn);
 
                 start = lexer->lexsize;
-                state = CDATA_ENDTAG;
+                if ( TY_(IsJavaScript)( container ) &&
+                     !TY_(LexerInJavaComment)( doc ) )
+                {
+                   state = CDATA_ENDTAG;
+                }
             }
             else
             {
@@ -1949,16 +1990,18 @@
                 /* if the end tag is not already escaped using backslash */
                 SetLexerLocus( doc, lexer );
                 lexer->columns -= 3;
-                TY_(ReportError)(doc, NULL, NULL, BAD_CDATA_CONTENT);
 
                 /* if javascript insert backslash before / */
                 if (TY_(IsJavaScript)(container))
                 {
+                    TY_(ReportError)(doc, NULL, NULL, BAD_CDATA_CONTENT_INSERTED);
                     for (i = lexer->lexsize; i > start-1; --i)
                         lexer->lexbuf[i] = lexer->lexbuf[i-1];
 
                     lexer->lexbuf[start-1] = '\\';
                     lexer->lexsize++;
+                } else {
+                    TY_(ReportError)(doc, NULL, NULL, BAD_CDATA_CONTENT);
                 }
             }
             state = CDATA_INTERMEDIATE;
@@ -2014,6 +2057,10 @@
 */
 static Node* GetTokenFromStream( TidyDocImpl* doc, GetTokenMode mode );
 
+#ifndef  NDEBUG
+#include "lexer-dbg.c"
+#else /* !#ifndef  NDEBUG */
+
 Node* TY_(GetToken)( TidyDocImpl* doc, GetTokenMode mode )
 {
     Lexer* lexer = doc->lexer;
@@ -2057,6 +2104,9 @@
     return GetTokenFromStream( doc, mode );
 }
 
+#endif   /* #ifndef  NDEBUG y/n */
+
+
 static Node* GetTokenFromStream( TidyDocImpl* doc, GetTokenMode mode )
 {
     Lexer* lexer = doc->lexer;
@@ -2118,7 +2168,9 @@
                         if (mode != Preformatted && mode != IgnoreMarkup)
                         {
                             --(lexer->lexsize);
-                            SetLexerLocus( doc, lexer );
+                            /* 2811690 - SetLexerLocus( doc, lexer ); - does not seem necessary
+                               and causes the line/column report for this item to be
+                               grossly incremented */
                         }
                     }
                     else /* prev character wasn't white */
@@ -2173,8 +2225,9 @@
                                 lexer->txtend = lexer->lexsize;
                             }
                             lexer->token = TY_(TextToken)(lexer);
-#ifdef TIDY_STORE_ORIGINAL_TEXT
-                            StoreOriginalTextInToken(doc, lexer->token, 3);
+#ifdef TIDY_STORE_ORIGINAL_TEXT /* FIX20090712 - reduce to 2,
+                                   since now UngetChar did 1! */
+                            StoreOriginalTextInToken(doc, lexer->token, 2); /* was 3 */
 #endif
                             return lexer->token;
                         }
@@ -3820,6 +3873,68 @@
     TY_(ReportError)(doc, NULL, NULL, MALFORMED_DOCTYPE);
     TY_(FreeNode)(doc, node);
     return NULL;
+}
+
+Bool TY_(LexerInJavaComment)( TidyDocImpl* doc )
+{
+    Lexer* lexer = doc->lexer;
+    uint i;
+    tmbchar c, last, inQuote;
+    Bool inComment1 = no;
+    Bool inComment2 = no;
+    if ( lexer && ( lexer->lexsize > lexer->txtstart ) )
+    {
+       last = 0;
+       inQuote = 0;
+       for( i = lexer->txtstart; i < lexer->txtend; i++ )
+       {
+          c = lexer->lexbuf[i];
+          if ( inQuote )
+          {
+             if ( ( ( c == inQuote ) && ( last != '\\' ) ) ||
+                  ( c == '\n' ) )
+                  inQuote = 0;
+          }
+          else if ( inComment1 )
+          {
+             /* have a '/*' start */
+             if (( c == '/' ) && ( last == '*' ))
+                inComment1 = no;
+          }
+          else if ( inComment2 )
+          {
+             /* have a '//' start */
+             if ( c == '\n' )
+                inComment2 = no;
+          }
+          else
+          {
+             /* not in any comment yet */
+             if ( c == '/' )
+             {
+                if ( last == '/' )
+                {
+                   inComment2 = yes; /* in a comment, until EOL */
+                }
+             }
+             else if ( c == '*' )
+             {
+                if ( last == '/' )
+                {
+                   inComment1 = yes;   /* in a comment, until '*'+'/' */
+                }
+             }
+             else if (( c == '"' ) || ( c == 0x27 ))
+             {
+                inQuote = c;
+             }
+          }
+          last = c;
+       }
+       if ( inQuote || inComment1 || inComment2 )
+          return yes;
+    }
+    return no;
 }
 
 /*
diff -ur -x *.manifest -x *.map tidycvs\src\localize.c tidydev\src\localize.c
--- tidycvs\src\localize.c	Wed Jun 18 22:18:54 2008
+++ tidydev\src\localize.c	Wed Jan 11 14:13:13 2012
@@ -119,6 +119,7 @@
   { MISSING_ENDTAG_BEFORE,        "missing </%s> before %s"                                                 }, /* Error */
   { DISCARDING_UNEXPECTED,        "discarding unexpected %s"                                                }, /* Error */
   { NON_MATCHING_ENDTAG,          "replacing unexpected %s by </%s>"                                        }, /* Error */
+  { REPLACING_UNEXPECTED,         "replacing unexpected </%s> by </%s>"                                        }, /* Error */
   { TAG_NOT_ALLOWED_IN,           "%s isn't allowed in <%s> elements"                                       }, /* Error */
   { MISSING_STARTTAG,             "missing <%s>"                                                            }, /* Error */
   { UNEXPECTED_ENDTAG,            "unexpected </%s>"                                                }, /* Error */
@@ -144,6 +145,7 @@
   { MALFORMED_COMMENT,            "adjacent hyphens within comment"                                         }, /* Error */
   { BAD_COMMENT_CHARS,            "expecting -- or >"                                                       }, /* Error */
   { BAD_CDATA_CONTENT,            "'<' + '/' + letter not allowed here"                                     }, /* Error */
+  { BAD_CDATA_CONTENT_INSERTED,   "'<' + '/' + letter not allowed here - inserted escape"                   }, /* Error */
   { INCONSISTENT_NAMESPACE,       "HTML namespace doesn't match content"                                    }, /* Error */
   { SPACE_PRECEDING_XMLDECL,      "removing whitespace preceding XML Declaration"                           }, /* Error */
   { MALFORMED_DOCTYPE,            "discarding malformed <!DOCTYPE>"                                         }, /* Error */
@@ -857,6 +859,10 @@
    "If set to \"no\", any existing name attribute is removed "
    "if an id attribute exists or has been added. "
   },
+  {TidyNoEqWrap,
+   "This option specifies if Tidy should pretty print output, not splitting "
+   "on an equal sign in attributes, like as in xml output."
+  },
   {N_TIDY_OPTIONS,
    NULL
   }
@@ -950,8 +956,13 @@
 
     /* Change formatting to be parsable by GNU Emacs */
     if ( cfgBool(doc, TidyEmacs) && cfgStr(doc, TidyEmacsFile) )
+#ifdef _MSC_VER
+        TY_(tmbsnprintf)(buf, count, "%s(%d,%d) ",
+                         cfgStr(doc, TidyEmacsFile), line, col);
+#else /* NOT _MSC_VER */
         TY_(tmbsnprintf)(buf, count, "%s:%d:%d: ", 
                          cfgStr(doc, TidyEmacsFile), line, col);
+#endif /* _MSC_VER y/n */
     else /* traditional format */
         TY_(tmbsnprintf)(buf, count, "line %d column %d - ", line, col);
     return buf + TY_(tmbstrlen)( buf );
@@ -1477,6 +1488,7 @@
     case BAD_COMMENT_CHARS:
     case BAD_XML_COMMENT:
     case BAD_CDATA_CONTENT:
+    case BAD_CDATA_CONTENT_INSERTED:
     case INCONSISTENT_NAMESPACE:
     case DOCTYPE_AFTER_TAGS:
     case DTYPE_NOT_UPPER_CASE:
@@ -1486,6 +1498,9 @@
     case COERCE_TO_ENDTAG:
     case NON_MATCHING_ENDTAG:
         messageNode(doc, TidyWarning, rpt, fmt, node->element, node->element);
+        break;
+    case REPLACING_UNEXPECTED:
+        messageNode(doc, TidyWarning, rpt, fmt, node->element, rpt->element);
         break;
 
     case UNEXPECTED_ENDTAG_IN:
diff -ur -x *.manifest -x *.map tidycvs\src\mappedio.c tidydev\src\mappedio.c
--- tidycvs\src\mappedio.c	Tue Mar 18 21:19:35 2008
+++ tidydev\src\mappedio.c	Sun Jul 12 11:53:01 2009
@@ -107,6 +107,9 @@
 #pragma warning(disable:4115) /* named type definition in parentheses in windows headers */
 #endif
 #include <windows.h>
+#ifndef   NDEBUG
+#include "sprtf.h"
+#endif
 
 typedef struct _fp_input_mapped_source
 {
@@ -144,6 +147,9 @@
 {
     MappedFileSource *data = sourceData;
 
+#ifndef  NDEBUG
+    int  ch;
+#endif
     if ( !data->view || data->iter >= data->end )
     {
         data->pos += data->gran;
@@ -152,7 +158,17 @@
             return EndOfStream;
     }
 
+#ifdef   NDEBUG
     return *( data->iter++ );
+#else
+/* int __cdecl sprtf( char * pf, ... ); */
+    ch = *( data->iter++ );
+    sprtf( "%c", ch );
+/*    if( ch == '#' ) */
+    if( ch == '\t' )
+       sprtf( "<debug stop>" );
+    return ch;
+#endif
 }
 
 static Bool TIDY_CALL mapped_eof( void *sourceData )
diff -ur -x *.manifest -x *.map tidycvs\src\message.h tidydev\src\message.h
--- tidycvs\src\message.h	Wed May 30 18:47:31 2007
+++ tidydev\src\message.h	Wed Apr 16 11:15:06 2008
@@ -103,6 +103,7 @@
 #define BAD_COMMENT_CHARS            30
 #define BAD_XML_COMMENT              31
 #define BAD_CDATA_CONTENT            32
+#define BAD_CDATA_CONTENT_INSERTED   88
 #define INCONSISTENT_NAMESPACE       33
 #define DOCTYPE_AFTER_TAGS           34
 #define MALFORMED_DOCTYPE            35
@@ -159,8 +160,8 @@
 #define UNEXPECTED_END_OF_FILE_ATTR  75
 #define MISSING_ATTRIBUTE            86
 #define WHITE_IN_URI                 87
-
-#define PREVIOUS_LOCATION            88 /* last */
+#define REPLACING_UNEXPECTED         89
+#define PREVIOUS_LOCATION            90 /* last */
 
 /* character encoding errors */
 
diff -ur -x *.manifest -x *.map tidycvs\src\parser.c tidydev\src\parser.c
--- tidycvs\src\parser.c	Tue Oct 27 20:27:49 2009
+++ tidydev\src\parser.c	Mon Feb 08 20:23:34 2010
@@ -23,6 +23,11 @@
 #include "charsets.h"
 #endif
 
+#ifndef NDEBUG
+extern int __cdecl sprtf( char * lpf, ... );
+extern void _test_show( TidyDocImpl * doc, Node * node, uint level );
+#endif
+
 Bool TY_(CheckNodeIntegrity)(Node *node)
 {
 #ifndef NO_NODE_INTEGRITY_CHECK
@@ -1254,6 +1259,23 @@
             if ( nodeIsBR(node) )
                 TrimSpaces( doc, element );
 
+            if (node->implicit && !lexer->pushed)
+            {
+               /* 1747864 - check that we are NOT adding an implicit node,
+                  which is already next in the stream anyway ... */
+               Node * next = TY_(GetToken)(doc, mode);
+               if(next && (next->tag == node->tag))
+               {
+                   TY_(FreeNode)( doc, node );  /* toss this implict node */
+                   node = next;  /* use the node from the stream */
+               }
+               else
+               {
+                  /* not the same - put it back */
+                  TY_(UngetToken)( doc );
+               }
+            }
+
             TY_(InsertNodeAtEnd)(element, node);
             
             if (node->implicit)
@@ -1310,11 +1332,13 @@
 
      will get corrupted.
     */
-    if ((TY_(nodeHasCM)(element, CM_BLOCK) || nodeIsDT(element)) &&
-        !TY_(nodeHasCM)(element, CM_MIXED))
-        TY_(InlineDup)(doc, NULL);
-    else if (TY_(nodeHasCM)(element, CM_INLINE))
-        TY_(PushInline)(doc, element);
+    if ( !TY_(nodeHasCM)(element, CM_MIXED) )
+    {
+        if (TY_(nodeHasCM)(element, CM_BLOCK) || nodeIsDT(element))
+            TY_(InlineDup)(doc, NULL);
+        else if (TY_(nodeHasCM)(element, CM_INLINE))
+            TY_(PushInline)(doc, element);
+    }
 
     if ( nodeIsNOBR(element) )
         doc->badLayout |= USING_NOBR;
@@ -1530,7 +1554,7 @@
                        <b>bold <i>bold and italic</b> italics</i> */
                     if ( TY_(SwitchInline)( doc, element, node ) )
                     {
-                        TY_(ReportError)(doc, element, node, NON_MATCHING_ENDTAG);
+                        TY_(ReportError)(doc, element, node, REPLACING_UNEXPECTED);
                         TY_(UngetToken)( doc ); /* put this back */
                         TY_(InlineDup1)( doc, NULL, element ); /* dupe the <i>, after </b> */
                         if (!(mode & Preformatted))
@@ -3207,18 +3231,20 @@
                 ++HasTitle;
 
                 if (HasTitle > 1)
-                    TY_(ReportError)(doc, head, node,
-                                     head ?
-                                     TOO_MANY_ELEMENTS_IN : TOO_MANY_ELEMENTS);
+                    if (head)
+                        TY_(ReportError)(doc, head, node, TOO_MANY_ELEMENTS_IN);
+                    else
+                        TY_(ReportError)(doc, head, node, TOO_MANY_ELEMENTS);
             }
             else if ( nodeIsBASE(node) )
             {
                 ++HasBase;
 
                 if (HasBase > 1)
-                    TY_(ReportError)(doc, head, node,
-                                     head ?
-                                     TOO_MANY_ELEMENTS_IN : TOO_MANY_ELEMENTS);
+                    if (head)
+                        TY_(ReportError)(doc, head, node, TOO_MANY_ELEMENTS_IN);
+                    else
+                        TY_(ReportError)(doc, head, node, TOO_MANY_ELEMENTS);
             }
             else if ( nodeIsNOSCRIPT(node) )
             {
@@ -4216,6 +4242,11 @@
         TY_(InsertNodeAtEnd)(head, TY_(InferredTag)(doc, TidyTag_TITLE));
     }
 
+#ifndef NDEBUG
+    sprtf( "\nDone parsing - show tree\n" );
+    _test_show( doc, &doc->root, 0 );
+    sprtf( "<debug stop>" );
+#endif /* !NDEBUG */
     AttributeChecks(doc, &doc->root);
     ReplaceObsoleteElements(doc, &doc->root);
     TY_(DropEmptyElements)(doc, &doc->root);
@@ -4270,7 +4301,8 @@
 
     /* if node is pre or has xml:space="preserve" then do so */
 
-    if ( TY_(XMLPreserveWhiteSpace)(doc, element) )
+    if (( TY_(XMLPreserveWhiteSpace)(doc, element) ) ||
+        ( cfgBool(doc, TidyXmlTags) )) /* or got -xml command */
         mode = Preformatted;
 
     while ((node = TY_(GetToken)(doc, mode)) != NULL)
diff -ur -x *.manifest -x *.map tidycvs\src\pprint.c tidydev\src\pprint.c
--- tidycvs\src\pprint.c	Sat Mar 22 21:23:37 2008
+++ tidydev\src\pprint.c	Sun Mar 28 12:43:37 2010
@@ -42,6 +42,30 @@
 static Bool InsideHead( TidyDocImpl* doc, Node *node );
 static Bool ShouldIndent( TidyDocImpl* doc, Node *node );
 
+#ifdef NDEBUG
+#define SETWRAPHERE(a)  pprint->wraphere = a
+#else /* !#ifdef NDEBUG */
+extern int __cdecl sprtf( char * pf, ... );
+int debug_stop3(int val)
+{
+    int i;
+    i = val;
+    return i;
+}
+static void set_wrap_here( TidyPrintImpl* pprint, uint val, int line, char * func )
+{
+    if (pprint->wraphere != val) {
+        sprtf("%s:%d: Change wraphere from %d to %d\n", func, line, pprint->wraphere, val );
+        pprint->wraphere = val;
+        if ( val == 63 )
+            debug_stop3(val);
+    }
+}
+#define SETWRAPHERE(a)  set_wrap_here(pprint,a,__LINE__,__FUNCTION__)
+
+#endif /* #ifdef NDEBUG y/n */
+
+
 #if SUPPORT_ASIAN_ENCODINGS
 /* #431953 - start RJ Wraplen adjusted for smooth international ride */
 
@@ -462,7 +486,7 @@
     {
         if ( pprint->indent[0].spaces < 0 )
             pprint->indent[0].spaces = indent;
-        pprint->wraphere = pprint->linelen;
+        SETWRAPHERE(pprint->linelen);
     }
     else if ( pprint->ixInd == 0 )
     {
@@ -723,7 +747,7 @@
             return;
         }
         else
-            pprint->wraphere = pprint->linelen;
+            SETWRAPHERE(pprint->linelen);
     }
 
     /* comment characters are passed raw */
@@ -804,9 +828,9 @@
         {
             WrapPoint wp = CharacterWrapPoint(c);
             if (wp == WrapBefore)
-                pprint->wraphere = pprint->linelen;
+                SETWRAPHERE(pprint->linelen);
             else if (wp == WrapAfter)
-                pprint->wraphere = pprint->linelen + 1;
+                SETWRAPHERE((pprint->linelen + 1));
         }
         break;
 
@@ -818,9 +842,9 @@
         {
             WrapPoint wp = Big5WrapPoint(c);
             if (wp == WrapBefore)
-                pprint->wraphere = pprint->linelen;
+                SETWRAPHERE(pprint->linelen);
             else if (wp == WrapAfter)
-                pprint->wraphere = pprint->linelen + 1;
+                SETWRAPHERE((pprint->linelen + 1));
         }
         return;
 
@@ -1011,8 +1035,9 @@
 
     AddChar( pprint, '=' );
 
-    /* don't wrap after "=" for xml documents */
-    if ( !cfgBool(doc, TidyXmlOut) || cfgBool(doc, TidyXhtmlOut) )
+    /* don't wrap after "=" for xml documents, or on a user request */
+    if ( !(cfgBool(doc, TidyXmlOut) || cfgBool(doc, TidyXhtmlOut) ||
+        cfgBool(doc, TidyNoEqWrap) ) )
     {
         SetWrap( doc, indent );
         CheckWrapIndent( doc, indent );
@@ -1367,7 +1392,7 @@
                 && (!TY_(nodeCMIsInline)(node) || nodeIsBR(node))
                 && AfterSpace(doc->lexer, node))
             {
-                pprint->wraphere = pprint->linelen;
+                SETWRAPHERE(pprint->linelen);
             }
         }
         /* flush the current buffer only if it is known to be safe,
diff -ur -x *.manifest -x *.map tidycvs\src\streamio.c tidydev\src\streamio.c
--- tidycvs\src\streamio.c	Sat Mar 22 22:00:18 2008
+++ tidydev\src\streamio.c	Mon Feb 08 20:26:56 2010
@@ -242,6 +242,18 @@
 }
 
 #ifdef TIDY_STORE_ORIGINAL_TEXT
+#ifdef _MSC_VER
+#pragma message("NOTE: TIDY_STORE_ORIGINAL_TEXT is ON!")
+#endif
+/* FIX20090712 - new service to unget original store */
+void TY_(UngetCharOriginalText) (StreamIn *in)
+{
+    if (in->otextlen) {
+        in->otextlen--;
+        in->otextbuf[in->otextlen] = 0; /* zero terminate the string */
+    }
+}
+
 void TY_(AddByteToOriginalText)(StreamIn *in, tmbchar c)
 {
     if (in->otextlen + 1 >= in->otextsize)
@@ -322,7 +334,7 @@
 
     if ( in->tabs > 0 )
     {
-        in->curcol++;
+        /* why is this done? in->curcol++; this is purely a tab expansion */
         in->tabs--;
         return ' ';
     }
@@ -527,10 +539,16 @@
             in->curcol = 1;
             in->curline++;
             PopLastPos( in );
+#ifdef TIDY_STORE_ORIGINAL_TEXT /* FIX20090712 */
+            TY_(AddCharToOriginalText)(in, (tchar)c);
+#endif
             return c;
         }
         in->curcol++;
         PopLastPos( in );
+#ifdef TIDY_STORE_ORIGINAL_TEXT /* FIX20090712 */
+        TY_(AddCharToOriginalText)(in, (tchar)c);
+#endif
     }
     return c;
 }
@@ -552,6 +570,10 @@
 
     if (c == '\n')
         --(in->curline);
+
+#ifdef TIDY_STORE_ORIGINAL_TEXT /* FIX20090712 */
+    TY_(UngetCharOriginalText) (in);
+#endif
 
     RestoreLastPos( in );
 }
diff -ur -x *.manifest -x *.map tidycvs\src\tags.c tidydev\src\tags.c
--- tidycvs\src\tags.c	Tue Jan 10 17:23:20 2012
+++ tidydev\src\tags.c	Wed Jan 11 14:49:51 2012
@@ -994,6 +994,25 @@
     return 0;
 }
 
+/* new 20070818 - tags that normally contain text */
+Bool TY_(nodeIsTextLike)( Node * node )
+{
+   switch ( node->type )
+   {
+   case TextNode:	  /* yes for sure */
+   case CDATATag:   /* maybe??? */
+   case SectionTag: /* maybe??? */
+   case AspTag:     /* yes? */
+   case JsteTag:    /* yes? */
+   case PhpTag:     /* yes for sure */
+      return yes;
+   }
+   return no;
+}
+
+const Dict * get_tag_block( void ) { return &tag_defs[0]; }
+
+
 /*
  * local variables:
  * mode: c
diff -ur -x *.manifest -x *.map tidycvs\src\tags.h tidydev\src\tags.h
--- tidycvs\src\tags.h	Fri Dec 15 11:17:55 2006
+++ tidydev\src\tags.h	Sun Sep 02 15:32:46 2007
@@ -128,6 +128,8 @@
 
 Bool TY_(nodeHasText)( TidyDocImpl* doc, Node* node );
 
+Bool TY_(nodeIsTextLike)( Node * node ); /* new 20070818 - tags that normally contain text */
+
 #if 0
 /* Compare & result to operand.  If equal, then all bits
 ** requested are set.
diff -ur -x *.manifest -x *.map tidycvs\src\tidylib.c tidydev\src\tidylib.c
--- tidycvs\src\tidylib.c	Tue Jan 10 17:23:20 2012
+++ tidydev\src\tidylib.c	Wed Jan 11 14:51:12 2012
@@ -41,6 +41,11 @@
 #include "win32tc.h"
 #endif
 
+#ifndef  NDEBUG
+#include "..\src\sprtf.h"
+void  _test_show( TidyDocImpl * doc, Node * node, uint level );
+#endif   /* if DEBUG */
+
 /* Create/Destroy a Tidy "document" object */
 static TidyDocImpl* tidyDocCreate( TidyAllocator *allocator );
 static void         tidyDocRelease( TidyDocImpl* impl );
@@ -157,6 +162,9 @@
     ** But we need to start off with a way to report errors.
     */
     doc->errout = TY_(StdErrOutput)();
+#ifdef TIDY_STORE_ORIGINAL_TEXT /* FIX20090712 */
+    doc->storeText = yes;
+#endif
     return doc;
 }
 
@@ -1267,8 +1275,15 @@
         /* prune Word2000's <![if ...]> ... <![endif]> */
         TY_(DropSections)( doc, &doc->root );
 
+/* #if   (defined XTRA_DEBUG2 && !defined(NDEBUG)) */
+#ifndef NDEBUG
+         sprtf( "\nBEFORE calling CleanWord2000, calling _test_show ...\n" );
+         _test_show( doc, &doc->root, 0 );
+         sprtf("<debug stop>");
+#endif   /* if DEBUG */
         /* drop style & class attributes and empty p, span elements */
         TY_(CleanWord2000)( doc, &doc->root );
+        TY_(CleanWord2003)( doc, &doc->root );
         TY_(DropEmptyElements)(doc, &doc->root);
     }
 
@@ -1412,10 +1427,24 @@
 
     if ( showMarkup && (doc->errors == 0 || forceOutput) )
     {
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+        {
+            char * type = "PPrintTree";
+            if ( xmlOut && !xhtmlOut )
+                type = "PPrintXMLTree";
+            else if ( showBodyOnly( doc, bodyOnly ) )
+                type = "PrintBody";
+            sprtf("Output stream via %s...\n", type);
+        }
+#endif
 #if SUPPORT_UTF16_ENCODINGS
         /* Output a Byte Order Mark if required */
-        if ( outputBOM || (doc->inputHadBOM && smartBOM) )
+        if ( outputBOM || (doc->inputHadBOM && smartBOM) ) {
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+            sprtf("Output BOM...\n");
+#endif
             TY_(outBOM)( out );
+        }
 #endif
 
         /* No longer necessary. No DOCTYPE == HTML 3.2,
diff -ur -x *.manifest -x *.map tidycvs\src\version.h tidydev\src\version.h
--- tidycvs\src\version.h	Tue Jan 10 19:26:29 2012
+++ tidydev\src\version.h	Wed Jan 11 15:00:27 2012
@@ -11,4 +11,8 @@
 
 */
 
-static const char TY_(release_date)[] = "10 January 2012";
+/* static const char TY_(release_date)[] = "7 December 2008"; */
+/* static const char TY_(release_date)[] = "20 January 2009\nDEVELOPMENT VERSION"; */
+/* static const char TY_(release_date)[] = "26 March 2009\nDEVELOPMENT VERSION"; */
+static const char TY_(release_date)[] = "11 January 2012\nDEVELOPMENT VERSION, with HTML5 support";
+
