From 1c72ffcbe310e13d7dda73fa78d6ea4f93636c3e Mon Sep 17 00:00:00 2001
From: Dimitri van Heesch <dimitri@stack.nl>
Date: Sun, 15 Sep 2002 19:55:15 +0000
Subject: Release-1.2.17-20020915

---
 INSTALL                   |    4 +-
 README                    |    4 +-
 VERSION                   |    2 +-
 doc/commands.doc          |   36 +-
 doc/config.doc            |   29 +
 doc/index.doc             |    2 +-
 packages/rpm/doxygen.spec |    2 +-
 src/config.l              |   35 +-
 src/doc.l                 |    2 +-
 src/docparser.cpp         |  793 +++++++++++---------
 src/docparser.h           |   63 +-
 src/docvisitor.h          |    3 +-
 src/dot.cpp               |    1 +
 src/htmldocvisitor.cpp    |   29 +-
 src/htmldocvisitor.h      |    3 +-
 src/htmlgen.cpp           |   16 +-
 src/latexdocvisitor.cpp   |   99 ++-
 src/latexdocvisitor.h     |    4 +-
 src/latexgen.cpp          |   16 +-
 src/libdoxygen.pro.in     |    4 +-
 src/mangen.cpp            |   21 +-
 src/mangen.h              |    2 +
 src/outputgen.h           |    2 +-
 src/outputlist.cpp        |   15 +-
 src/pre.l                 |   13 +-
 src/printdocvisitor.h     |   15 +-
 src/rtfdocvisitor.cpp     |  549 +++++++-------
 src/rtfdocvisitor.h       |    5 +-
 src/rtfgen.cpp            |   50 +-
 src/rtfgen.h              |    2 +
 src/rtfstyle.cpp          |    2 +-
 src/rtfstyle.h            |    7 +-
 src/scanner.l             |   19 +-
 src/section.h             |    2 +-
 src/util.cpp              |    4 +-
 src/xmldocvisitor.cpp     |  737 +++++++++++++++++++
 src/xmldocvisitor.h       |  147 ++++
 src/xmlgen.cpp            | 1790 +++++++++++++++++++++++++--------------------
 38 files changed, 2993 insertions(+), 1536 deletions(-)
 create mode 100644 src/xmldocvisitor.cpp
 create mode 100644 src/xmldocvisitor.h

diff --git a/INSTALL b/INSTALL
index b679d97..15e5d56 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,6 @@
-DOXYGEN Version 1.2.17-20020901
+DOXYGEN Version 1.2.17-20020915
 
 Please read the installation section of the manual for instructions.
 
 --------
-Dimitri van Heesch (01 September 2002)
+Dimitri van Heesch (15 September 2002)
diff --git a/README b/README
index d39ad5d..ef80b4e 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.2.17_20020901
+DOXYGEN Version 1.2.17_20020915
 
 Please read INSTALL for compilation instructions.
 
@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
 
 Enjoy,
 
-Dimitri van Heesch (dimitri@stack.nl) (01 September 2002)
+Dimitri van Heesch (dimitri@stack.nl) (15 September 2002)
diff --git a/VERSION b/VERSION
index 98b96a6..6ab16e8 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.2.17-20020901
+1.2.17-20020915
diff --git a/doc/commands.doc b/doc/commands.doc
index 8a95ab6..42d4c8d 100644
--- a/doc/commands.doc
+++ b/doc/commands.doc
@@ -116,6 +116,7 @@ documentation:
 \refitem cmdskipline \\skipline
 \refitem cmdstruct \\struct
 \refitem cmdsubsection \\subsection
+\refitem cmdsubsubsection \\subsubsection
 \refitem cmdtest \\test
 \refitem cmdthrow \\throw
 \refitem cmdtodo \\todo
@@ -1106,7 +1107,8 @@ ALIASES  = "english=\if english" \
   subsection should be specified as the second argument of the \\subsection
   command.
 
-  \warning This command only works inside related page documentation and
+  \warning This command only works inside a section of a related page 
+           documentation block and
            \e not in other documentation blocks!
 
   \sa
@@ -1114,6 +1116,38 @@ ALIASES  = "english=\if english" \
            \ref cmdsubsection "\\subsection" command.
 
 <hr>
+\section cmdsubsubsection \subsubsection <subsubsection-name> (subsubsection title)
+
+  \addindex \\subsubsection
+  Creates a subsubsection with name \<subsubsection-name\>. The title of the
+  subsubsection should be specified as the second argument of the 
+  \\subsubsection command.
+
+  \warning This command only works inside a subsection of a 
+           related page documentation block and
+           \e not in other documentation blocks!
+
+  \sa
+   Section \ref cmdpage "\\page" for an example of the 
+           \ref cmdsubsubsection "\\subsubsection" command.
+
+<hr>
+\section cmdparagraph \paragraph <paragraph-name> (paragraph title)
+
+  \addindex \\paragraph
+  Creates a named paragraph with name \<paragraph-name\>. The title of the
+  paragraph should be specified as the second argument of the 
+  \\paragraph command.
+
+  \warning This command only works inside a subsubsection of a 
+           related page documentation block and
+           \e not in other documentation blocks!
+
+  \sa
+   Section \ref cmdpage "\\page" for an example of the 
+           \ref cmdparagraph "\\paragraph" command.
+
+<hr>
 
 <h2>\htmlonly <center> --- \endhtmlonly 
     Commands for displaying examples
diff --git a/doc/config.doc b/doc/config.doc
index 3f38ee0..974f7f4 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -113,6 +113,7 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_generate_testlist GENERATE_TESTLIST
 \refitem cfg_generate_todolist GENERATE_TODOLIST
 \refitem cfg_generate_treeview GENERATE_TREEVIEW
+\refitem cfg_generate_xml GENERATE_XML
 \refitem cfg_graphical_hierarchy GRAPHICAL_HIERARCHY
 \refitem cfg_have_dot HAVE_DOT
 \refitem cfg_hhc_location HHC_LOCATION
@@ -190,6 +191,8 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_warn_if_undocumented WARN_IF_UNDOCUMENTED
 \refitem cfg_warn_logfile WARN_LOGFILE
 \refitem cfg_warnings WARNINGS
+\refitem cfg_xml_dtd XML_DTD
+\refitem cfg_xml_schema XML_SCHEMA
 \endsecreflist
 
 \section config_general General options
@@ -1132,6 +1135,32 @@ EXTRA_PACKAGES = times
 
 </dl>
 
+\section xml_output XML related options
+\anchor cfg_generate_xml
+<dl>
+
+<dt>\c GENERATE_XML <dd>
+ \addindex GENERATE_XML
+ If the GENERATE_XML tag is set to YES Doxygen will
+ generate an XML file that captures the structure of
+ the code including all documentation. 
+
+\anchor cfg_xml_schema
+<dt>\c XML_SCHEMA <dd>
+ \addindex XML_SCHEMA
+ The XML_SCHEMA file can be used to specify an XML schema,
+ which can be used by a validating XML parser to check the
+ syntax of the XML files.
+
+\anchor cfg_xml_dtd
+<dt>\c XML_DTD <dd>
+ \addindex XML_DTD
+ The XML_DTD file can be used to specify an XML DTD,
+ which can be used by a validating XML parser to check the
+ syntax of the XML files.
+
+</dl>
+
 \section config_prepro Preprocessor related options
 \anchor cfg_enable_preprocessing
 <dl>
diff --git a/doc/index.doc b/doc/index.doc
index da5246a..5639b61 100644
--- a/doc/index.doc
+++ b/doc/index.doc
@@ -180,7 +180,7 @@ Thanks go to:
     All language maintainers for providing translations into many languages.
 <li>Erik Jan Lingen of <a href="http://www.habanera.nl/">Habanera</a>, Mark
     Roddy, Paul Schwartz, Charles Duffy, Vadym Voznyuk, Philip Walton,
-    Dwight Browne, and Andreas Fredriksson for donating money.
+    Dwight Browne, Andreas Fredriksson, and Karel Lindveld for donating money.
 <li>The Comms group of <a href="http://www.symbian.com">Symbian</a> for donating
     an ultra cool <a href="http://www.psion.com/revoplus">Revo plus</a> 
     organizer!
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index a75c06a..034ada1 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,6 +1,6 @@
 Summary: A documentation system for C/C++.
 Name: doxygen
-Version: 1.2.17_20020901
+Version: 1.2.17_20020915
 Release: 1
 Epoch: 1
 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz
diff --git a/src/config.l b/src/config.l
index 86b11eb..07fde20 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1186,12 +1186,31 @@ void Config::check()
   }
 
 #undef PUTENV
+#undef GETENV
+#undef SEP
 #if defined(_WIN32) && !defined(__GNUC__) && (__BORLANDC__ < 0x0550)
 #define PUTENV _putenv
-#else
+#define GETENV _getenv
+#define SEP ";"
+#else 
 #define PUTENV putenv
+#define GETENV getenv
+#define SEP ":"
 #endif
-  if (Config_getBool("HAVE_DOT")) PUTENV("DOTFONTPATH=.");
+  if (Config_getBool("HAVE_DOT")) 
+  {
+    char *curFontPath = GETENV("DOTFONTPATH");
+    int l=curFontPath ? strlen(curFontPath)+1 : 0;
+    static char *buf = 0;
+    buf = (char *)realloc(buf,strlen("DOTFONTPATH=.")+l+1);
+    strcpy(buf,"DOTFONTPATH=.");
+    if (l>0)
+    {
+      strcat(buf,SEP);
+      strcat(buf,curFontPath);
+    }
+    PUTENV(buf);
+  }
   
 }
 
@@ -2148,6 +2167,18 @@ void Config::create()
 		    "moment. \n",
 		    FALSE
                  );
+  cs = addString(
+                    "XML_SCHEMA",
+		    "The XML_SCHEMA file can be used to specify an XML schema, \n"
+		    "which can be used by a validating XML parser to check the \n"
+		    "syntax of the XML files. \n"
+                 );
+  cs = addString(
+                    "XML_DTD",
+		    "The XML_DTD file can be used to specify an XML DTD, \n"
+		    "which can be used by a validating XML parser to check the \n"
+		    "syntax of the XML files. \n"
+                 );
   //--------------------------------------------------------------------------
   addInfo(  "DEF","configuration options for the AutoGen Definitions output");
   //--------------------------------------------------------------------------
diff --git a/src/doc.l b/src/doc.l
index 42dd41f..2ce0a96 100644
--- a/src/doc.l
+++ b/src/doc.l
@@ -2763,7 +2763,7 @@ LINKMASK  [^ \t\n\r\\@<&$]+("("[^\n)]*")")?({B}*("const"|"volatile"))?
 					    {
 					      outDoc->newParagraph(); 
 					    }
-					    if (ib && currentListIndent.top()=="P") 
+					    if (ib && *currentListIndent.top()=='P') 
 					    { // inside paragraph block
 					      endBlock();
 					    }
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 5e4a79c..415e9cd 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -24,6 +24,7 @@
 #include <qcstring.h>
 #include <qstack.h>
 #include <qdict.h>
+#include <qregexp.h>
 #include <ctype.h>
 
 #include "doxygen.h"
@@ -35,24 +36,30 @@
 #include "doctokenizer.h"
 #include "cmdmapper.h"
 #include "printdocvisitor.h"
+#include "message.h"
 
 #define DBG(x) do {} while(0)
 //#define DBG(x) printf x
 
 //---------------------------------------------------------------------------
 
+static bool        g_hasParamCommand;
+static MemberDef * g_memberDef;
+static QDict<void> g_paramsFound;
+
 // include file state
 static QCString g_includeFileText;
 static uint     g_includeFileOffset;
 static uint     g_includeFileLength;
 
 // parser state
-static QCString g_context;
-static bool g_inSeeBlock;
-static bool g_insideHtmlLink;
-static QStack<DocNode> g_nodeStack;
+static QCString               g_context;
+static bool                   g_inSeeBlock;
+static bool                   g_insideHtmlLink;
+static QStack<DocNode>        g_nodeStack;
 static QStack<DocStyleChange> g_styleStack;
-static QList<Definition> g_copyStack;
+static QList<Definition>      g_copyStack;
+static QCString               g_fileName;
 
 struct DocParserContext
 {
@@ -62,6 +69,8 @@ struct DocParserContext
   QStack<DocNode> nodeStack;
   QStack<DocStyleChange> styleStack;
   QList<Definition> copyStack;
+  MemberDef *memberDef;
+  QCString fileName;
 };
 
 static QStack<DocParserContext> g_parserStack;
@@ -78,6 +87,7 @@ static void docParserPushContext()
   ctx->nodeStack      = g_nodeStack;
   ctx->styleStack     = g_styleStack;
   ctx->copyStack      = g_copyStack;
+  ctx->fileName       = g_fileName;
   g_parserStack.push(ctx);
 }
 
@@ -90,12 +100,105 @@ static void docParserPopContext()
   g_nodeStack      = ctx->nodeStack;
   g_styleStack     = ctx->styleStack;
   g_copyStack      = ctx->copyStack;
+  g_fileName       = ctx->fileName;
   delete ctx;
   doctokenizerYYpopContext();
 }
 
 //---------------------------------------------------------------------------
 
+static void checkArgumentName(const QCString &name,bool isParam)
+{                
+  if (g_memberDef==0) return; // not a member
+  ArgumentList *al=g_memberDef->isDocsForDefinition() ? 
+		   g_memberDef->argumentList() :
+                   g_memberDef->declArgumentList();
+  if (al==0) return; // no argument list
+  if (!Config_getBool("WARN_IF_UNDOCUMENTED")) return;
+
+  static QRegExp re("[a-zA-Z0-9_]+\\.*");
+  int p=0,i=0,l;
+  while ((i=re.match(name,p,&l))!=-1)
+  {
+    QCString aName=name.mid(i,l);
+    //printf("aName=%s\n",aName.data());
+    ArgumentListIterator ali(*al);
+    Argument *a;
+    bool found=FALSE;
+    for (ali.toFirst();(a=ali.current());++ali)
+    {
+      QCString argName = g_memberDef->isDefine() ? a->type : a->name;
+      if (argName.right(3)=="...") argName=argName.left(argName.length()-3);
+      if (aName==argName) 
+      {
+	//printf("adding `%s'\n",aName.data());
+	g_paramsFound.insert(aName,(void *)(0x8));
+	found=TRUE;
+	break;
+      }
+    }
+    if (!found && isParam)
+    {
+      //printf("member type=%d\n",memberDef->memberType());
+      QCString scope=g_memberDef->getScopeString();
+      if (!scope.isEmpty()) scope+="::"; else scope="";
+      warn(g_memberDef->docFile(),g_memberDef->docLine(),
+	  "Warning: argument `%s' of command @param "
+	  "is not found in the argument list of %s%s%s",
+	  aName.data(),scope.data(),g_memberDef->name().data(),
+	  argListToString(al).data()
+	  );
+    }
+    p=i+l;
+  }
+}
+
+static void checkUndocumentedParams()
+{
+  if (g_memberDef && g_hasParamCommand && Config_getBool("WARN_IF_UNDOCUMENTED"))
+  {
+    ArgumentList *al=g_memberDef->isDocsForDefinition() ? 
+      g_memberDef->argumentList() :
+      g_memberDef->declArgumentList();
+    if (al)
+    {
+      ArgumentListIterator ali(*al);
+      Argument *a;
+      bool found=FALSE;
+      for (ali.toFirst();(a=ali.current());++ali)
+      {
+        QCString argName = g_memberDef->isDefine() ? a->type : a->name;
+        if (argName.right(3)=="...") argName=argName.left(argName.length()-3);
+        if (!argName.isEmpty() && g_paramsFound.find(argName)==0) 
+        {
+          found = TRUE;
+          break;
+        }
+      }
+      if (found)
+      {
+        QCString scope=g_memberDef->getScopeString();
+        if (!scope.isEmpty()) scope+="::"; else scope="";
+        warn(g_memberDef->docFile(),g_memberDef->docLine(),
+            "Warning: The following parameters of "
+            "%s%s%s are not documented:",
+            scope.data(),g_memberDef->name().data(),
+            argListToString(al).data());
+        for (ali.toFirst();(a=ali.current());++ali)
+        {
+          QCString argName = g_memberDef->isDefine() ? a->type : a->name;
+          if (!argName.isEmpty() && g_paramsFound.find(argName)==0) 
+          {
+            warn_cont( "  parameter %s\n",argName.data());
+          }
+        }
+      }
+    }
+  }
+}
+
+//---------------------------------------------------------------------------
+
 static QCString stripKnownExtensions(const char *text)
 {
   QCString result=text;
@@ -300,8 +403,8 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children,
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-	cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+	cmdName.data());
     return tok;
   }
   while ((tok=doctokenizerYYlex()) && tok!=TK_WHITESPACE && tok!=TK_NEWPARA)
@@ -311,16 +414,16 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children,
       switch (tok)
       {
         case TK_COMMAND: 
-	  printf("Error: Illegal command \\%s as the argument of a \\%s command at line %d\n",
-	       g_token->name.data(),cmdName.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command \\%s as the argument of a \\%s command",
+	       g_token->name.data(),cmdName.data());
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-		g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+		g_token->name.data());
           break;
       }
     }
@@ -344,8 +447,8 @@ static void handleStyleLeave(DocNode *parent,QList<DocNode> &children,DocStyleCh
       g_styleStack.top()->position()!=g_nodeStack.count() // wrong position
      )
   {
-    printf("Error: found </%s> tag at line %d without matching <%s> in the same paragraph\n",
-        tagName,doctokenizerYYlineno,tagName);
+    warn(g_fileName,doctokenizerYYlineno,"Error: found </%s> tag without matching <%s> in the same paragraph",
+        tagName,tagName);
   }
   else // end the section
   {
@@ -373,8 +476,8 @@ static void handlePendingStyleCommands(DocNode *parent,QList<DocNode> &children)
         case DocStyleChange::Subscript:   cmd = "subscript"; break;
         case DocStyleChange::Superscript: cmd = "superscript"; break;
       }
-      printf("Error: end of paragraph at line %d without end of style "
-             "command </%s>\n",doctokenizerYYlineno,cmd);
+      warn(g_fileName,doctokenizerYYlineno,"Error: end of paragraph without end of style "
+             "command </%s>",cmd);
       children.append(new DocStyleChange(parent,g_nodeStack.count(),sc->style(),FALSE));
       g_styleStack.pop();
       sc = g_styleStack.top();
@@ -496,8 +599,7 @@ static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children
             doctokenizerYYsetStateHtmlOnly();
             int retval = doctokenizerYYlex();
             children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::HtmlOnly));
-            if (retval==0) printf("Error: htmlonly section ended without end marker at line %d\n",
-                doctokenizerYYlineno);
+            if (retval==0) warn(g_fileName,doctokenizerYYlineno,"Error: htmlonly section ended without end marker");
             doctokenizerYYsetStatePara();
           }
           break;
@@ -506,8 +608,7 @@ static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children
             doctokenizerYYsetStateLatexOnly();
             int retval = doctokenizerYYlex();
             children.append(new DocVerbatim(parent,g_context,g_token->verb,DocVerbatim::LatexOnly));
-            if (retval==0) printf("Error: latexonly section ended without end marker at line %d\n",
-                doctokenizerYYlineno);
+            if (retval==0) warn(g_fileName,doctokenizerYYlineno,"Error: latexonly section ended without end marker",doctokenizerYYlineno);
             doctokenizerYYsetStatePara();
           }
           break;
@@ -522,21 +623,21 @@ static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children
             int tok=doctokenizerYYlex();
             if (tok!=TK_WHITESPACE)
             {
-              printf("Error: expected whitespace after %s command at line %d\n",
-                  tokenName.data(),doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+                  tokenName.data());
               break;
             }
             tok=doctokenizerYYlex();
             if (tok==0)
             {
-              printf("Error: unexpected end of comment block at line %d while parsing the "
-                  "argument of command %s\n",doctokenizerYYlineno, tokenName.data());
+              warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment block while parsing the "
+                  "argument of command %s",tokenName.data());
               break;
             }
             else if (tok!=TK_WORD && tok!=TK_LNKWORD)
             {
-              printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-                  tokToString(tok),tokenName.data(),doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+                  tokToString(tok),tokenName.data());
               break;
             }
             DocAnchor *anchor = new DocAnchor(parent,g_token->name,FALSE);
@@ -548,8 +649,8 @@ static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children
             int tok=doctokenizerYYlex();
             if (tok!=TK_WHITESPACE)
             {
-              printf("Error: expected whitespace after %s command at line %d\n",
-                  tokenName.data(),doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+                  tokenName.data());
               break;
             }
             doctokenizerYYsetStateInternalRef();
@@ -557,8 +658,8 @@ static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children
             DocInternalRef *ref=0;
             if (tok!=TK_WORD && tok!=TK_LNKWORD)
             {
-              printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-                  tokToString(tok),tokenName.data(),doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+                  tokToString(tok),tokenName.data());
               doctokenizerYYsetStatePara();
               break;
             }
@@ -796,15 +897,15 @@ static void readTextFileByName(const QCString &file,QCString &text)
   }
   else if (ambig)
   {
-    printf("Error: included file name %s at line %d is ambigious.\n"
-           "Possible candidates:\n%s",file.data(),doctokenizerYYlineno,
+    warn(g_fileName,doctokenizerYYlineno,"Error: included file name %s is ambigious"
+           "Possible candidates:\n%s",file.data(),
            showFileDefMatches(Doxygen::exampleNameDict,file).data()
           );
   }
   else
   {
-    printf("Error: included file %s at line %d is not found. "
-           "Check you EXAMPLE_PATH",file.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: included file %s is not found"
+           "Check you EXAMPLE_PATH",file.data());
   }
 }
 
@@ -815,7 +916,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor)
 {
   if (id.isEmpty())
   {
-    printf("Error: Empty anchor label at line %d!\n",doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: Empty anchor label");
   }
   if (newAnchor) // found <a name="label">
   {
@@ -831,7 +932,7 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor)
     }
     else
     {
-      printf("Error: Invalid anchor id `%s' at line %d\n",id.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Invalid anchor id `%s'",id.data());
     }
   }
 }
@@ -998,14 +1099,14 @@ void DocCopy::parse()
     }
     else // oops, recursion
     {
-      printf("Error: recursive call chain of \\copydoc commands detected at %d\n",
+      warn(g_fileName,doctokenizerYYlineno,"Error: recursive call chain of \\copydoc commands detected at %d\n",
           doctokenizerYYlineno);
     }
   }
   else
   {
-    printf("Error: target %s of \\copydoc command at line %d not found\n",
-        m_link.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: target %s of \\copydoc command not found",
+        m_link.data());
   }
 }
 
@@ -1047,7 +1148,8 @@ DocFormula::DocFormula(DocNode *parent,int id) :
   Formula *formula=Doxygen::formulaNameDict[formCmd];
   if (formula)
   {
-    m_name.sprintf("form_%d",formula->getId());
+    m_id = formula->getId();
+    m_name.sprintf("form_%d",m_id);
     m_text = formula->getFormulaText();
   }
 }
@@ -1095,16 +1197,16 @@ void DocSecRefItem::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a \\refitem at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a \\refitem",
+	       g_token->name.data());
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+	       g_token->name.data());
           break;
       }
     }
@@ -1123,14 +1225,13 @@ void DocSecRefItem::parse()
     }
     else
     {
-      printf("Error reference to unknown section %s at line %d\n",
-          m_target.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error reference to unknown section %s",
+          m_target.data());
     }
   } 
   else
   {
-    printf("Error reference to empty target at line %d\n",
-        doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error reference to empty target");
   }
   
   DBG(("DocSecRefItem::parse() end\n"));
@@ -1160,15 +1261,14 @@ void DocSecRefList::parse()
             int tok=doctokenizerYYlex();
             if (tok!=TK_WHITESPACE)
             {
-              printf("Error: expected whitespace after \\refitem command at line %d\n",
-                  doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after \\refitem command");
               break;
             }
             tok=doctokenizerYYlex();
             if (tok!=TK_WORD && tok!=TK_LNKWORD)
             {
-              printf("Error: unexpected token %s as the argument of \\refitem at line %d.\n",
-                  tokToString(tok),doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of \\refitem",
+                  tokToString(tok));
               break;
             }
 
@@ -1180,8 +1280,8 @@ void DocSecRefList::parse()
         case CMD_ENDSECREFLIST:
           goto endsecreflist;
         default:
-          printf("Error: Illegal command %s as part of a \\secreflist at line %d\n",
-              g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a \\secreflist",
+              g_token->name.data());
           goto endsecreflist;
       }
     }
@@ -1191,8 +1291,8 @@ void DocSecRefList::parse()
     }
     else
     {
-      printf("Error: Unexpected token %s inside section reference list at line %d\n",
-          tokToString(tok),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s inside section reference list",
+          tokToString(tok));
       goto endsecreflist;
     }
     tok=doctokenizerYYlex();
@@ -1234,16 +1334,16 @@ void DocInternalRef::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a \\ref at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a \\ref",
+	       g_token->name.data());
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-		g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+		g_token->name.data());
           break;
       }
     }
@@ -1291,8 +1391,8 @@ DocRef::DocRef(DocNode *parent,const QCString &target) :
   }
   else // oops, bogus target
   {
-    printf("Error: unable to resolve reference to `%s' for \\ref command at line %d\n",
-           target.data(),doctokenizerYYlineno); 
+    warn(g_fileName,doctokenizerYYlineno,"Error: unable to resolve reference to `%s' for \\ref command",
+           target.data()); 
   }
 }
 
@@ -1309,16 +1409,16 @@ void DocRef::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a \\ref at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a \\ref",
+	       g_token->name.data());
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-		g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+		g_token->name.data());
           break;
       }
     }
@@ -1353,8 +1453,8 @@ DocLink::DocLink(DocNode *parent,const QCString &target) :
   }
   else // oops, bogus target
   {
-    printf("Error: unable to resolve link to `%s' for \\link command at line %d\n",
-           target.data(),doctokenizerYYlineno); 
+    warn(g_fileName,doctokenizerYYlineno,"Error: unable to resolve link to `%s' for \\link command",
+           target.data()); 
   }
 }
 
@@ -1378,19 +1478,18 @@ QCString DocLink::parse(bool isJavaLink)
             case CMD_ENDLINK:
               if (isJavaLink)
               {
-                printf("Error: {@link.. ended with @endlink command at line %d\n",
-                    doctokenizerYYlineno);
+                warn(g_fileName,doctokenizerYYlineno,"Error: {@link.. ended with @endlink command");
               }
               goto endlink;
             default:
-              printf("Error: Illegal command %s as part of a \\ref at line %d\n",
-                  g_token->name.data(),doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a \\ref",
+                  g_token->name.data());
               break;
           }
           break;
         case TK_SYMBOL: 
-          printf("Error: Unsupported symbol %s found at line %d\n",
-              g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+              g_token->name.data());
           break;
         case TK_LNKWORD: 
         case TK_WORD: 
@@ -1416,16 +1515,16 @@ QCString DocLink::parse(bool isJavaLink)
           m_children.append(new DocWord(this,g_token->name));
           break;
         default:
-          printf("Error: Unexpected token %s at line %d\n",
-            g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+            g_token->name.data());
         break;
       }
     }
   }
   if (tok==0)
   {
-    printf("Error: Unexpected end of comment at line %d while inside"
-           " link command\n",doctokenizerYYlineno); 
+    warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected end of comment while inside"
+           " link command\n"); 
   }
 endlink:
 
@@ -1453,16 +1552,16 @@ void DocDotFile::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a \\dotfile at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a \\dotfile",
+	       g_token->name.data());
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-		g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+		g_token->name.data());
           break;
       }
     }
@@ -1480,8 +1579,8 @@ void DocDotFile::parse()
     }
     else 
     {
-      printf("Error: Unknown option %s after image title at line %d\n",
-            g_token->name.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unknown option %s after image title",
+            g_token->name.data());
     }
     tok=doctokenizerYYlex();
   }
@@ -1497,15 +1596,15 @@ void DocDotFile::parse()
   }
   else if (ambig)
   {
-    printf("Error: included dot file name %s at line %d is ambigious.\n"
-           "Possible candidates:\n%s",m_name.data(),doctokenizerYYlineno,
+    warn(g_fileName,doctokenizerYYlineno,"Error: included dot file name %s is ambigious.\n"
+           "Possible candidates:\n%s",m_name.data(),
            showFileDefMatches(Doxygen::exampleNameDict,m_name).data()
           );
   }
   else
   {
-    printf("Error: included dot file %s at line %d is not found "
-           "in any of the paths specified via DOTFILE_DIRS!",m_name.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: included dot file %s is not found "
+           "in any of the paths specified via DOTFILE_DIRS!",m_name.data());
   }
 
   DBG(("DocDotFile::parse() end\n"));
@@ -1530,16 +1629,16 @@ void DocImage::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a \\image at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a \\image",
+	       g_token->name.data());
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-		g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+		g_token->name.data());
           break;
       }
     }
@@ -1557,8 +1656,8 @@ void DocImage::parse()
     }
     else 
     {
-      printf("Error: Unknown option %s after image title at line %d\n",
-            g_token->name.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unknown option %s after image title",
+            g_token->name.data());
     }
     tok=doctokenizerYYlex();
   }
@@ -1588,8 +1687,8 @@ int DocHtmlHeader::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a <h%d> tag at line %d\n",
-	       g_token->name.data(),m_level,doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a <h%d> tag",
+	       g_token->name.data(),m_level);
           break;
         case TK_HTMLTAG:
           {
@@ -1598,8 +1697,8 @@ int DocHtmlHeader::parse()
             {
               if (m_level!=1)
               {
-                printf("Error: <h%d> ended with </h1> at line %d\n",
-                    m_level,doctokenizerYYlineno); 
+                warn(g_fileName,doctokenizerYYlineno,"Error: <h%d> ended with </h1>",
+                    m_level); 
               }
               goto endheader;
             }
@@ -1607,8 +1706,8 @@ int DocHtmlHeader::parse()
             {
               if (m_level!=2)
               {
-                printf("Error: <h%d> ended with </h2> at line %d\n",
-                    m_level,doctokenizerYYlineno); 
+                warn(g_fileName,doctokenizerYYlineno,"Error: <h%d> ended with </h2>",
+                    m_level); 
               }
               goto endheader;
             }
@@ -1616,33 +1715,33 @@ int DocHtmlHeader::parse()
             {
               if (m_level!=3)
               {
-                printf("Error: <h%d> ended with </h3> at line %d\n",
-                    m_level,doctokenizerYYlineno); 
+                warn(g_fileName,doctokenizerYYlineno,"Error: <h%d> ended with </h3>",
+                    m_level); 
               }
               goto endheader;
             }
             else
             {
-              printf("Error: Unexpected html tag <%s%s> found at line %d within <h%d> context\n",
-                  g_token->endTag?"/":"",g_token->name.data(),doctokenizerYYlineno,m_level);
+              warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected html tag <%s%s> found within <h%d> context",
+                  g_token->endTag?"/":"",g_token->name.data(),m_level);
             }
           }
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-		g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+		g_token->name.data());
           break;
       }
     }
   }
   if (tok==0)
   {
-    printf("Error: Unexpected end of comment at line %d while inside"
-           " <h%d> tag\n",doctokenizerYYlineno,m_level); 
+    warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected end of comment while inside"
+           " <h%d> tag\n",m_level); 
   }
 endheader:
   handlePendingStyleCommands(this,m_children);
@@ -1668,12 +1767,12 @@ int DocHRef::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a <a>..</a> block at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a <a>..</a> block",
+	       g_token->name.data());
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         case TK_HTMLTAG:
           {
@@ -1684,13 +1783,13 @@ int DocHRef::parse()
             }
             else
             {
-              printf("Error: Unexpected html tag <%s%s> found at line %d within <a href=...> context\n",
+              warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected html tag <%s%s> found within <a href=...> context",
                   g_token->endTag?"/":"",g_token->name.data(),doctokenizerYYlineno);
             }
           }
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
 		g_token->name.data(),doctokenizerYYlineno);
           break;
       }
@@ -1698,8 +1797,8 @@ int DocHRef::parse()
   }
   if (tok==0)
   {
-    printf("Error: Unexpected end of comment at line %d while inside"
-           " <a href=...> tag\n",doctokenizerYYlineno); 
+    warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected end of comment while inside"
+           " <a href=...> tag",doctokenizerYYlineno); 
   }
 endhref:
   handlePendingStyleCommands(this,m_children);
@@ -1736,7 +1835,7 @@ int DocInternal::parse()
     }
     if (retval==TK_LISTITEM)
     {
-      printf("Error: Invalid list item found at line %d!\n",doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Invalid list item found",doctokenizerYYlineno);
     }
   } while (retval!=0 && retval!=RetVal_Section);
   if (lastPar) lastPar->markLast();
@@ -1748,7 +1847,7 @@ int DocInternal::parse()
     int secLev = sec->type==SectionInfo::Subsection ? 2 : 1;
     if (secLev!=1) // wrong level
     {
-      printf("Error: Expected level 1 section, found a section with level %d at line %d.\n",secLev,doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Expected level 1 section, found a section with level %d.",secLev);
       break;
     }
     else
@@ -1761,7 +1860,7 @@ int DocInternal::parse()
 
   if (retval==RetVal_Internal)
   {
-    printf("Error: \\internal command found inside internal section\n");
+    warn(g_fileName,doctokenizerYYlineno,"Error: \\internal command found inside internal section");
   }
 
   DBG(("DocInternal::parse() end\n"));
@@ -1780,35 +1879,66 @@ int DocIndexEntry::parse()
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after \\addindex command at line %d\n",
-        doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after \\addindex command");
     goto endindexentry;
   }
+  m_entry.resize(0);
   while ((tok=doctokenizerYYlex()) && tok!=TK_WHITESPACE && tok!=TK_NEWPARA)
   {
-    if (!defaultHandleToken(this,tok,m_children))
+    switch (tok)
     {
-      switch (tok)
+      case TK_WORD: 
+      case TK_LNKWORD: 
+        m_entry+=g_token->name;
+        break;
+      case TK_SYMBOL:
+        {
+          char letter='\0';
+          DocSymbol::SymType s = DocSymbol::decodeSymbol(g_token->name,&letter);
+          switch (s)
+          {
+            case DocSymbol::BSlash:  m_entry+='\\'; break;
+            case DocSymbol::At:      m_entry+='@';  break;
+            case DocSymbol::Less:    m_entry+='<';  break;
+            case DocSymbol::Greater: m_entry+='>';  break;
+            case DocSymbol::Amp:     m_entry+='&';  break;
+            case DocSymbol::Dollar:  m_entry+='$';  break;
+            case DocSymbol::Hash:    m_entry+='#';  break;
+            case DocSymbol::Percent: m_entry+='%';  break;
+            case DocSymbol::Apos:    m_entry+='\''; break;
+            case DocSymbol::Quot:    m_entry+='"';  break;
+            default:
+              warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected symbol found as argument of \\addindex");
+              break;
+          }
+        }
+        break;
+    case TK_COMMAND: 
+      switch (CmdMapper::map(g_token->name))
       {
-        case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a \\addindex at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
-          break;
-        case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
-          break;
+        case CMD_BSLASH:  m_entry+='\\'; break;
+        case CMD_AT:      m_entry+='@';  break;
+        case CMD_LESS:    m_entry+='<';  break;
+        case CMD_GREATER: m_entry+='>';  break;
+        case CMD_AMP:     m_entry+='&';  break;
+        case CMD_DOLLAR:  m_entry+='$';  break;
+        case CMD_HASH:    m_entry+='#';  break;
+        case CMD_PERCENT: m_entry+='%';  break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-		g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected command %s found as argument of \\addindex",
+                    g_token->name.data());
           break;
       }
+      break;
+      default:
+        warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+            g_token->name.data());
+        break;
     }
   }
   if (tok!=TK_WHITESPACE) retval=tok;
 endindexentry:
-  handlePendingStyleCommands(this,m_children);
-  DBG(("DocIndexEntry::parse() end\n"));
+  DBG(("DocIndexEntry::parse() end retval=%x\n",retval));
   DocNode *n=g_nodeStack.pop();
   ASSERT(n==this);
   return retval;
@@ -1829,12 +1959,12 @@ int DocHtmlCaption::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a <caption> tag at line %d\n",
-              g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a <caption> tag",
+              g_token->name.data());
           break;
         case TK_SYMBOL: 
-          printf("Error: Unsupported symbol %s found at line %d\n",
-              g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+              g_token->name.data());
           break;
         case TK_HTMLTAG:
           {
@@ -1846,22 +1976,22 @@ int DocHtmlCaption::parse()
             }
             else
             {
-              printf("Error: Unexpected html tag <%s%s> found at line %d within <caption> context\n",
-                  g_token->endTag?"/":"",g_token->name.data(),doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected html tag <%s%s> found within <caption> context",
+                  g_token->endTag?"/":"",g_token->name.data());
             }
           }
           break;
         default:
-          printf("Error: Unexpected token %s at line %d\n",
-              g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+              g_token->name.data());
           break;
       }
     }
   }
   if (tok==0)
   {
-    printf("Error: Unexpected end of comment at line %d while inside"
-           " <caption> tag\n",doctokenizerYYlineno); 
+    warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected end of comment while inside"
+           " <caption> tag",doctokenizerYYlineno); 
   }
 endcaption:
   handlePendingStyleCommands(this,m_children);
@@ -1927,21 +2057,21 @@ int DocHtmlRow::parse()
     }
     else // found some other tag
     {
-      printf("Error: expected <td> or <th> tag at line %d but "
-          "found <%s> instead!\n",doctokenizerYYlineno,g_token->name.data());
+      warn(g_fileName,doctokenizerYYlineno,"Error: expected <td> or <th> tag but "
+          "found <%s> instead!",g_token->name.data());
       goto endrow;
     }
   }
   else if (tok==0) // premature end of comment
   {
-    printf("Error: unexpected end of comment at line %d while looking"
-        " for a html description title\n",doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment while looking"
+        " for a html description title");
     goto endrow;
   }
   else // token other than html token
   {
-    printf("Error: expected <td> or <th> tag at line %d but found %s token instead!\n",
-        doctokenizerYYlineno,tokToString(tok));
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected <td> or <th> tag but found %s token instead!",
+        tokToString(tok));
     goto endrow;
   }
 
@@ -1991,8 +2121,7 @@ getrow:
     {
       if (m_caption)
       {
-        printf("Error: table already has a caption, found another one at line %d\n",
-            doctokenizerYYlineno);
+        warn(g_fileName,doctokenizerYYlineno,"Error: table already has a caption, found another one");
       }
       else
       {
@@ -2007,20 +2136,19 @@ getrow:
     }
     else // found wrong token
     {
-      printf("Error: expected <tr> or <caption> tag at line %d but "
-          "found <%s%s> instead!\n",doctokenizerYYlineno,
-          g_token->endTag ? "/" : "", g_token->name.data());
+      warn(g_fileName,doctokenizerYYlineno,"Error: expected <tr> or <caption> tag but "
+          "found <%s%s> instead!", g_token->endTag ? "/" : "", g_token->name.data());
     }
   }
   else if (tok==0) // premature end of comment
   {
-      printf("Error: unexpected end of comment at line %d while looking"
-          " for a <tr> or <caption> tag\n",doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment while looking"
+          " for a <tr> or <caption> tag");
   }
   else // token other than html token
   {
-    printf("Error: expected <tr> tag at line %d but found %s token instead!\n",
-        doctokenizerYYlineno,tokToString(tok));
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected <tr> tag but found %s token instead!",
+        tokToString(tok));
   }
        
   // parse one or more rows
@@ -2053,12 +2181,12 @@ int DocHtmlDescTitle::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a <dt> tag at line %d\n",
-              g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a <dt> tag",
+              g_token->name.data());
           break;
         case TK_SYMBOL: 
-          printf("Error: Unsupported symbol %s found at line %d\n",
-              g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+              g_token->name.data());
           break;
         case TK_HTMLTAG:
           {
@@ -2074,22 +2202,22 @@ int DocHtmlDescTitle::parse()
             }
             else
             {
-              printf("Error: Unexpected html tag <%s%s> found at line %d within <dt> context\n",
-                  g_token->endTag?"/":"",g_token->name.data(),doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected html tag <%s%s> found within <dt> context",
+                  g_token->endTag?"/":"",g_token->name.data());
             }
           }
           break;
         default:
-          printf("Error: Unexpected token %s at line %d\n",
-              g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+              g_token->name.data());
           break;
       }
     }
   }
   if (tok==0)
   {
-    printf("Error: Unexpected end of comment at line %d while inside"
-        " <dt> tag\n",doctokenizerYYlineno); 
+    warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected end of comment while inside"
+        " <dt> tag"); 
   }
 endtitle:
   handlePendingStyleCommands(this,m_children);
@@ -2147,21 +2275,21 @@ int DocHtmlDescList::parse()
     }
     else // found some other tag
     {
-      printf("Error: expected <dt> tag at line %d but "
-          "found <%s> instead!\n",doctokenizerYYlineno,g_token->name.data());
+      warn(g_fileName,doctokenizerYYlineno,"Error: expected <dt> tag but "
+          "found <%s> instead!",g_token->name.data());
       goto enddesclist;
     }
   }
   else if (tok==0) // premature end of comment
   {
-    printf("Error: unexpected end of comment at line %d while looking"
-        " for a html description title\n",doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment while looking"
+        " for a html description title");
     goto enddesclist;
   }
   else // token other than html token
   {
-    printf("Error: expected <dt> tag at line %d but found %s token instead!\n",
-        doctokenizerYYlineno,tokToString(tok));
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected <dt> tag but found %s token instead!",
+        tokToString(tok));
     goto enddesclist;
   }
 
@@ -2185,8 +2313,7 @@ int DocHtmlDescList::parse()
 
   if (retval==0)
   {
-    printf("Error: unexpected end of comment at line %d while inside <dl> block\n",
-        doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment while inside <dl> block");
   }
 
 enddesclist:
@@ -2270,21 +2397,21 @@ int DocHtmlList::parse()
     }
     else // found some other tag
     {
-      printf("Error: expected <li> tag at line %d but "
-          "found <%s> instead!\n",doctokenizerYYlineno,g_token->name.data());
+      warn(g_fileName,doctokenizerYYlineno,"Error: expected <li> tag but "
+          "found <%s> instead!",g_token->name.data());
       goto endlist;
     }
   }
   else if (tok==0) // premature end of comment
   {
-    printf("Error: unexpected end of comment at line %d while looking"
-        " for a html list item\n",doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment while looking"
+        " for a html list item");
     goto endlist;
   }
   else // token other than html token
   {
-    printf("Error: expected <li> tag at line %d but found %s token instead!\n",
-        doctokenizerYYlineno,tokToString(tok));
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected <li> tag but found %s token instead!",
+        tokToString(tok));
     goto endlist;
   }
 
@@ -2297,8 +2424,8 @@ int DocHtmlList::parse()
   
   if (retval==0)
   {
-    printf("Error: unexpected end of comment at line %d while inside <%cl> block\n",
-        doctokenizerYYlineno,m_type==Unordered ? 'u' : 'o');
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment while inside <%cl> block",
+        m_type==Unordered ? 'u' : 'o');
   }
 
 endlist:
@@ -2390,16 +2517,16 @@ void DocTitle::parse()
       switch (tok)
       {
         case TK_COMMAND: 
-          printf("Error: Illegal command %s as part of a title section at line %d\n",
-	       g_token->name.data(),doctokenizerYYlineno);
+          warn(g_fileName,doctokenizerYYlineno,"Error: Illegal command %s as part of a title section",
+	       g_token->name.data());
           break;
         case TK_SYMBOL: 
-	  printf("Error: Unsupported symbol %s found at line %d\n",
-               g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+               g_token->name.data());
           break;
         default:
-	  printf("Error: Unexpected token %s at line %d\n",
-		g_token->name.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s",
+		g_token->name.data());
           break;
       }
     }
@@ -2480,21 +2607,31 @@ int DocParamList::parse(const QCString &cmdName)
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-        cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+        cmdName.data());
   }
   doctokenizerYYsetStateParam();
   tok=doctokenizerYYlex();
   while (tok==TK_WORD) /* there is a parameter name */
   {
+    if (m_type==DocParamSect::Param)
+    {
+      g_hasParamCommand=TRUE;
+      checkArgumentName(g_token->name,TRUE);
+    }
+    else if (m_type==DocParamSect::RetVal)
+    {
+      g_hasParamCommand=TRUE;
+      checkArgumentName(g_token->name,FALSE);
+    }
     m_params.append(g_token->name);
     tok=doctokenizerYYlex();
   }
   doctokenizerYYsetStatePara();
   if (tok==0) /* premature end of comment block */
   {
-    printf("Error: unexpected end of comment block at line %d while parsing the "
-        "argument of command %s\n",doctokenizerYYlineno, cmdName.data());
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment block while parsing the "
+        "argument of command %s",cmdName.data());
     return 0;
   }
   ASSERT(tok==TK_WHITESPACE);
@@ -2517,7 +2654,7 @@ int DocParamSect::parse(const QCString &cmdName)
   DBG(("DocParamSect::parse() start\n"));
   g_nodeStack.push(this);
 
-  DocParamList *pl = new DocParamList(this);
+  DocParamList *pl = new DocParamList(this,m_type);
   m_children.append(pl);
   retval = pl->parse(cmdName);
   
@@ -2590,8 +2727,8 @@ void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-        cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+        cmdName.data());
     return;
   }
   doctokenizerYYsetStatePattern();
@@ -2599,14 +2736,14 @@ void DocPara::handleIncludeOperator(const QCString &cmdName,DocIncOperator::Type
   doctokenizerYYsetStatePara();
   if (tok==0)
   {
-    printf("Error: unexpected end of comment block at line %d while parsing the "
-        "argument of command %s\n",doctokenizerYYlineno, cmdName.data());
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment block while parsing the "
+        "argument of command %s", cmdName.data());
     return;
   }
   else if (tok!=TK_WORD)
   {
-    printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-        tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+        tokToString(tok),cmdName.data());
     return;
   }
   DocIncOperator *op = new DocIncOperator(this,t,g_token->name,g_context);
@@ -2640,22 +2777,22 @@ void DocPara::handleImage(const QCString &cmdName)
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-        cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+        cmdName.data());
     return;
   }
   tok=doctokenizerYYlex();
   if (tok!=TK_WORD && tok!=TK_LNKWORD)
   {
-    printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-        tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+        tokToString(tok),cmdName.data());
     return;
   }
   tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-        cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+        cmdName.data());
     return;
   }
   DocImage::Type t;
@@ -2665,17 +2802,17 @@ void DocPara::handleImage(const QCString &cmdName)
   else if (imgType=="rtf")   t=DocImage::Rtf;
   else
   {
-    printf("Error: image type %s specified as the first argument of "
-        "%s at line %d is not valid.\n",
-        imgType.data(),cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: image type %s specified as the first argument of "
+        "%s is not valid",
+        imgType.data(),cmdName.data());
     return;
   } 
   doctokenizerYYsetStateFile();
   tok=doctokenizerYYlex();
   if (tok!=TK_WORD)
   {
-    printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-        tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+        tokToString(tok),cmdName.data());
     return;
   }
   doctokenizerYYsetStatePara();
@@ -2689,16 +2826,16 @@ void DocPara::handleDotFile(const QCString &cmdName)
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-        cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+        cmdName.data());
     return;
   }
   doctokenizerYYsetStateFile();
   tok=doctokenizerYYlex();
   if (tok!=TK_WORD)
   {
-    printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-        tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+        tokToString(tok),cmdName.data());
     return;
   }
   doctokenizerYYsetStatePara();
@@ -2712,16 +2849,16 @@ void DocPara::handleLink(const QCString &cmdName,bool isJavaLink)
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-        cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+        cmdName.data());
     return;
   }
   doctokenizerYYsetStateLink();
   tok=doctokenizerYYlex();
   if (tok!=TK_WORD)
   {
-    printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-        tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+        tokToString(tok),cmdName.data());
     return;
   }
   doctokenizerYYsetStatePara();
@@ -2739,8 +2876,8 @@ void DocPara::handleRef(const QCString &cmdName)
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-        cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+        cmdName.data());
     return;
   }
   doctokenizerYYsetStateRef();
@@ -2748,8 +2885,8 @@ void DocPara::handleRef(const QCString &cmdName)
   DocRef *ref=0;
   if (tok!=TK_WORD)
   {
-    printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-        tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+        tokToString(tok),cmdName.data());
     goto endref;
   }
   ref = new DocRef(this,g_token->name);
@@ -2789,8 +2926,8 @@ int DocPara::handleLanguageSwitch()
       }
       else
       {
-        printf("Error: Unexpected token %s as parameter of \\~ at line %d\n",
-            tokToString(tok),doctokenizerYYlineno);
+        warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected token %s as parameter of \\~",
+            tokToString(tok));
         goto endlang;
       }
     }
@@ -2809,8 +2946,8 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t)
   int tok=doctokenizerYYlex();
   if (tok!=TK_WHITESPACE)
   {
-    printf("Error: expected whitespace after %s command at line %d\n",
-        cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+        cmdName.data());
     return;
   }
   doctokenizerYYsetStateFile();
@@ -2818,14 +2955,14 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t)
   doctokenizerYYsetStatePara();
   if (tok==0)
   {
-    printf("Error: unexpected end of comment block at line %d while parsing the "
-        "argument of command %s\n",doctokenizerYYlineno, cmdName.data());
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment block while parsing the "
+        "argument of command %s",cmdName.data());
     return;
   }
   else if (tok!=TK_WORD)
   {
-    printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-        tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+    warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+        tokToString(tok),cmdName.data());
     return;
   }
   DocInclude *inc = new DocInclude(this,g_token->name,g_context,t);
@@ -2840,7 +2977,7 @@ int DocPara::handleCommand(const QCString &cmdName)
   switch (CmdMapper::map(cmdName))
   {
     case CMD_UNKNOWN:
-      printf("Error: Found unknown command `\\%s' at line %d\n",cmdName.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Found unknown command `\\%s'",cmdName.data());
       break;
     case CMD_EMPHASIS:
       m_children.append(new DocStyleChange(this,g_nodeStack.count(),DocStyleChange::Italic,TRUE));
@@ -2941,21 +3078,21 @@ int DocPara::handleCommand(const QCString &cmdName)
 	int tok=doctokenizerYYlex();
 	if (tok!=TK_WHITESPACE)
 	{
-	  printf("Error: expected whitespace after %s command at line %d\n",
-	      cmdName.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+	      cmdName.data());
 	  break;
 	}
 	tok=doctokenizerYYlex();
 	if (tok==0)
 	{
-	  printf("Error: unexpected end of comment block at line %d while parsing the "
-	      "argument of command %s\n",doctokenizerYYlineno, cmdName.data());
+	  warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment block while parsing the "
+	      "argument of command %s\n", cmdName.data());
 	  break;
 	}
 	else if (tok!=TK_WORD && tok!=TK_LNKWORD)
 	{
-	  printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-	      tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+	      tokToString(tok),cmdName.data());
 	  break;
 	}
 	g_token->sectionId = g_token->name;
@@ -2967,8 +3104,7 @@ int DocPara::handleCommand(const QCString &cmdName)
         doctokenizerYYsetStateCode();
         retval = doctokenizerYYlex();
         m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Code));
-        if (retval==0) printf("Error: code section ended without end marker at line %d\n",
-            doctokenizerYYlineno);
+        if (retval==0) warn(g_fileName,doctokenizerYYlineno,"Error: code section ended without end marker");
         doctokenizerYYsetStatePara();
       }
       break;
@@ -2977,8 +3113,7 @@ int DocPara::handleCommand(const QCString &cmdName)
         doctokenizerYYsetStateHtmlOnly();
         retval = doctokenizerYYlex();
         m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::HtmlOnly));
-        if (retval==0) printf("Error: htmlonly section ended without end marker at line %d\n",
-            doctokenizerYYlineno);
+        if (retval==0) warn(g_fileName,doctokenizerYYlineno,"Error: htmlonly section ended without end marker");
         doctokenizerYYsetStatePara();
       }
       break;
@@ -2987,8 +3122,7 @@ int DocPara::handleCommand(const QCString &cmdName)
         doctokenizerYYsetStateLatexOnly();
         retval = doctokenizerYYlex();
         m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::LatexOnly));
-        if (retval==0) printf("Error: latexonly section ended without end marker at line %d\n",
-            doctokenizerYYlineno);
+        if (retval==0) warn(g_fileName,doctokenizerYYlineno,"Error: latexonly section ended without end marker");
         doctokenizerYYsetStatePara();
       }
       break;
@@ -2997,8 +3131,7 @@ int DocPara::handleCommand(const QCString &cmdName)
         doctokenizerYYsetStateVerbatim();
         retval = doctokenizerYYlex();
         m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::Verbatim));
-        if (retval==0) printf("Error: verbatim section ended without end marker at line %d\n",
-            doctokenizerYYlineno);
+        if (retval==0) warn(g_fileName,doctokenizerYYlineno,"Error: verbatim section ended without end marker");
         doctokenizerYYsetStatePara();
       }
       break;
@@ -3007,7 +3140,7 @@ int DocPara::handleCommand(const QCString &cmdName)
     case CMD_ENDLATEXONLY:
     case CMD_ENDLINK:
     case CMD_ENDVERBATIM:
-      printf("Error: unexpected command %s at line %d\n",g_token->name.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: unexpected command %s",g_token->name.data());
       break; 
     case CMD_PARAM:
       retval = handleParamSection(cmdName,DocParamSect::Param);
@@ -3041,21 +3174,21 @@ int DocPara::handleCommand(const QCString &cmdName)
 	int tok=doctokenizerYYlex();
 	if (tok!=TK_WHITESPACE)
 	{
-	  printf("Error: expected whitespace after %s command at line %d\n",
-	      cmdName.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+	      cmdName.data());
 	  break;
 	}
 	tok=doctokenizerYYlex();
 	if (tok==0)
 	{
-	  printf("Error: unexpected end of comment block at line %d while parsing the "
-	      "argument of command %s\n",doctokenizerYYlineno, cmdName.data());
+	  warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment block while parsing the "
+	      "argument of command %s",cmdName.data());
 	  break;
 	}
 	else if (tok!=TK_WORD && tok!=TK_LNKWORD)
 	{
-	  printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-	      tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+	      tokToString(tok),cmdName.data());
 	  break;
 	}
         DocAnchor *anchor = new DocAnchor(this,g_token->name,FALSE);
@@ -3077,21 +3210,21 @@ int DocPara::handleCommand(const QCString &cmdName)
 	int tok=doctokenizerYYlex();
 	if (tok!=TK_WHITESPACE)
 	{
-	  printf("Error: expected whitespace after %s command at line %d\n",
-	      cmdName.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: expected whitespace after %s command",
+	      cmdName.data());
 	  break;
 	}
 	tok=doctokenizerYYlex();
 	if (tok==0)
 	{
-	  printf("Error: unexpected end of comment block at line %d while parsing the "
-	      "argument of command %s\n",doctokenizerYYlineno, cmdName.data());
+	  warn(g_fileName,doctokenizerYYlineno,"Error: unexpected end of comment block while parsing the "
+	      "argument of command %s\n", cmdName.data());
 	  break;
 	}
 	else if (tok!=TK_WORD && tok!=TK_LNKWORD)
 	{
-	  printf("Error: unexpected token %s as the argument of %s at line %d.\n",
-	      tokToString(tok),cmdName.data(),doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: unexpected token %s as the argument of %s",
+	      tokToString(tok),cmdName.data());
 	  break;
 	}
         DocCopy *cpy = new DocCopy(this,g_token->name);
@@ -3146,10 +3279,10 @@ int DocPara::handleCommand(const QCString &cmdName)
       }
       break;
     case CMD_SECREFITEM:
-      printf("Error: unexpected command %s at line %d\n",g_token->name.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: unexpected command %s",g_token->name.data());
       break;
     case CMD_ENDSECREFLIST:
-      printf("Error: unexpected command %s at line %d\n",g_token->name.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: unexpected command %s",g_token->name.data());
       break;
     case CMD_FORMULA:
       {
@@ -3161,7 +3294,7 @@ int DocPara::handleCommand(const QCString &cmdName)
       retval = handleLanguageSwitch();
       break;
     case CMD_INTERNALREF:
-      printf("Error: unexpected command %s at line %d\n",g_token->name.data(),doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: unexpected command %s",g_token->name.data());
       break;
     default:
       // we should not get here!
@@ -3201,7 +3334,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const QList<Option> &tag
     case HTML_LI:
       if (!insideUL(this) && !insideOL(this))
       {
-        printf("Error: lonely <li> tag found at line %d\n",doctokenizerYYlineno);
+        warn(g_fileName,doctokenizerYYlineno,"Error: lonely <li> tag found");
       }
       else
       {
@@ -3250,8 +3383,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const QList<Option> &tag
       retval = RetVal_DescTitle;
       break;
     case HTML_DD:
-      printf("Error: Unexpected tag <dd> found at line %d\n",
-          doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag <dd> found");
       break;
     case HTML_TABLE:
       {
@@ -3270,8 +3402,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const QList<Option> &tag
       retval = RetVal_TableHCell;
       break;
     case HTML_CAPTION:
-      printf("Error: Unexpected tag <caption> found at line %d\n",
-          doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag <caption> found");
       break;
     case HTML_BR:
       {
@@ -3301,8 +3432,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const QList<Option> &tag
             }
             else
             {
-              printf("Error: found <a> tag at line %d with name option but without value!\n",
-                  doctokenizerYYlineno);
+              warn(g_fileName,doctokenizerYYlineno,"Error: found <a> tag with name option but without value!");
             }
           }
           else if (opt->name=="href") // <a href=url>..</a> tag
@@ -3356,8 +3486,7 @@ int DocPara::handleHtmlStartTag(const QCString &tagName,const QList<Option> &tag
       }
       break;
     case HTML_UNKNOWN:
-      printf("Error: Unsupported html tag <%s> found at line %d\n",
-          tagName.data(), doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported html tag <%s> found", tagName.data());
       break;
     default:
       // we should not get here!
@@ -3377,8 +3506,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName)
     case HTML_UL: 
       if (!insideUL(this))
       {
-        printf("Error: found </ul> tag at line %d without matching <ul>\n",
-            doctokenizerYYlineno);
+        warn(g_fileName,doctokenizerYYlineno,"Error: found </ul> tag without matching <ul>");
       }
       else
       {
@@ -3388,8 +3516,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName)
     case HTML_OL: 
       if (!insideOL(this))
       {
-        printf("Error: found </ol> tag at line %d without matching <ol>\n",
-            doctokenizerYYlineno);
+        warn(g_fileName,doctokenizerYYlineno,"Error: found </ol> tag without matching <ol>");
       }
       else
       {
@@ -3399,8 +3526,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName)
     case HTML_LI:
       if (!insideLI(this))
       {
-        printf("Error: found </li> tag at line %d without matching <li>\n",
-            doctokenizerYYlineno);
+        warn(g_fileName,doctokenizerYYlineno,"Error: found </li> tag without matching <li>");
       }
       else
       {
@@ -3410,8 +3536,7 @@ int DocPara::handleHtmlEndTag(const QCString &tagName)
     case HTML_PRE:
       if (!insidePRE(this))
       {
-        printf("Error: found </pre> tag at line %d without matching <pre>\n",
-            doctokenizerYYlineno);
+        warn(g_fileName,doctokenizerYYlineno,"Error: found </pre> tag without matching <pre>");
       }
       else
       {
@@ -3464,40 +3589,33 @@ int DocPara::handleHtmlEndTag(const QCString &tagName)
       // ignore </th> tag
       break;
     case HTML_CAPTION:
-      printf("Error: Unexpected tag </caption> found at line %d\n",
-          doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag </caption> found");
       break;
     case HTML_BR:
-      printf("Error: Illegal </br> tag found\n");
+      warn(g_fileName,doctokenizerYYlineno,"Error: Illegal </br> tag found\n");
       break;
     case HTML_H1:
-      printf("Error: Unexpected tag </h1> found at line %d\n",
-          doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag </h1> found");
       break;
     case HTML_H2:
-      printf("Error: Unexpected tag </h2> found at line %d\n",
-          doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag </h2> found");
       break;
     case HTML_H3:
-      printf("Error: Unexpected tag </h3> found at line %d\n",
-          doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag </h3> found");
       break;
     case HTML_IMG:
-      printf("Error: Unexpected tag </img> found at line %d\n",
-          doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag </img> found");
       break;
     case HTML_HR:
-      printf("Error: Unexpected tag </hr> found at line %d\n",
-          doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag </hr> found");
       break;
     case HTML_A:
-      //printf("Error: Unexpected tag </a> found at line %d\n",
-      //    doctokenizerYYlineno);
+      //warn(g_fileName,doctokenizerYYlineno,"Error: Unexpected tag </a> found");
       // ignore </a> tag (can be part of <a name=...></a>
       break;
     case HTML_UNKNOWN:
-      printf("Error: Unsupported html tag </%s> found at line %d\n",
-          tagName.data(), doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported html tag </%s> found",
+          tagName.data());
       break;
     default:
       // we should not get here!
@@ -3619,14 +3737,14 @@ reparsetoken:
 	  }
 	  else
 	  {
-	    printf("Error: End of list marker found at line %d "
-		   "has invalid indent level ",doctokenizerYYlineno);
+	    warn(g_fileName,doctokenizerYYlineno,"Error: End of list marker found "
+		   "has invalid indent level");
 	  }
 	}
 	else
 	{
-	  printf("Error: End of list marker found at line %d without any preceding "
-	         "list items\n",doctokenizerYYlineno);
+	  warn(g_fileName,doctokenizerYYlineno,"Error: End of list marker found without any preceding "
+	         "list items");
 	}
 	break;
       case TK_COMMAND:    
@@ -3726,8 +3844,8 @@ reparsetoken:
           }
           else
           {
-            printf("Error: Unsupported symbol %s found at line %d\n",
-                g_token->name.data(),doctokenizerYYlineno);
+            warn(g_fileName,doctokenizerYYlineno,"Error: Unsupported symbol %s found",
+                g_token->name.data());
           }
           break;
         }
@@ -3747,7 +3865,7 @@ endparagraph:
 
   if (!(retval==0 || retval==TK_NEWPARA || retval==TK_LISTITEM || 
          retval==TK_ENDLIST || retval>RetVal_OK 
-	)) printf("DocPara::parse: Error retval=%x unexpected at line %d!\n",retval,doctokenizerYYlineno);
+	)) warn(g_fileName,doctokenizerYYlineno,"DocPara::parse: Error retval=%x unexpected",retval);
   return retval; 
 }
 
@@ -3791,7 +3909,7 @@ int DocSection::parse()
     }
     if (retval==TK_LISTITEM)
     {
-      printf("Error: Invalid list item found at line %d!\n",doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Invalid list item found");
     }
   } while (retval!=0 && retval!=RetVal_Section && retval!=RetVal_Internal);
   if (lastPar) lastPar->markLast();
@@ -3801,15 +3919,23 @@ int DocSection::parse()
   {
     SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];
     ASSERT(sec!=0);
-    int secLev = sec->type==SectionInfo::Subsection ? 2 : 1;
+    int secLev = 1;
+    switch (sec->type)
+    {
+      case SectionInfo::Section:       secLev=1; break;
+      case SectionInfo::Subsection:    secLev=2; break;
+      case SectionInfo::Subsubsection: secLev=3; break;
+      case SectionInfo::Paragraph:     secLev=4; break;
+      default: ASSERT(0);
+    }
     if (secLev<=level()) // new section at same or lower level 
     {
       break;
     }
     if (secLev!=level()+1) // new section at wrong level
     {
-      printf("Error: Expected level %d section, found a section "
-	  "with level %d at line %d.\n",level()+1,secLev,doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Expected level %d section, found a section "
+	  "with level %d",level()+1,secLev);
       retval=0; // stop parsing any further.
       break;
     }
@@ -3820,7 +3946,7 @@ int DocSection::parse()
       retval = s->parse();
     }
   }
-  ASSERT(retval==0 || retval==RetVal_Section);
+  ASSERT(retval==0 || retval==RetVal_Section || retval==RetVal_Internal);
 
   DBG(("DocSection::parse() end\n"));
   DocNode *n = g_nodeStack.pop();
@@ -3855,7 +3981,7 @@ void DocRoot::parse()
     }
     if (retval==TK_LISTITEM)
     {
-      printf("Error: Invalid list item found at line %d!\n",doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Invalid list item found");
     }
   } while (retval!=0 && retval!=RetVal_Section && retval!=RetVal_Internal);
   if (lastPar) lastPar->markLast();
@@ -3865,10 +3991,11 @@ void DocRoot::parse()
   {
     SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];
     ASSERT(sec!=0);
+    if (sec==0) break;
     int secLev = sec->type==SectionInfo::Subsection ? 2 : 1;
     if (secLev!=1) // wrong level
     {
-      printf("Error: Expected level 1 section, found a section with level %d at line %d.\n",secLev,doctokenizerYYlineno);
+      warn(g_fileName,doctokenizerYYlineno,"Error: Expected level 1 section, found a section with level %d",secLev);
       break;
     }
     else
@@ -3893,14 +4020,17 @@ void DocRoot::parse()
 //--------------------------------------------------------------------------
 
 DocNode *validatingParseDoc(const char *fileName,int startLine,
-                            const char *context,const char *input)
+                            const char *context,MemberDef *md,
+                            const char *input)
 {
-  printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",input);
+  //printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",input);
   
-  printf("========== validating %s at line %d\n",fileName,startLine);
+  //printf("========== validating %s at line %d\n",fileName,startLine);
   g_token = new TokenInfo;
 
   g_context = context;
+  g_fileName = fileName;
+  g_memberDef = md;
   g_nodeStack.clear();
   g_styleStack.clear();
   g_inSeeBlock = FALSE;
@@ -3908,6 +4038,9 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
   g_includeFileText.resize(0);
   g_includeFileOffset = 0;
   g_includeFileLength = 0;
+  g_hasParamCommand = FALSE;
+  g_paramsFound.setAutoDelete(FALSE);
+  g_paramsFound.clear();
   
   doctokenizerYYlineno=startLine;
   doctokenizerYYinit(input);
@@ -3923,6 +4056,8 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
     root->accept(v);
   }
 
+  checkUndocumentedParams();
+
   delete g_token;
 
   // TODO: These should be called at the end of the program.
diff --git a/src/docparser.h b/src/docparser.h
index ccb06e5..e5a76f3 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -27,6 +27,7 @@
 #include "doctokenizer.h"
 
 class DocNode;
+class MemberDef;
 
 //---------------------------------------------------------------------------
 
@@ -40,7 +41,8 @@ class DocNode;
  *                   pointer is handed over to the caller.
  */
 DocNode *validatingParseDoc(const char *fileName,int startLine,
-                            const char *context, const char *input);
+                            const char *context, MemberDef *md,
+                            const char *input);
 
 //---------------------------------------------------------------------------
 
@@ -380,9 +382,10 @@ class DocFormula : public DocNode
 {
   public:
     DocFormula(DocNode *parent,int id);
-    Kind kind() const { return Kind_Formula; }
-    QCString name() const { return m_name; }
-    QCString text() const { return m_text; }
+    Kind kind() const       { return Kind_Formula; }
+    QCString name() const   { return m_name; }
+    QCString text() const   { return m_text; }
+    int id() const          { return m_id; }
     DocNode *parent() const { return m_parent; }
     void accept(DocVisitor *v) { v->visit(this); }
 
@@ -390,39 +393,42 @@ class DocFormula : public DocNode
     DocNode *m_parent;
     QCString m_name;
     QCString m_text;
+    int m_id;
 };
 
-//-----------------------------------------------------------------------
-
-/*! @brief Node representing a entry in the index. */
-class DocCopy : public CompAccept<DocCopy>, public DocNode
+/*! @brief Node representing an entry in the index. */
+class DocIndexEntry : public DocNode
 {
   public:
-    DocCopy(DocNode *parent,const QCString &link) 
-      : m_parent(parent), m_link(link) { }
+    DocIndexEntry(DocNode *parent) : m_parent(parent) { }
     Kind kind() const { return Kind_IndexEntry; }
-    QCString link() const { return m_link; }
-    void parse();
+    int parse();
     DocNode *parent() const { return m_parent; }
-    void accept(DocVisitor *v) { CompAccept<DocCopy>::accept(this,v); }
+    void accept(DocVisitor *v) { v->visit(this); }
+    QCString entry() { return m_entry; }
 
   private:
     DocNode *m_parent;
-    QCString m_link;
+    QCString m_entry;
 };
 
+//-----------------------------------------------------------------------
+
 /*! @brief Node representing a entry in the index. */
-class DocIndexEntry : public CompAccept<DocIndexEntry>, public DocNode
+class DocCopy : public CompAccept<DocCopy>, public DocNode
 {
   public:
-    DocIndexEntry(DocNode *parent) : m_parent(parent) { }
+    DocCopy(DocNode *parent,const QCString &link) 
+      : m_parent(parent), m_link(link) { }
     Kind kind() const { return Kind_IndexEntry; }
-    int parse();
+    QCString link() const { return m_link; }
+    void parse();
     DocNode *parent() const { return m_parent; }
-    void accept(DocVisitor *v) { CompAccept<DocIndexEntry>::accept(this,v); }
+    void accept(DocVisitor *v) { CompAccept<DocCopy>::accept(this,v); }
 
   private:
     DocNode *m_parent;
+    QCString m_link;
 };
 
 /*! @brief Node representing an auto List */
@@ -866,7 +872,8 @@ class DocPara : public CompAccept<DocPara>, public DocNode
 class DocParamList : public DocNode
 {
   public:
-    DocParamList(DocNode *parent) : m_parent(parent) 
+    DocParamList(DocNode *parent,DocParamSect::Type t) 
+      : m_parent(parent) , m_type(t)
     { m_paragraph=new DocPara(this); }
     virtual ~DocParamList()
     { delete m_paragraph; }
@@ -874,6 +881,7 @@ class DocParamList : public DocNode
     Kind kind() const { return Kind_ParamList; }
     DocNode *parent() const { return m_parent; }
     const QStrList &parameters() { return m_params; }
+    DocParamSect::Type type() const { return m_type; }
     void accept(DocVisitor *v)
     { 
       v->visitPre(this); 
@@ -882,9 +890,10 @@ class DocParamList : public DocNode
     }
 
   private:
-    DocNode   *m_parent;
-    DocPara   *m_paragraph;
-    QStrList   m_params;
+    DocNode     *m_parent;
+    DocPara     *m_paragraph;
+    QStrList     m_params;
+    DocParamSect::Type m_type;
 };
 
 /*! @brief Node representing an item of a auto list */
@@ -1049,7 +1058,15 @@ class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode
       }
       return cols;
     }
-    void accept(DocVisitor *v) { CompAccept<DocHtmlTable>::accept(this,v); }
+    void accept(DocVisitor *v) 
+    { 
+      v->visitPre(this); 
+      QListIterator<DocNode> cli(m_children);
+      DocNode *n;
+      for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
+      if (m_caption) m_caption->accept(v);
+      v->visitPost(this); 
+    }
 
   private:
     DocNode *          m_parent;
diff --git a/src/docvisitor.h b/src/docvisitor.h
index 771971f..4ccbd0e 100644
--- a/src/docvisitor.h
+++ b/src/docvisitor.h
@@ -87,6 +87,7 @@ class DocVisitor
     virtual void visit(DocIncOperator *) = 0;
     virtual void visit(DocFormula *) = 0;
     virtual void visit(DocLinkedWord *) = 0;
+    virtual void visit(DocIndexEntry *) = 0;
 
     /*! @name Visitor functions for internal nodes */
     virtual void visitPre(DocAutoList *) = 0;
@@ -127,8 +128,6 @@ class DocVisitor
     virtual void visitPost(DocHtmlTable *) = 0;
     virtual void visitPre(DocHtmlCaption *) = 0;
     virtual void visitPost(DocHtmlCaption *) = 0;
-    virtual void visitPre(DocIndexEntry *) = 0;
-    virtual void visitPost(DocIndexEntry *) = 0;
     virtual void visitPre(DocInternal *) = 0;
     virtual void visitPost(DocInternal *) = 0;
     virtual void visitPre(DocHRef *) = 0;
diff --git a/src/dot.cpp b/src/dot.cpp
index b1d4c05..58c05d3 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -1777,6 +1777,7 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir,
   QCString oldDir = convertToQCString(QDir::currentDirPath());
   // go to the html output directory (i.e. path)
   QDir::setCurrent(outDir);
+  //printf("Going to dir %s\n",QDir::currentDirPath().data());
 
   //{ // copy input file to output dir.
   //  QFile inf(inFile,IO_ReadOnly);
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index f9bfa53..7e6f385 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -23,6 +23,7 @@
 #include "outputgen.h"
 #include "code.h"
 #include "dot.h"
+#include "message.h"
 
 HtmlDocVisitor::HtmlDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) 
   : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) 
@@ -82,18 +83,20 @@ void HtmlDocVisitor::visit(DocSymbol *s)
     case DocSymbol::Circ:    m_t << "&" << s->letter() << "circ;"; break;
     case DocSymbol::Tilde:   m_t << "&" << s->letter() << "tilde;"; break;
     case DocSymbol::Szlig:   m_t << "&szlig;"; break;
-    case DocSymbol::Cedil:   m_t << "&" << s->letter() << "cedul;"; break;
+    case DocSymbol::Cedil:   m_t << "&" << s->letter() << "cedil;"; break;
     case DocSymbol::Ring:    m_t << "&" << s->letter() << "ring;"; break;
     case DocSymbol::Nbsp:    m_t << "&nbsp;"; break;
     default:
-                             printf("Error: unknown symbol found\n");
+                             err("Error: unknown symbol found\n");
   }
 }
 
 void HtmlDocVisitor::visit(DocURL *u)
 {
   if (m_hide) return;
-  m_t << "<a href=\"" << u->url() << "\">" << u->url() << "</a>";
+  m_t << "<a href=\"" << u->url() << "\">";
+  filter(u->url());
+  m_t << "</a>";
 }
 
 void HtmlDocVisitor::visit(DocLineBreak *)
@@ -161,10 +164,10 @@ void HtmlDocVisitor::visit(DocVerbatim *s)
   }
 }
 
-void HtmlDocVisitor::visit(DocAnchor *)
+void HtmlDocVisitor::visit(DocAnchor *anc)
 {
   if (m_hide) return;
-  m_t << "<a name=\"%s\"/></a>";
+  m_t << "<a name=\"" /*<< anc->file() << "#"*/ << anc->anchor() << "\"/></a>";
 }
 
 void HtmlDocVisitor::visit(DocInclude *inc)
@@ -233,6 +236,10 @@ void HtmlDocVisitor::visit(DocFormula *f)
     m_t << " ";
 }
 
+void HtmlDocVisitor::visit(DocIndexEntry *)
+{
+}
+
 //--------------------------------------
 // visitor functions for compound nodes
 //--------------------------------------
@@ -376,8 +383,8 @@ void HtmlDocVisitor::visitPre(DocSection *s)
 {
   m_t << "<h" << s->level()+1 << ">";
   m_t << "<a name=\"" << s->anchor();
+  m_t << "\"></a>" << endl;
   filter(s->title());
-  m_t << "\"</a>" << endl;
   m_t << "</h" << s->level()+1 << ">\n";
 }
 
@@ -493,16 +500,6 @@ void HtmlDocVisitor::visitPost(DocHtmlCaption *)
   m_t << "</caption>\n";
 }
 
-void HtmlDocVisitor::visitPre(DocIndexEntry *)
-{
-  m_hide = TRUE;
-}
-
-void HtmlDocVisitor::visitPost(DocIndexEntry *) 
-{
-  m_hide = FALSE;
-}
-
 void HtmlDocVisitor::visitPre(DocInternal *)
 {
   m_t << "<p><b>" << theTranslator->trForInternalUseOnly() << "</b></p>" << endl;
diff --git a/src/htmldocvisitor.h b/src/htmldocvisitor.h
index 2be1fa5..7d3470e 100644
--- a/src/htmldocvisitor.h
+++ b/src/htmldocvisitor.h
@@ -48,6 +48,7 @@ class HtmlDocVisitor : public DocVisitor
     void visit(DocInclude *);
     void visit(DocIncOperator *);
     void visit(DocFormula *);
+    void visit(DocIndexEntry *);
 
     //--------------------------------------
     // visitor functions for compound nodes
@@ -91,8 +92,6 @@ class HtmlDocVisitor : public DocVisitor
     void visitPost(DocHtmlCell *);
     void visitPre(DocHtmlCaption *);
     void visitPost(DocHtmlCaption *);
-    void visitPre(DocIndexEntry *);
-    void visitPost(DocIndexEntry *);
     void visitPre(DocInternal *);
     void visitPost(DocInternal *);
     void visitPre(DocHRef *);
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index f95d2d7..7962c0b 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -526,9 +526,11 @@ void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::Secti
 {
   switch(type)
   {
-    case SectionInfo::Page:       t << "<h1>"; break;
-    case SectionInfo::Section:    t << "<h2>"; break;
-    case SectionInfo::Subsection: t << "<h3>"; break;
+    case SectionInfo::Page:          t << "<h1>"; break;
+    case SectionInfo::Section:       t << "<h2>"; break;
+    case SectionInfo::Subsection:    t << "<h3>"; break;
+    case SectionInfo::Subsubsection: t << "<h4>"; break;
+    case SectionInfo::Paragraph:     t << "<h5>"; break;
     default: ASSERT(0); break;
   }
   t << "<a name=\"" << lab << "\">";
@@ -539,9 +541,11 @@ void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type)
   t << "</a>" << endl;
   switch(type)
   {
-    case SectionInfo::Page:       t << "</h1>"; break;
-    case SectionInfo::Section:    t << "</h2>"; break;
-    case SectionInfo::Subsection: t << "</h3>"; break;
+    case SectionInfo::Page:          t << "</h1>"; break;
+    case SectionInfo::Section:       t << "</h2>"; break;
+    case SectionInfo::Subsection:    t << "</h3>"; break;
+    case SectionInfo::Subsubsection: t << "</h4>"; break;
+    case SectionInfo::Paragraph:     t << "</h5>"; break;
     default: ASSERT(0); break;
   }
 }
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
index c6a13ab..bc1b17c 100644
--- a/src/latexdocvisitor.cpp
+++ b/src/latexdocvisitor.cpp
@@ -24,6 +24,48 @@
 #include "code.h"
 #include "dot.h"
 #include "util.h"
+#include "message.h"
+
+static QCString escapeLabelName(const char *s)
+{
+  QCString result;
+  const char *p=s;
+  char c;
+  while ((c=*p++))
+  {
+    switch (c)
+    {
+      case '%': result+="\\%"; break;
+      case '|': result+="\\texttt{\"|}"; break;
+      case '!': result+="\"!"; break;
+      default: result+=c;
+    }
+  }
+  return result;
+}
+
+QCString LatexDocVisitor::escapeMakeIndexChars(const char *s)
+{
+  QCString result;
+  const char *p=s;
+  char str[2]; str[1]=0;
+  char c;
+  while ((c=*p++))
+  {
+    switch (c)
+    {
+      case '!': m_t << "\"!"; break;
+      case '"': m_t << "\"\""; break;
+      case '@': m_t << "\"@"; break;
+      case '|': m_t << "\\texttt{\"|}"; break;
+      case '[': m_t << "["; break;
+      case ']': m_t << "]"; break;
+      default:  str[0]=c; filter(str); break;
+    }
+  }
+  return result;
+}
+
 
 LatexDocVisitor::LatexDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) 
   : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) 
@@ -107,7 +149,7 @@ void LatexDocVisitor::visit(DocSymbol *s)
     case DocSymbol::Ring:    m_t << "\\" << s->letter() << s->letter(); break;
     case DocSymbol::Nbsp:    m_t << "\\ "; break;
     default:
-                             printf("Error: unknown symbol found\n");
+                             err("Error: unknown symbol found\n");
   }
 }
 
@@ -249,6 +291,13 @@ void LatexDocVisitor::visit(DocFormula *f)
   m_t << f->text();
 }
 
+void LatexDocVisitor::visit(DocIndexEntry *i)
+{
+  m_t << "\\index{" << escapeLabelName(i->entry()) << "@{";
+  escapeMakeIndexChars(i->entry());
+  m_t << "}}";
+}
+
 //--------------------------------------
 // visitor functions for compound nodes
 //--------------------------------------
@@ -390,26 +439,24 @@ void LatexDocVisitor::visitPre(DocSection *s)
   {
     m_t << "\\hypertarget{" << s->file() << "_" << s->anchor() << "}{}";
   }
-  if (s->level()==1)
+  if (Config_getBool("COMPACT_LATEX"))
   {
-    if (Config_getBool("COMPACT_LATEX"))
-    {
-      m_t << "\\subsubsection{";
-    }
-    else
+    switch(s->level())
     {
-      m_t << "\\subsection{";
+      case 1: m_t << "\\subsubsection{"; break;
+      case 2: m_t << "\\paragraph{";     break;
+      case 3: m_t << "\\subparagraph{";  break;
+      case 4: m_t << "\\subparagraph{";  break;
     }
   }
-  else if (s->level()==2)
+  else
   {
-    if (Config_getBool("COMPACT_LATEX"))
-    {
-      m_t << "\\paragraph{";
-    }
-    else
+    switch(s->level())
     {
-      m_t << "\\subsubsection{";
+      case 1: m_t << "\\subsection{";    break;
+      case 2: m_t << "\\subsubsection{"; break;
+      case 3: m_t << "\\paragraph{";     break;
+      case 4: m_t << "\\subparagraph{";  break;
     }
   }
   filter(s->title());
@@ -534,16 +581,6 @@ void LatexDocVisitor::visitPost(DocHtmlCell *c)
   if (!c->isLast()) m_t << "&";
 }
 
-void LatexDocVisitor::visitPre(DocIndexEntry *)
-{
-  m_hide = TRUE;
-}
-
-void LatexDocVisitor::visitPost(DocIndexEntry *) 
-{
-  m_hide = FALSE;
-}
-
 void LatexDocVisitor::visitPre(DocInternal *)
 {
   m_t << "\\begin{Desc}" << endl 
@@ -577,18 +614,18 @@ void LatexDocVisitor::visitPre(DocHtmlHeader *header)
   {
     switch(header->level())
     {
-      case 1: m_t << "\\subsection{"; break;
-      case 2: m_t << "\\subsubsection{"; break;
-      case 3: m_t << "\\paragraph{"; break;
+      case 1: m_t << "\\subsection*{"; break;
+      case 2: m_t << "\\subsubsection*{"; break;
+      case 3: m_t << "\\paragraph*{"; break;
     }
   }
   else
   {
     switch(header->level())
     {
-      case 1: m_t << "\\section{"; break;
-      case 2: m_t << "\\subsection{"; break;
-      case 3: m_t << "\\subsubsection{"; break;
+      case 1: m_t << "\\section*{"; break;
+      case 2: m_t << "\\subsection*{"; break;
+      case 3: m_t << "\\subsubsection*{"; break;
     }
   }
 }
diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h
index f3a724f..504da97 100644
--- a/src/latexdocvisitor.h
+++ b/src/latexdocvisitor.h
@@ -48,6 +48,7 @@ class LatexDocVisitor : public DocVisitor
     void visit(DocInclude *);
     void visit(DocIncOperator *);
     void visit(DocFormula *);
+    void visit(DocIndexEntry *);
 
     //--------------------------------------
     // visitor functions for compound nodes
@@ -91,8 +92,6 @@ class LatexDocVisitor : public DocVisitor
     void visitPost(DocHtmlRow *) ;
     void visitPre(DocHtmlCell *);
     void visitPost(DocHtmlCell *);
-    void visitPre(DocIndexEntry *);
-    void visitPost(DocIndexEntry *);
     void visitPre(DocInternal *);
     void visitPost(DocInternal *);
     void visitPre(DocHRef *);
@@ -134,6 +133,7 @@ class LatexDocVisitor : public DocVisitor
     void startLink(const QCString &ref,const QCString &file,
                    const QCString &anchor);
     void endLink();
+    QCString escapeMakeIndexChars(const char *s);
 
     //--------------------------------------
     // state variables
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index af236dc..5c49d23 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -1209,9 +1209,11 @@ void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::Sect
   {
     switch(type)
     {
-      case SectionInfo::Page:       t << "subsection"; break;
-      case SectionInfo::Section:    t << "subsubsection"; break;
-      case SectionInfo::Subsection: t << "paragraph"; break;
+      case SectionInfo::Page:          t << "subsection"; break;
+      case SectionInfo::Section:       t << "subsubsection"; break;
+      case SectionInfo::Subsection:    t << "paragraph"; break;
+      case SectionInfo::Subsubsection: t << "subparagraph"; break;
+      case SectionInfo::Paragraph:     t << "subparagraph"; break;
       default: ASSERT(0); break;
     }
     t << "{";
@@ -1220,9 +1222,11 @@ void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::Sect
   {
     switch(type)
     {
-      case SectionInfo::Page:       t << "section"; break;
-      case SectionInfo::Section:    t << "subsection"; break;
-      case SectionInfo::Subsection: t << "subsubsection"; break;
+      case SectionInfo::Page:          t << "section"; break;
+      case SectionInfo::Section:       t << "subsection"; break;
+      case SectionInfo::Subsection:    t << "subsubsection"; break;
+      case SectionInfo::Subsubsection: t << "paragraph"; break;
+      case SectionInfo::Paragraph:     t << "subparagraph"; break;
       default: ASSERT(0); break;
     }
     t << "{";
diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in
index fbd3771..4d038d7 100644
--- a/src/libdoxygen.pro.in
+++ b/src/libdoxygen.pro.in
@@ -114,7 +114,8 @@ HEADERS      =	bufstr.h \
 		unistd.h \
 		util.h \
 		version.h \
-                xmlgen.h 
+		xmldocvisitor.h \
+                xmlgen.h
 SOURCES      =	ce_lex.cpp \
                 ce_parse.cpp \
 		classdef.cpp \
@@ -174,6 +175,7 @@ SOURCES      =	ce_lex.cpp \
 		translator.cpp \
 		util.cpp \
 		version.cpp \
+		xmldocvisitor.cpp \
                 xmlgen.cpp 
 
 win32:TMAKE_CXXFLAGS       += -DQT_NODLL 
diff --git a/src/mangen.cpp b/src/mangen.cpp
index 8364d65..6464790 100644
--- a/src/mangen.cpp
+++ b/src/mangen.cpp
@@ -28,6 +28,7 @@
 #include "util.h"
 #include "doxygen.h"
 #include <string.h>
+#include "docparser.h"
 
 static QCString getExtension()
 {
@@ -542,9 +543,11 @@ void ManGenerator::startSection(const char *,const char *,SectionInfo::SectionTy
   {
     switch(type)
     {
-      case SectionInfo::Page:       startGroupHeader(); break;
-      case SectionInfo::Section:    startGroupHeader(); break;
-      case SectionInfo::Subsection: startMemberHeader(); break;
+      case SectionInfo::Page:          startGroupHeader(); break;
+      case SectionInfo::Section:       startGroupHeader(); break;
+      case SectionInfo::Subsection:    startMemberHeader(); break;
+      case SectionInfo::Subsubsection: startMemberHeader(); break;
+      case SectionInfo::Paragraph:     startMemberHeader(); break;
       default: ASSERT(0); break;
     }
   }
@@ -556,9 +559,11 @@ void ManGenerator::endSection(const char *,SectionInfo::SectionType type)
   {
     switch(type)
     {
-      case SectionInfo::Page:       endGroupHeader(); break;
-      case SectionInfo::Section:    endGroupHeader(); break;
-      case SectionInfo::Subsection: endMemberHeader(); break;
+      case SectionInfo::Page:          endGroupHeader(); break;
+      case SectionInfo::Section:       endGroupHeader(); break;
+      case SectionInfo::Subsection:    endMemberHeader(); break;
+      case SectionInfo::Subsubsection: endMemberHeader(); break;
+      case SectionInfo::Paragraph:     endMemberHeader(); break;
       default: ASSERT(0); break;
     }
   }
@@ -608,3 +613,7 @@ void ManGenerator::endParamList()
 {
 }
 
+void ManGenerator::printDoc(DocNode *)
+{
+}
+
diff --git a/src/mangen.h b/src/mangen.h
index 35439d6..3f81dfc 100644
--- a/src/mangen.h
+++ b/src/mangen.h
@@ -39,6 +39,8 @@ class ManGenerator : public OutputGenerator
     bool isEnabled(OutputType o) { return (o==Man && active); } 
     OutputGenerator *get(OutputType o) { return (o==Man) ? this : 0; }
 
+    void printDoc(DocNode *);
+
     static void init();
     void startFile(const char *name,const char *manName,
                    const char *title,bool external);
diff --git a/src/outputgen.h b/src/outputgen.h
index 48752cc..5613bc1 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -323,7 +323,7 @@ class OutputGenerator : public BaseOutputDocInterface
     void pushGeneratorState();
     void popGeneratorState();
 
-    virtual void printDoc(DocNode *) {}
+    virtual void printDoc(DocNode *) = 0;
 
     ///////////////////////////////////////////////////////////////
     // structural output interface
diff --git a/src/outputlist.cpp b/src/outputlist.cpp
index 7374aff..f9aadd5 100644
--- a/src/outputlist.cpp
+++ b/src/outputlist.cpp
@@ -192,14 +192,23 @@ void OutputList::popGeneratorState()
 }
 
 void OutputList::parseDoc(const char *fileName,int startLine,
-                  const char * clName,MemberDef * /*md*/,
+                  const char * clName,MemberDef * md,
                   const QCString &docStr)
 {
-  DocNode *root = validatingParseDoc(fileName,startLine,clName,docStr);
-
+  int count=0;
   OutputGenerator *og=outputs->first();
   while (og)
   {
+    if (og->isEnabled()) count++;
+    og=outputs->next();
+  }
+  if (count==0) return; // no output formats enabled.
+
+  DocNode *root = validatingParseDoc(fileName,startLine,clName,md,docStr);
+
+  og=outputs->first();
+  while (og)
+  {
     if (og->isEnabled()) og->printDoc(root);
     og=outputs->next();
   }
diff --git a/src/pre.l b/src/pre.l
index 0219d8e..903b69e 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -98,6 +98,7 @@ static bool               g_nospaces; // add extra spaces during macro expansion
 
 static bool               g_macroExpansion; // from the configuration
 static bool               g_expandOnlyPredef; // from the configuration
+static int                g_commentCount;
 
 
 static void setFileName(const char *name)
@@ -1613,6 +1614,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 					  g_defText+=' ';
 					  g_defLitText+=' ';
 					  g_lastCContext=YY_START;
+					  g_commentCount=1;
   					  BEGIN(SkipCComment);
   					}
 <DefineText>"//"			{
@@ -1622,16 +1624,20 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
   					  BEGIN(SkipCPPComment);
   					}
 <SkipCComment>"*/"			{
-  					  outputChar('*');outputChar('/');
-  					  BEGIN(g_lastCContext);  
+					  if (--g_commentCount<=0)
+					  {
+  					    outputChar('*');outputChar('/');
+  					    BEGIN(g_lastCContext);  
+					  }
   					}
 <SkipCComment>"//"			{
   					  outputChar('/');outputChar('/');
   					}
 <SkipCComment>"/*"			{
   					  outputChar('/');outputChar('*');
+					  g_commentCount++;
   					}
-<SkipCComment>[^*\n]+			{
+<SkipCComment>[^*\n\/]+			{
   					  outputArray(yytext,yyleng);
   					}
 <SkipCComment>\n			{ 
@@ -1809,6 +1815,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 <*>"/*"					{
 					  outputChar('/');outputChar('*');
   					  g_lastCContext=YY_START;
+					  g_commentCount=1;
 					  BEGIN(SkipCComment);
   					}
 <*>"//"					{
diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h
index 9e2247f..55a55ad 100644
--- a/src/printdocvisitor.h
+++ b/src/printdocvisitor.h
@@ -178,6 +178,11 @@ class PrintDocVisitor : public DocVisitor
       indent_leaf();
       printf("<formula name=%s test=%s/>",f->name().data(),f->text().data());
     }
+    void visit(DocIndexEntry *i)
+    {
+      indent_leaf();
+      printf("<indexentry>%s</indexentry\n",i->entry().data());
+    }
 
     //--------------------------------------
     
@@ -408,16 +413,6 @@ class PrintDocVisitor : public DocVisitor
       indent_post();
       printf("</caption>\n");
     }
-    void visitPre(DocIndexEntry *)
-    {
-      indent_pre();
-      printf("<indexentry>\n");
-    }
-    void visitPost(DocIndexEntry *) 
-    {
-      indent_post();
-      printf("</indexentry>\n");
-    }
     void visitPre(DocInternal *)
     {
       indent_pre();
diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp
index 4a4abb9..48f202c 100644
--- a/src/rtfdocvisitor.cpp
+++ b/src/rtfdocvisitor.cpp
@@ -25,6 +25,7 @@
 #include "dot.h"
 #include "util.h"
 #include "rtfstyle.h"
+#include "message.h"
 
 RTFDocVisitor::RTFDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) 
   : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_indentLevel(0) 
@@ -40,6 +41,16 @@ QCString RTFDocVisitor::getStyle(const char *name)
   return sd->reference;
 }
 
+void RTFDocVisitor::incIndentLevel()
+{
+  if (m_indentLevel<rtf_maxIndentLevels-1) m_indentLevel++;
+}
+
+void RTFDocVisitor::decIndentLevel()
+{
+  if (m_indentLevel>0) m_indentLevel--;
+}
+
   //--------------------------------------
   // visitor functions for leaf nodes
   //--------------------------------------
@@ -179,7 +190,7 @@ void RTFDocVisitor::visit(DocSymbol *s)
     case DocSymbol::Szlig:   m_t << "\337"; break;
     case DocSymbol::Nbsp:    m_t << "\\~ "; break;
     default:
-                             printf("Error: unknown symbol found\n");
+                             err("Error: unknown symbol found\n");
   }
 }
 
@@ -188,12 +199,19 @@ void RTFDocVisitor::visit(DocURL *u)
   if (m_hide) return;
   if (Config_getBool("RTF_HYPERLINKS"))
   {
-    m_t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
+    m_t << "{\\field "
+             "{\\*\\fldinst "
+               "{ HYPERLINK  \\\\l \"";
     m_t << u->url();
-    m_t << "\" }{}";
-    m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+    m_t <<  "\" }"
+               "{}";
+    m_t <<   "}"
+             "{\\fldrslt "
+               "{\\cs37\\ul\\cf2 ";
     filter(u->url());
-    m_t << "}}}" << endl;
+    m_t <<     "}"
+             "}"
+           "}" << endl;
   }
   else
   {
@@ -277,12 +295,21 @@ void RTFDocVisitor::visit(DocVerbatim *s)
 void RTFDocVisitor::visit(DocAnchor *anc)
 {
   if (m_hide) return;
-  m_t << "\\label{" << anc->anchor() << "}" << endl;
-  if (!anc->file().isEmpty() && Config_getBool("PDF_HYPERLINKS")) 
+  QCString anchor;
+  if (!anc->file().isEmpty())
   {
-    m_t << "\\hypertarget{" << anc->file() << "_" << anc->anchor() 
-      << "}{}" << endl;
-  }    
+    anchor+=anc->file();
+  }
+  if (!anc->file().isEmpty() && !anc->anchor().isEmpty())
+  {
+    anchor+="_";
+  }
+  if (!anc->anchor().isEmpty())
+  {
+    anchor+=anc->anchor();
+  }
+  m_t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
+  m_t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
 }
 
 void RTFDocVisitor::visit(DocInclude *inc)
@@ -291,18 +318,24 @@ void RTFDocVisitor::visit(DocInclude *inc)
   switch(inc->type())
   {
     case DocInclude::Include: 
-      m_t << "\n\n\\footnotesize\\begin{verbatim}"; 
+      m_t << "{" << endl;
+      m_t << "\\par" << endl;
+      m_t << rtf_Style_Reset << getStyle("CodeExample");
       parseCode(m_ci,inc->context(),inc->text(),FALSE,0);
-      m_t << "\\end{verbatim}\\normalsize" << endl; 
+      m_t << "\\par" << endl; 
+      m_t << "}" << endl;
       break;
     case DocInclude::DontInclude: 
       break;
     case DocInclude::HtmlInclude: 
       break;
     case DocInclude::VerbInclude: 
-      m_t << "\n\n\\footnotesize\\begin{verbatim}"; 
+      m_t << "{" << endl;
+      m_t << "\\par" << endl;
+      m_t << rtf_Style_Reset << getStyle("CodeExample");
       m_t << inc->text();
-      m_t << "\\end{verbatim}\\normalsize" << endl; 
+      m_t << "\\par" << endl; 
+      m_t << "}" << endl;
       break;
   }
 }
@@ -313,7 +346,9 @@ void RTFDocVisitor::visit(DocIncOperator *op)
   //    op->type(),op->isFirst(),op->isLast(),op->text().data());
   if (op->isFirst()) 
   {
-    m_t << "\n\n\\footnotesize\\begin{verbatim}"; 
+    m_t << "{" << endl;
+    m_t << "\\par" << endl;
+    m_t << rtf_Style_Reset << getStyle("CodeExample");
     m_hide = TRUE;
   }
   if (op->type()!=DocIncOperator::Skip) 
@@ -323,7 +358,8 @@ void RTFDocVisitor::visit(DocIncOperator *op)
   if (op->isLast())  
   {
     m_hide = FALSE;
-    m_t << "\\end{verbatim}\\normalsize" << endl; 
+    m_t << "\\par" << endl; 
+    m_t << "}" << endl;
   }
   else
   {
@@ -334,42 +370,50 @@ void RTFDocVisitor::visit(DocIncOperator *op)
 void RTFDocVisitor::visit(DocFormula *f)
 {
   if (m_hide) return;
+  // TODO: do something sensible here, like including a bitmap
   m_t << f->text();
 }
 
+void RTFDocVisitor::visit(DocIndexEntry *i)
+{
+  m_t << "{\\xe \\v " << i->entry() << "}" << endl;
+}
+
 //--------------------------------------
 // visitor functions for compound nodes
 //--------------------------------------
 
 void RTFDocVisitor::visitPre(DocAutoList *l)
 {
-  if (l->isEnumList())
-  {
-    m_t << "\\begin{enumerate}" << endl;
-  }
-  else
-  {
-    m_t << "\\begin{itemize}" << endl;
-  }
+  m_t << "{" << endl;
+  incIndentLevel();
+  rtf_listItemInfo[m_indentLevel].isEnum = l->isEnumList();
+  rtf_listItemInfo[m_indentLevel].number = 1;
 }
 
-void RTFDocVisitor::visitPost(DocAutoList *l)
+void RTFDocVisitor::visitPost(DocAutoList *)
+{
+  m_t << "\\par" << endl;
+  m_t << "}" << endl;
+  decIndentLevel();
+}
+
+void RTFDocVisitor::visitPre(DocAutoListItem *)
 {
-  if (l->isEnumList())
+  m_t << "\\par" << endl;
+  m_t << rtf_Style_Reset;
+  if (rtf_listItemInfo[m_indentLevel].isEnum)
   {
-    m_t << "\\end{enumerate}" << endl;
+    m_t << getStyle("ListEnum") << endl;
+    m_t << rtf_listItemInfo[m_indentLevel].number << ".\\tab ";
+    rtf_listItemInfo[m_indentLevel].number++;
   }
   else
   {
-    m_t << "\\end{itemize}" << endl;
+    m_t << getStyle("ListBullet") << endl;
   }
 }
 
-void RTFDocVisitor::visitPre(DocAutoListItem *)
-{
-  m_t << "\\item ";
-}
-
 void RTFDocVisitor::visitPost(DocAutoListItem *) 
 {
 }
@@ -384,7 +428,7 @@ void RTFDocVisitor::visitPost(DocPara *p)
       !(p->parent() &&           // and for parameter sections
         p->parent()->kind()==DocNode::Kind_ParamSect
        )
-     ) m_t << endl << endl;
+     ) m_t << "\\par" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocRoot *)
@@ -397,7 +441,8 @@ void RTFDocVisitor::visitPost(DocRoot *)
 
 void RTFDocVisitor::visitPre(DocSimpleSect *s)
 {
-  m_t << "\\begin{Desc}\n\\item[";
+  m_t << "{"; // start desc
+  m_t << "{\\b "; // start bold
   switch(s->type())
   {
     case DocSimpleSect::See: 
@@ -435,13 +480,18 @@ void RTFDocVisitor::visitPre(DocSimpleSect *s)
   // special case 1: user defined title
   if (s->type()!=DocSimpleSect::User)
   {
-    m_t << ":]";
+    m_t << ":}"; // end bold
+    m_t << "\\par" << endl;
+    incIndentLevel();
+    m_t << rtf_Style_Reset << getStyle("DescContinue");
   }
 }
 
 void RTFDocVisitor::visitPost(DocSimpleSect *)
 {
-  m_t << "\\end{Desc}" << endl;
+  m_t << "\\par" << endl;
+  decIndentLevel();
+  m_t << "}"; // end desc
 }
 
 void RTFDocVisitor::visitPre(DocTitle *)
@@ -450,22 +500,29 @@ void RTFDocVisitor::visitPre(DocTitle *)
 
 void RTFDocVisitor::visitPost(DocTitle *)
 {
-  m_t << "]";
+  m_t << "}"; // end bold
+  m_t << "\\par" << endl;
+  incIndentLevel();
+  m_t << rtf_Style_Reset << getStyle("DescContinue");
 }
 
 void RTFDocVisitor::visitPre(DocSimpleList *)
 {
-  m_t << "\\begin{itemize}" << endl;
+  m_t << "{" << endl;
+  incIndentLevel();
+  rtf_listItemInfo[m_indentLevel].isEnum = FALSE;
 }
 
 void RTFDocVisitor::visitPost(DocSimpleList *)
 {
-  m_t << "\\end{itemize}" << endl;
+  decIndentLevel();
+  m_t << "\\par" << endl;
+  m_t << "}" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocSimpleListItem *)
 {
-  m_t << "\\item ";
+  m_t << "\\par" << rtf_Style_Reset << getStyle("ListBullet") << endl;
 }
 
 void RTFDocVisitor::visitPost(DocSimpleListItem *) 
@@ -474,59 +531,53 @@ void RTFDocVisitor::visitPost(DocSimpleListItem *)
 
 void RTFDocVisitor::visitPre(DocSection *s)
 {
-  if (Config_getBool("PDF_HYPERLINKS"))
-  {
-    m_t << "\\hypertarget{" << s->file() << "_" << s->anchor() << "}{}";
-  }
-  if (s->level()==1)
-  {
-    if (Config_getBool("COMPACT_LATEX"))
-    {
-      m_t << "\\subsubsection{";
-    }
-    else
-    {
-      m_t << "\\subsection{";
-    }
-  }
-  else if (s->level()==2)
-  {
-    if (Config_getBool("COMPACT_LATEX"))
-    {
-      m_t << "\\paragraph{";
-    }
-    else
-    {
-      m_t << "\\subsubsection{";
-    }
-  }
+  m_t << "{" // start section
+      << rtf_Style_Reset;
+  QCString heading;
+  int level = QMIN(s->level()+2,4);
+  heading.sprintf("Heading%d",level);
+  // set style
+  m_t << rtf_Style[heading]->reference;
+  // make table of contents entry
+  m_t << "{\\tc\\tcl" << level << " \\v ";
   filter(s->title());
-  m_t << "}\\label{" << s->anchor() << "}" << endl;
+  m_t << "}" << endl;
 }
 
 void RTFDocVisitor::visitPost(DocSection *) 
 {
+  m_t << "\\par" << endl;
+  m_t << "}"; // end section
 }
 
-void RTFDocVisitor::visitPre(DocHtmlList *s)
+void RTFDocVisitor::visitPre(DocHtmlList *l)
 {
-  if (s->type()==DocHtmlList::Ordered) 
-    m_t << "\\begin{enumerate}" << endl; 
-  else 
-    m_t << "\\begin{itemize}" << endl;
+  m_t << "{" << endl;
+  incIndentLevel();
+  rtf_listItemInfo[m_indentLevel].isEnum = l->type()==DocHtmlList::Ordered; 
+  rtf_listItemInfo[m_indentLevel].number = 1;
 }
 
-void RTFDocVisitor::visitPost(DocHtmlList *s) 
+void RTFDocVisitor::visitPost(DocHtmlList *) 
 {
-  if (s->type()==DocHtmlList::Ordered) 
-    m_t << "\\end{enumerate}" << endl; 
-  else 
-    m_t << "\\end{itemize}" << endl;
+  m_t << "\\par" << endl << "}" << endl;
+  decIndentLevel();
 }
 
 void RTFDocVisitor::visitPre(DocHtmlListItem *)
 {
-  m_t << "\\item ";
+  m_t << "\\par" << endl;
+  m_t << rtf_Style_Reset;
+  if (rtf_listItemInfo[m_indentLevel].isEnum)
+  {
+    m_t << getStyle("ListEnum") << endl;
+    m_t << rtf_listItemInfo[m_indentLevel].number << ".\\tab ";
+    rtf_listItemInfo[m_indentLevel].number++;
+  }
+  else
+  {
+    m_t << getStyle("ListBullet") << endl;
+  }
 }
 
 void RTFDocVisitor::visitPost(DocHtmlListItem *) 
@@ -535,34 +586,41 @@ void RTFDocVisitor::visitPost(DocHtmlListItem *)
 
 void RTFDocVisitor::visitPre(DocHtmlPre *)
 {
-  m_t << "\\small\\begin{alltt}";
+  m_t << "{" << endl;
+  m_t << "\\par" << endl;
+  m_t << rtf_Style_Reset << getStyle("CodeExample");
   m_insidePre=TRUE;
 }
 
 void RTFDocVisitor::visitPost(DocHtmlPre *) 
 {
   m_insidePre=FALSE;
-  m_t << "\\end{alltt}\\normalsize " << endl;
+  m_t << "\\par" << endl; 
+  m_t << "}" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocHtmlDescList *)
 {
-  m_t << "\\begin{description}" << endl;
+  m_t << "{" << endl;
+  m_t << rtf_Style_Reset << getStyle("ListContinue");
 }
 
 void RTFDocVisitor::visitPost(DocHtmlDescList *) 
 {
-  m_t << "\\end{description}" << endl;
+  m_t << "}" << endl;
+  m_t << "\\par" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocHtmlDescTitle *)
 {
-  m_t << "\\item[";
+  m_t << "\\par" << endl;
+  m_t << "{\\b ";
 }
 
 void RTFDocVisitor::visitPost(DocHtmlDescTitle *) 
 {
-  m_t << "]";
+  m_t << "}" << endl;
+  m_t << "\\par" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocHtmlDescData *)
@@ -573,173 +631,163 @@ void RTFDocVisitor::visitPost(DocHtmlDescData *)
 {
 }
 
-void RTFDocVisitor::visitPre(DocHtmlTable *t)
+void RTFDocVisitor::visitPre(DocHtmlTable *)
 {
-  if (t->hasCaption()) 
-  {
-    m_t << "\\begin{table}[h]";
-  }
-  m_t << "\\begin{TabularC}{" << t->numCols() << "}\n\\hline\n";
+  m_t << "\\par" << endl;
 }
 
 void RTFDocVisitor::visitPost(DocHtmlTable *t) 
 {
-  if (t->hasCaption())
+  if (!t->hasCaption())
   {
-    m_t << "\\end{table}\n";
-  }
-  else
-  {
-    m_t << "\\\\\\hline\n\\end{TabularC}\n";
+    m_t << endl; 
+    m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
+    m_t << "{\\row }" << endl;
   }
+  m_t << "\\pard" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocHtmlCaption *)
 {
-  m_t << "\\\\\\hline\n\\end{TabularC}\n\\centering\n\\caption{";
 }
 
 void RTFDocVisitor::visitPost(DocHtmlCaption *) 
 {
-  m_t << "}\n";
 }
 
-void RTFDocVisitor::visitPre(DocHtmlRow *)
+void RTFDocVisitor::visitPre(DocHtmlRow *r)
 {
+  uint i,columnWidth=rtf_pageWidth/r->numCells();
+  m_t << "\\trowd \\trgaph108\\trleft-108"
+         "\\trbrdrt\\brdrs\\brdrw10 "
+         "\\trbrdrl\\brdrs\\brdrw10 "
+         "\\trbrdrb\\brdrs\\brdrw10 "
+         "\\trbrdrr\\brdrs\\brdrw10 "
+         "\\trbrdrh\\brdrs\\brdrw10 "
+         "\\trbrdrv\\brdrs\\brdrw10 "<< endl;
+  for (i=0;i<r->numCells();i++)
+  {
+    m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 "
+           "\\clbrdrl\\brdrs\\brdrw10 "
+           "\\clbrdrb\\brdrs\\brdrw10 "
+           "\\clbrdrr \\brdrs\\brdrw10 "
+           "\\cltxlrtb "
+           "\\cellx" << (i*columnWidth) << endl;
+  }
+  m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
 }
 
 void RTFDocVisitor::visitPost(DocHtmlRow *) 
 {
-  m_t << "\\\\\\hline\n";
+  m_t << endl;
+  m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
+  m_t << "{\\row }" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocHtmlCell *)
 {
+  m_t << "{";
 }
 
-void RTFDocVisitor::visitPost(DocHtmlCell *c) 
-{
-  if (!c->isLast()) m_t << "&";
-}
-
-void RTFDocVisitor::visitPre(DocIndexEntry *)
+void RTFDocVisitor::visitPost(DocHtmlCell *) 
 {
-  m_hide = TRUE;
-}
-
-void RTFDocVisitor::visitPost(DocIndexEntry *) 
-{
-  m_hide = FALSE;
+  m_t << "\\cell }";
 }
 
 void RTFDocVisitor::visitPre(DocInternal *)
 {
-  m_t << "\\begin{Desc}" << endl 
-    << "\\item[" << theTranslator->trForInternalUseOnly() << "]" << endl;
+  m_t << "{"; // start desc
+  m_t << "{\\b "; // start bold
+  m_t << theTranslator->trForInternalUseOnly();
+  m_t << "}"; // end bold
+  m_t << "\\par" << endl;
+  incIndentLevel();
+  m_t << rtf_Style_Reset << getStyle("DescContinue");
 }
 
 void RTFDocVisitor::visitPost(DocInternal *) 
 {
-  m_t << "\\end{Desc}" << endl;
+  m_t << "\\par" << endl;
+  decIndentLevel();
+  m_t << "}"; // end desc
 }
 
 void RTFDocVisitor::visitPre(DocHRef *href)
 {
-  if (Config_getBool("PDF_HYPERLINKS"))
+  if (Config_getBool("RTF_HYPERLINKS"))
   {
-    m_t << "\\href{";
-    m_t << href->url();
-    m_t << "}";
+    m_t << "{\\field "
+             "{\\*\\fldinst "
+               "{ HYPERLINK  \\\\l \"" << href->url() << "\" "
+               "}{}"
+             "}"
+             "{\\fldrslt "
+               "{\\cs37\\ul\\cf2 ";
+
+  }
+  else
+  {
+    m_t << "{\\f2 ";
   }
-  m_t << "{\\tt ";
 }
 
 void RTFDocVisitor::visitPost(DocHRef *) 
 {
-  m_t << "}";
-}
-
-void RTFDocVisitor::visitPre(DocHtmlHeader *header)
-{
-  if (Config_getBool("COMPACT_LATEX"))
-  {
-    switch(header->level())
-    {
-      case 1: m_t << "\\subsection{"; break;
-      case 2: m_t << "\\subsubsection{"; break;
-      case 3: m_t << "\\paragraph{"; break;
-    }
+  if (Config_getBool("RTF_HYPERLINKS"))
+  { 
+    m_t <<     "}"
+             "}"
+           "}";
   }
   else
   {
-    switch(header->level())
-    {
-      case 1: m_t << "\\section{"; break;
-      case 2: m_t << "\\subsection{"; break;
-      case 3: m_t << "\\subsubsection{"; break;
-    }
+    m_t << "}";
   }
 }
 
+void RTFDocVisitor::visitPre(DocHtmlHeader *header)
+{
+  m_t << "{" // start section
+      << rtf_Style_Reset;
+  QCString heading;
+  int level = QMIN(header->level()+2,4);
+  heading.sprintf("Heading%d",level);
+  // set style
+  m_t << rtf_Style[heading]->reference;
+  // make table of contents entry
+  m_t << "{\\tc\\tcl \\v " << level << "}";
+  
+}
+
 void RTFDocVisitor::visitPost(DocHtmlHeader *) 
 {
-  m_t << "}";
+  m_t << "\\par" << endl;
+  m_t << "}" << endl; // end section
 }
 
 void RTFDocVisitor::visitPre(DocImage *img)
 {
-  if (img->type()==DocImage::Latex)
+  if (img->type()==DocImage::Rtf)
   {
-    if (img->hasCaption())
-    {
-      m_t << "\\begin{figure}[H]" << endl;
-      m_t << "\\begin{center}" << endl;
-    }
-    else
-    {
-      m_t << "\\mbox{";
-    }
-    QCString gfxName = img->name();
-    if (gfxName.right(4)==".eps" || gfxName.right(4)==".pdf")
-    {
-      gfxName=gfxName.left(gfxName.length()-4);
-    }
-    m_t << "\\includegraphics";
-    if (!img->width().isEmpty())
-    {
-      m_t << "[width=" << img->width() << "]";
-    }
-    else if (!img->height().isEmpty())
-    {
-      m_t << "[height=" << img->height() << "]";
-    }
-    m_t << "{" << gfxName << "}";
-    if (img->hasCaption())
-    {
-      m_t << "\\caption{";
-    }
+    m_t << "\\par" << endl;
+    m_t << "{" << endl;
+    m_t << rtf_Style_Reset << endl;
+    m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
+    m_t << img->name();
+    m_t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+    m_t << "}" << endl;
+
   }
   else // other format -> skip
   {
-    m_hide=TRUE;
   }
+  // hide caption since it is not supported at the moment
+  m_hide=TRUE;
 }
 
-void RTFDocVisitor::visitPost(DocImage *img) 
+void RTFDocVisitor::visitPost(DocImage *) 
 {
-  if (img->type()==DocImage::Latex)
-  {
-    m_t << "}" << endl; // end mbox or caption
-    if (img->hasCaption())
-    {
-      m_t << "\\end{center}" << endl;
-      m_t << "\\end{figure}" << endl;
-    }
-  }
-  else // other format
-  {
-    m_hide=FALSE;
-  }
+  m_hide=FALSE;
 }
 
 void RTFDocVisitor::visitPre(DocDotFile *df)
@@ -750,46 +798,23 @@ void RTFDocVisitor::visitPre(DocDotFile *df)
   {
     baseName=baseName.right(baseName.length()-i-1);
   } 
-  if (baseName.right(4)==".eps" || baseName.right(4)==".pdf")
-  {
-    baseName=baseName.left(baseName.length()-4);
-  }
-  QCString outDir = Config_getString("LATEX_OUTPUT");
-  writeDotGraphFromFile(df->file(),outDir,baseName,EPS);
-  if (df->hasCaption())
-  {
-    m_t << "\\begin{figure}[H]" << endl;
-    m_t << "\\begin{center}" << endl;
-  }
-  else
-  {
-    m_t << "\\mbox{";
-  }
-  m_t << "\\includegraphics";
-  if (!df->width().isEmpty())
-  {
-    m_t << "[width=" << df->width() << "]";
-  }
-  else if (!df->height().isEmpty())
-  {
-    m_t << "[height=" << df->height() << "]";
-  }
-  m_t << "{" << baseName << "}";
+  QCString outDir = Config_getString("RTF_OUTPUT");
+  writeDotGraphFromFile(df->file(),outDir,baseName,BITMAP);
+  m_t << "\\par" << endl;
+  m_t << "{" << endl;
+  m_t << rtf_Style_Reset << endl;
+  m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
+  m_t << outDir << "\\" << baseName;
+  m_t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+  m_t << "}" << endl;
 
-  if (df->hasCaption())
-  {
-    m_t << "\\caption{";
-  }
+  // hide caption since it is not supported at the moment
+  m_hide=TRUE;
 }
 
-void RTFDocVisitor::visitPost(DocDotFile *df) 
+void RTFDocVisitor::visitPost(DocDotFile *) 
 {
-  m_t << "}" << endl; // end mbox or caption
-  if (df->hasCaption())
-  {
-    m_t << "\\end{center}" << endl;
-    m_t << "\\end{figure}" << endl;
-  }
+  m_hide=FALSE;
 }
 
 void RTFDocVisitor::visitPre(DocLink *lnk)
@@ -814,28 +839,28 @@ void RTFDocVisitor::visitPost(DocRef *ref)
   m_t << " ";
 }
 
+
 void RTFDocVisitor::visitPre(DocSecRefItem *)
 {
-  m_t << "\\item \\contentsline{section}{";
 }
 
-void RTFDocVisitor::visitPost(DocSecRefItem *ref) 
+void RTFDocVisitor::visitPost(DocSecRefItem *) 
 {
-  m_t << "}{\\ref{" << ref->anchor() << "}}{}" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocSecRefList *)
 {
-  m_t << "\\footnotesize" << endl;
-  m_t << "\\begin{multicols}{2}" << endl;
-  m_t << "\\begin{CompactList}" << endl;
+  m_t << "{" << endl;
+  incIndentLevel();
+  m_t << rtf_Style_Reset << getStyle("LatexTOC") << endl;
+  m_t << "\\par" << endl;
 }
 
 void RTFDocVisitor::visitPost(DocSecRefList *) 
 {
-  m_t << "\\end{CompactList}" << endl;
-  m_t << "\\end{multicols}" << endl;
-  m_t << "\\normalsize" << endl;
+  decIndentLevel();
+  m_t << "\\par" << endl;
+  m_t << "}";
 }
 
 void RTFDocVisitor::visitPre(DocLanguage *)
@@ -848,8 +873,9 @@ void RTFDocVisitor::visitPost(DocLanguage *)
 
 void RTFDocVisitor::visitPre(DocParamSect *s)
 {
-  m_t << "\\begin{Desc}" << endl;
-  m_t << "\\item[";
+  m_t << "{"; // start param list
+  m_t << "{\\b "; // start bold
+  m_t << "\\par" << endl;
   switch(s->type())
   {
     case DocParamSect::Param: 
@@ -861,19 +887,22 @@ void RTFDocVisitor::visitPre(DocParamSect *s)
     default:
       ASSERT(0);
   }
-  m_t << ":]" << endl;
-  m_t << "\\begin{description}" << endl;
+  m_t << ":}" << endl;
+  m_t << "\\par" << endl;
+  incIndentLevel();
+  m_t << rtf_Style_Reset << getStyle("DescContinue");
 }
 
 void RTFDocVisitor::visitPost(DocParamSect *)
 {
-  m_t << "\\end{description}" << endl;
-  m_t << "\\end{Desc}" << endl;
+  m_t << "\\par" << endl;
+  decIndentLevel();
+  m_t << "}" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocParamList *pl)
 {
-  m_t << "\\item[{\\em ";
+  m_t << "{\\i ";
   QStrListIterator li(pl->parameters());
   const char *s;
   bool first=TRUE;
@@ -882,32 +911,60 @@ void RTFDocVisitor::visitPre(DocParamList *pl)
     if (!first) m_t << ","; else first=FALSE;
     m_t << s;
   }
-  m_t << "}]";
+  m_t << "} ";
 }
 
 void RTFDocVisitor::visitPost(DocParamList *)
 {
+  m_t << "\\par" << endl;
 }
 
 void RTFDocVisitor::visitPre(DocXRefItem *x)
 {
-  m_t << "\\begin{Desc}" << endl;
-  m_t << "\\item[";
-  if (Config_getBool("PDF_HYPERLINKS"))
+  m_t << "{"; // start param list
+  m_t << "{\\b "; // start bold
+  m_t << "\\par" << endl;
+  if (Config_getBool("RTF_HYPERLINKS"))
   {
-    m_t << "\\hyperlink{" << x->file() << "_" << x->anchor() << "}{";
+    QCString refName;
+    if (!x->file().isEmpty())
+    {
+      refName+=x->file();
+    }
+    if (!x->file().isEmpty() && !x->anchor().isEmpty())
+    {
+      refName+="_";
+    }
+    if (!x->anchor().isEmpty())
+    {
+      refName+=x->anchor();
+    }
+
+    m_t << "{\\field "
+             "{\\*\\fldinst "
+               "{ HYPERLINK  \\\\l \"" << refName << "\" "
+               "}{}"
+             "}"
+             "{\\fldrslt "
+               "{\\cs37\\ul\\cf2 ";
+    filter(x->title());
+    m_t <<     "}"
+             "}"
+           "}";
   }
   else
   {
-    m_t << "{\\bf ";
+    filter(x->title());
   }
-  filter(x->title());
-  m_t << "}]";
+  m_t << "}"; // end bold
+  m_t << "\\par" << endl;
+  incIndentLevel();
+  m_t << rtf_Style_Reset << getStyle("DescContinue");
 }
 
 void RTFDocVisitor::visitPost(DocXRefItem *)
 {
-  m_t << "\\end{Desc}" << endl;
+  m_t << "}" << endl; // end param list
 }
 
 void RTFDocVisitor::visitPre(DocInternalRef *ref)
diff --git a/src/rtfdocvisitor.h b/src/rtfdocvisitor.h
index 842cc84..0f7649a 100644
--- a/src/rtfdocvisitor.h
+++ b/src/rtfdocvisitor.h
@@ -48,6 +48,7 @@ class RTFDocVisitor : public DocVisitor
     void visit(DocInclude *);
     void visit(DocIncOperator *);
     void visit(DocFormula *);
+    void visit(DocIndexEntry *);
 
     //--------------------------------------
     // visitor functions for compound nodes
@@ -91,8 +92,6 @@ class RTFDocVisitor : public DocVisitor
     void visitPost(DocHtmlRow *) ;
     void visitPre(DocHtmlCell *);
     void visitPost(DocHtmlCell *);
-    void visitPre(DocIndexEntry *);
-    void visitPost(DocIndexEntry *);
     void visitPre(DocInternal *);
     void visitPost(DocInternal *);
     void visitPre(DocHRef *);
@@ -135,6 +134,8 @@ class RTFDocVisitor : public DocVisitor
                    const QCString &anchor);
     void endLink(const QCString &ref);
     QCString getStyle(const char *name);
+    void incIndentLevel();
+    void decIndentLevel();
 
     //--------------------------------------
     // state variables
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index 2aaa3ab..eaae2d7 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -34,13 +34,12 @@
 #include "version.h"
 #include "page.h"
 #include "rtfstyle.h"
+#include "rtfdocvisitor.h"
+#include "docparser.h"
 
 //#define DBG_RTF(x) x;
 #define DBG_RTF(x)
 
-// used for table column width calculation
-#define PAGEWIDTH 8748
-
 static QCString dateToRTFDateString()
 {
   const QDateTime &d = QDateTime::currentDateTime();
@@ -870,7 +869,7 @@ void RTFGenerator::startItemList()
   DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl)
   t << "{";
   incrementIndentLevel();
-  listItemInfo[m_listLevel].isEnum = FALSE;
+  rtf_listItemInfo[m_listLevel].isEnum = FALSE;
 }
 
 /*! end bullet list */
@@ -889,8 +888,8 @@ void RTFGenerator::startEnumList()  // starts an enumeration list
   DBG_RTF(t << "{\\comment (startEnumList)}" << endl)
   t << "{" << endl;
   incrementIndentLevel();
-  listItemInfo[m_listLevel].isEnum = TRUE;
-  listItemInfo[m_listLevel].number = 1;
+  rtf_listItemInfo[m_listLevel].isEnum = TRUE;
+  rtf_listItemInfo[m_listLevel].number = 1;
 }
 
 /*! end enumeration list */
@@ -909,11 +908,11 @@ void RTFGenerator::writeListItem()
   DBG_RTF(t << "{\\comment (writeListItem)}" << endl)
   newParagraph();
   t << rtf_Style_Reset;
-  if (listItemInfo[m_listLevel].isEnum)
+  if (rtf_listItemInfo[m_listLevel].isEnum)
   {
     t << rtf_EList_DepthStyle() << endl;
-    t << listItemInfo[m_listLevel].number << ".\\tab ";
-    listItemInfo[m_listLevel].number++;
+    t << rtf_listItemInfo[m_listLevel].number << ".\\tab ";
+    rtf_listItemInfo[m_listLevel].number++;
   }
   else
   {
@@ -1099,12 +1098,14 @@ void RTFGenerator::endSubsubsection()
 
 void RTFGenerator::startTable(bool,int colNumbers) 
 {
+  DBG_RTF(t << "{\\comment startTable}\n";)
   m_numCols=colNumbers;
   t << "\\par\n";
 }
 
 void RTFGenerator::endTable(bool hasCaption) 
 { 
+  DBG_RTF(t << "{\\comment endTable}\n";)
   if (!hasCaption) 
     t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n"; 
   t << "\\pard\n" << endl; 
@@ -1112,22 +1113,25 @@ void RTFGenerator::endTable(bool hasCaption)
 
 void  RTFGenerator::startCaption() 
 {
+  DBG_RTF(t << "{\\comment startCaption}\n";)
   endTableRow();
   t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 \\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 \\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 \\trbrdrv\\brdrs\\brdrw10" << endl;
-  t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 \\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb \\cellx"<<PAGEWIDTH<<"\\pard \\qc\\nowidctlpar\\widctlpar\\intbl\\adjustright " << endl;
+  t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 \\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb \\cellx"<<rtf_pageWidth<<"\\pard \\qc\\nowidctlpar\\widctlpar\\intbl\\adjustright " << endl;
   nextTableColumn();
 }
 
 void  RTFGenerator::endCaption() 
 {
+  DBG_RTF(t << "{\\comment endCaption}\n";)
   endTableColumn();
   endTableRow();
 }
 
 void RTFGenerator::nextTableRow() 
 {  
+  DBG_RTF(t << "{\\comment nextTableRow}\n";)
   ASSERT(m_numCols>0 && m_numCols<25);
-  uint columnWidth=PAGEWIDTH/m_numCols;
+  uint columnWidth=rtf_pageWidth/m_numCols;
   t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 "
        "\\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 "
        "\\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 "
@@ -1143,16 +1147,19 @@ void RTFGenerator::nextTableRow()
  
 void RTFGenerator::endTableRow() 
 { 
+  DBG_RTF(t << "{\\comment endTableRow}\n";)
   t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
 }
  
 void RTFGenerator::nextTableColumn() 
 {
+  DBG_RTF(t << "{\\comment nextTableColumn}\n";)
   t << "{ ";
 }
 
 void RTFGenerator::endTableColumn() 
 { 
+  DBG_RTF(t << "{\\comment endTableColumn}\n";)
   t << " \\cell }";
 }
 
@@ -1516,9 +1523,11 @@ void RTFGenerator::startSection(const char *,const char *title,SectionInfo::Sect
   int num=4;
   switch(type)
   {
-    case SectionInfo::Page:       num=2; break;
-    case SectionInfo::Section:    num=3; break;
-    case SectionInfo::Subsection: num=4; break;
+    case SectionInfo::Page:          num=2; break;
+    case SectionInfo::Section:       num=3; break;
+    case SectionInfo::Subsection:    num=4; break;
+    case SectionInfo::Subsubsection: num=4; break;
+    case SectionInfo::Paragraph:     num=4; break;
     default: ASSERT(0); break;
   }
   QCString heading;
@@ -1883,10 +1892,10 @@ void RTFGenerator::endDescTableData()
 void RTFGenerator::incrementIndentLevel()
 {
   m_listLevel++;
-  if (m_listLevel>indentLevels-1)
+  if (m_listLevel>rtf_maxIndentLevels-1)
   {
-    warn_cont("Warning: Maximum indent level (%d) exceeded while generating RTF output!\n",indentLevels);
-    m_listLevel=indentLevels-1;
+    warn_cont("Warning: Maximum indent level (%d) exceeded while generating RTF output!\n",rtf_maxIndentLevels);
+    m_listLevel=rtf_maxIndentLevels-1;
   }
 }
 
@@ -2398,3 +2407,10 @@ void RTFGenerator::endParamList()
   t << "}";
 }
 
+void RTFGenerator::printDoc(DocNode *n)
+{
+  RTFDocVisitor *visitor = new RTFDocVisitor(t,*this);
+  n->accept(visitor);
+  delete visitor; 
+}
+
diff --git a/src/rtfgen.h b/src/rtfgen.h
index 221135e..a3aec7a 100644
--- a/src/rtfgen.h
+++ b/src/rtfgen.h
@@ -42,6 +42,8 @@ class RTFGenerator : public OutputGenerator
     bool isEnabled(OutputType o) { return (o==RTF && active); } 
     OutputGenerator *get(OutputType o) { return (o==RTF) ? this : 0; }
 
+    void printDoc(DocNode *);
+
     void startFile(const char *name,const char *manName,
                    const char *title, bool external);
     void writeFooter(int,bool) {}
diff --git a/src/rtfstyle.cpp b/src/rtfstyle.cpp
index 017bdaf..074872e 100644
--- a/src/rtfstyle.cpp
+++ b/src/rtfstyle.cpp
@@ -25,7 +25,7 @@
 #include "message.h"
 
 
-RTFListItemInfo listItemInfo[indentLevels];
+RTFListItemInfo rtf_listItemInfo[rtf_maxIndentLevels];
 
 QCString rtf_title;
 QCString rtf_subject;
diff --git a/src/rtfstyle.h b/src/rtfstyle.h
index 1fe353c..260f922 100644
--- a/src/rtfstyle.h
+++ b/src/rtfstyle.h
@@ -23,6 +23,9 @@
 #include <qregexp.h>
 #include <qdict.h>
 
+// used for table column width calculation
+const int rtf_pageWidth = 8748;
+
 extern QCString rtf_title;
 extern QCString rtf_subject;
 extern QCString rtf_comments;
@@ -40,9 +43,9 @@ struct RTFListItemInfo
   int number;
 };
 
-const int indentLevels = 10;
+const int rtf_maxIndentLevels = 10;
 
-extern RTFListItemInfo listItemInfo[indentLevels];
+extern RTFListItemInfo rtf_listItemInfo[rtf_maxIndentLevels];
 
 struct Rtf_Style_Default
 {
diff --git a/src/scanner.l b/src/scanner.l
index c2710e4..d4754fa 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -282,10 +282,10 @@ static void addSection()
 {
   //printf("New section pageName=%s label=%s title=%s\n",
   //    current->name.data(),sectionLabel.data(),sectionTitle.data());
-  if (current->name.isEmpty() || current->section != Entry::PAGEDOC_SEC)
+  if (current->name.isEmpty() /*|| current->section != Entry::PAGEDOC_SEC */)
   {
-    warn(yyFileName,yyLineNr,"Warning: found section or anchor with label `%s' "
-	                     "outside of \\page context!\n",sectionLabel.data());
+    //warn(yyFileName,yyLineNr,"Warning: found section or anchor with label `%s' "
+    //                     "outside of \\page context!\n",sectionLabel.data());
     return;
   }
   if (sectionLabel.isEmpty()) return;
@@ -453,6 +453,7 @@ static void addSpecialItem(const char *listName)
     ASSERT(item!=0);
     item->text += " <p>";
     item->text += current->brief;
+    //printf("%s: text +=%s\n",listName,item->text.data());
   }
   else // new item
   {
@@ -473,6 +474,7 @@ static void addSpecialItem(const char *listName)
     sectionLabel=anchorLabel;
     addSection();
     current->name = tmpName;
+    //printf("%s: text %s doc %s\n",listName,item->text.data(),cmdString.data());
   }
   current->brief  = slString.copy(); // restore orginial brief desc.
 }
@@ -3223,6 +3225,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
   					  current->section = Entry::MAINPAGEDOC_SEC;
 					  current->fileName = yyFileName;
 					  current->startLine = yyLineNr;
+					  current->name = "mainpage";
 					  BEGIN( PageDocArg2 );
   					}
 <Doc,JavaDoc>{B}*{CMD}"file"{B}*	{
@@ -3517,6 +3520,14 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
   					  sectionType=SectionInfo::Subsection;
   					  BEGIN(SectionLabel);
   					}
+<PageDoc>{CMD}"subsubsection"{B}+	{
+  					  sectionType=SectionInfo::Subsubsection;
+  					  BEGIN(SectionLabel);
+  					}
+<PageDoc>{CMD}"paragraph"{B}+		{
+  					  sectionType=SectionInfo::Paragraph;
+  					  BEGIN(SectionLabel);
+  					}
 <GroupHeader>.				{ memberGroupHeader+=*yytext; }
 <GroupHeader>"*/"			{
   					  unput('/');unput('*');
@@ -3970,7 +3981,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 <DocBaseClass>\n			{ yyLineNr++; BEGIN( ClassDoc ); }
 <ClassDocBrief>{BS}({BL}|"\\n\\n")	{ 
   					  current->brief=current->brief.stripWhiteSpace();
-					  if (!current->doc.isEmpty()) current->doc+=" <p>";
+					  //if (!current->doc.isEmpty()) current->doc+=" <p>";
 					  if (lastBriefContext==TodoParam || 
 					      lastBriefContext==TestParam || 
 					      lastBriefContext==BugParam ||
diff --git a/src/section.h b/src/section.h
index 7868036..b1138b0 100644
--- a/src/section.h
+++ b/src/section.h
@@ -29,7 +29,7 @@ class PageInfo;
 
 struct SectionInfo
 {
-  enum SectionType { Page, Section, Subsection, Anchor };
+  enum SectionType { Page, Section, Subsection, Subsubsection, Paragraph, Anchor };
   SectionInfo(const char *l,const char *t,SectionType st,const char *r=0)
     { label=l; title=t; type=st; ref=r; definition=0; pageRef=0; generated=FALSE; }
  ~SectionInfo() {}
diff --git a/src/util.cpp b/src/util.cpp
index 4efc7b9..65d2069 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -3519,7 +3519,7 @@ void addRefItem(const QList<ListItemInfo> *sli,
         doc += "</dt>\n<dd>";
         doc += item->text;
         doc += "</dd></dl>\n";
-        addRelatedPage(refList->listName(),refList->pageTitle(),doc,0,"generated",1,0,0,0);
+        addRelatedPage(refList->listName(),refList->pageTitle(),doc,0,refList->listName(),1,0,0,0);
         item->written=TRUE;
       }
     }
@@ -3937,7 +3937,7 @@ QCString rtfFormatBmkStr(const char *name)
      {
          if ( ( ++(*nxtTag) ) > 'Z' )
          {
-            (*nxtTag) = 'A';
+            *nxtTag = 'A';
          }
          else
          {
diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp
new file mode 100644
index 0000000..d65d2fa
--- /dev/null
+++ b/src/xmldocvisitor.cpp
@@ -0,0 +1,737 @@
+/******************************************************************************
+ *
+ * 
+ *
+ *
+ * Copyright (C) 1997-2002 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby 
+ * granted. No representations are made about the suitability of this software 
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "xmldocvisitor.h"
+#include "docparser.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputgen.h"
+#include "xmlgen.h"
+#include "code.h"
+#include "dot.h"
+#include "message.h"
+
+XmlDocVisitor::XmlDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) 
+  : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) 
+{
+}
+
+  //--------------------------------------
+  // visitor functions for leaf nodes
+  //--------------------------------------
+
+void XmlDocVisitor::visit(DocWord *w)
+{
+  if (m_hide) return;
+  filter(w->word());
+}
+
+void XmlDocVisitor::visit(DocLinkedWord *w)
+{
+  if (m_hide) return;
+  startLink(w->ref(),w->file(),w->anchor());
+  filter(w->word());
+  endLink();
+}
+
+void XmlDocVisitor::visit(DocWhiteSpace *w)
+{
+  if (m_hide) return;
+  if (m_insidePre)
+  {
+    m_t << w->chars();
+  }
+  else
+  {
+    m_t << " ";
+  }
+}
+
+void XmlDocVisitor::visit(DocSymbol *s)
+{
+  if (m_hide) return;
+  switch(s->symbol())
+  {
+    case DocSymbol::BSlash:  m_t << "\\"; break;
+    case DocSymbol::At:      m_t << "@"; break;
+    case DocSymbol::Less:    m_t << "&lt;"; break;
+    case DocSymbol::Greater: m_t << "&gt;"; break;
+    case DocSymbol::Amp:     m_t << "&amp;"; break;
+    case DocSymbol::Dollar:  m_t << "$"; break;
+    case DocSymbol::Hash:    m_t << "#"; break;
+    case DocSymbol::Percent: m_t << "%"; break;
+    case DocSymbol::Copy:    m_t << "<copy/>"; break;
+    case DocSymbol::Apos:    m_t << "'"; break;
+    case DocSymbol::Quot:    m_t << "\""; break;
+    case DocSymbol::Uml:     m_t << "<umlaut char=\"" << s->letter() << "\"/>"; break;
+    case DocSymbol::Acute:   m_t << "<acute char=\"" << s->letter() << "\"/>"; break;
+    case DocSymbol::Grave:   m_t << "<grave char=\"" << s->letter() << "\"/>"; break;
+    case DocSymbol::Circ:    m_t << "<circ char=\"" << s->letter() << "\"/>"; break;
+    case DocSymbol::Tilde:   m_t << "<tilde char=\"" << s->letter() << "\"/>"; break;
+    case DocSymbol::Szlig:   m_t << "<szlig/>"; break;
+    case DocSymbol::Cedil:   m_t << "<cedil char=\"" << s->letter() << "\"/>"; break;
+    case DocSymbol::Ring:    m_t << "<ring char=\"" << s->letter() << "\"/>"; break;
+    case DocSymbol::Nbsp:    m_t << "<nonbreakablespace/>"; break;
+    default:
+                             err("Error: unknown symbol found\n");
+  }
+}
+
+void XmlDocVisitor::visit(DocURL *u)
+{
+  if (m_hide) return;
+  m_t << "<ulink url=\"" << u->url() << "\">";
+  filter(u->url());
+  m_t << "</ulink>";
+}
+
+void XmlDocVisitor::visit(DocLineBreak *)
+{
+  if (m_hide) return;
+  m_t << "<linebreak/>\n";
+}
+
+void XmlDocVisitor::visit(DocHorRuler *)
+{
+  if (m_hide) return;
+  m_t << "<hruler/>\n";
+}
+
+void XmlDocVisitor::visit(DocStyleChange *s)
+{
+  if (m_hide) return;
+  switch (s->style())
+  {
+    case DocStyleChange::Bold:
+      if (s->enable()) m_t << "<bold>";      else m_t << "</bold> ";
+      break;
+    case DocStyleChange::Italic:
+      if (s->enable()) m_t << "<emphasis>";     else m_t << "</emphasis> ";
+      break;
+    case DocStyleChange::Code:
+      if (s->enable()) m_t << "<computeroutput>";   else m_t << "</computeroutput> ";
+      break;
+    case DocStyleChange::Subscript:
+      if (s->enable()) m_t << "<subscript>";    else m_t << "</subscript> ";
+      break;
+    case DocStyleChange::Superscript:
+      if (s->enable()) m_t << "<superscript>";    else m_t << "</superscript> ";
+      break;
+    case DocStyleChange::Center:
+      if (s->enable()) m_t << "<center>"; else m_t << "</center> ";
+      break;
+    case DocStyleChange::Small:
+      if (s->enable()) m_t << "<small>";  else m_t << "</small> ";
+      break;
+  }
+}
+
+void XmlDocVisitor::visit(DocVerbatim *s)
+{
+  if (m_hide) return;
+  switch(s->type())
+  {
+    case DocVerbatim::Code: // fall though
+      m_t << "<programlisting>"; 
+      parseCode(m_ci,s->context(),s->text(),FALSE,0);
+      m_t << "</programlisting>"; 
+      break;
+    case DocVerbatim::Verbatim: 
+      m_t << "<preformatted>";
+      filter(s->text());
+      m_t << "</preformatted>"; 
+      break;
+    case DocVerbatim::HtmlOnly: 
+      m_t << "<htmlonly>";
+      filter(s->text());
+      m_t << "</htmlonly>";
+      break;
+    case DocVerbatim::LatexOnly: 
+      m_t << "<latexonly>";
+      filter(s->text());
+      m_t << "</latexonly>";
+      break;
+  }
+}
+
+void XmlDocVisitor::visit(DocAnchor *anc)
+{
+  if (m_hide) return;
+  m_t << "<anchor id=\"" << anc->file() << "_1" << anc->anchor() << "\"/>";
+}
+
+void XmlDocVisitor::visit(DocInclude *inc)
+{
+  if (m_hide) return;
+  switch(inc->type())
+  {
+    case DocInclude::Include: 
+      m_t << "<programlisting>";
+      parseCode(m_ci,inc->context(),inc->text(),FALSE,0);
+      m_t << "</programlisting>"; 
+      break;
+    case DocInclude::DontInclude: 
+      break;
+    case DocInclude::HtmlInclude: 
+      m_t << "<htmlonly>";
+      filter(inc->text());
+      m_t << "</htmlonly>";
+      break;
+    case DocInclude::VerbInclude: 
+      m_t << "<preformatted>";
+      filter(inc->text());
+      m_t << "</preformatted>"; 
+      break;
+  }
+}
+
+void XmlDocVisitor::visit(DocIncOperator *op)
+{
+  //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
+  //    op->type(),op->isFirst(),op->isLast(),op->text().data());
+  if (op->isFirst()) 
+  {
+    m_t << "<programlisting>";
+    m_hide = TRUE;
+  }
+  if (op->type()!=DocIncOperator::Skip) 
+  {
+    parseCode(m_ci,op->context(),op->text(),FALSE,0);
+  }
+  if (op->isLast())  
+  {
+    m_hide = FALSE;
+    m_t << "</programlisting>"; 
+  }
+  else
+  {
+    m_t << endl;
+  }
+}
+
+void XmlDocVisitor::visit(DocFormula *f)
+{
+  if (m_hide) return;
+  m_t << "<formula id=\"" << f->id() << "\">";
+  filter(f->text());
+  m_t << "</formula>";
+}
+
+void XmlDocVisitor::visit(DocIndexEntry *ie)
+{
+  m_t << "<indexentry>"
+           "<primaryie>";
+  filter(ie->entry());
+  m_t << "</primaryie>"
+           "<secondaryie></secondaryie>"
+         "</indexentry>";
+}
+
+//--------------------------------------
+// visitor functions for compound nodes
+//--------------------------------------
+
+void XmlDocVisitor::visitPre(DocAutoList *l)
+{
+  if (l->isEnumList())
+  {
+    m_t << "<orderedlist>\n";
+  }
+  else
+  {
+    m_t << "<itemizedlist>\n";
+  }
+}
+
+void XmlDocVisitor::visitPost(DocAutoList *l)
+{
+  if (l->isEnumList())
+  {
+    m_t << "</orderedlist>\n";
+  }
+  else
+  {
+    m_t << "</itemizedlist>\n";
+  }
+}
+
+void XmlDocVisitor::visitPre(DocAutoListItem *)
+{
+  m_t << "<listitem>";
+}
+
+void XmlDocVisitor::visitPost(DocAutoListItem *) 
+{
+  m_t << "</listitem>";
+}
+
+void XmlDocVisitor::visitPre(DocPara *) 
+{
+  m_t << "<para>";
+}
+
+void XmlDocVisitor::visitPost(DocPara *)
+{
+  m_t << "</para>";
+}
+
+void XmlDocVisitor::visitPre(DocRoot *)
+{
+  //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n";
+}
+
+void XmlDocVisitor::visitPost(DocRoot *)
+{
+  //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n";
+}
+
+void XmlDocVisitor::visitPre(DocSimpleSect *s)
+{
+  m_t << "<simplesect kind=\">";
+  switch(s->type())
+  {
+    case DocSimpleSect::See: 
+      m_t << "see"; break;
+    case DocSimpleSect::Return: 
+      m_t << "return"; break;
+    case DocSimpleSect::Author: 
+      m_t << "author"; break;
+    case DocSimpleSect::Authors: 
+      m_t << "authors"; break;
+    case DocSimpleSect::Version: 
+      m_t << "version"; break;
+    case DocSimpleSect::Since: 
+      m_t << "since"; break;
+    case DocSimpleSect::Date: 
+      m_t << "date"; break;
+    case DocSimpleSect::Note: 
+      m_t << "bug"; break;
+    case DocSimpleSect::Warning:
+      m_t << "warning"; break;
+    case DocSimpleSect::Pre:
+      m_t << "pre"; break;
+    case DocSimpleSect::Post:
+      m_t << "post"; break;
+    case DocSimpleSect::Invar:
+      m_t << "invariant"; break;
+    case DocSimpleSect::Remark:
+      m_t << "remark"; break;
+    case DocSimpleSect::Attention:
+      m_t << "attention"; break;
+    case DocSimpleSect::User: 
+      m_t << "par"; break;
+    case DocSimpleSect::Unknown:  break;
+  }
+  m_t << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocSimpleSect *)
+{
+  m_t << "</simplesect>\n";
+}
+
+void XmlDocVisitor::visitPre(DocTitle *)
+{
+  m_t << "<title>";
+}
+
+void XmlDocVisitor::visitPost(DocTitle *)
+{
+  m_t << "</title>";
+}
+
+void XmlDocVisitor::visitPre(DocSimpleList *)
+{
+  m_t << "<itemizedlist>\n";
+}
+
+void XmlDocVisitor::visitPost(DocSimpleList *)
+{
+  m_t << "</itemizedlist>\n";
+}
+
+void XmlDocVisitor::visitPre(DocSimpleListItem *)
+{
+  m_t << "<listitem>";
+}
+
+void XmlDocVisitor::visitPost(DocSimpleListItem *) 
+{
+  m_t << "</listitem>\n";
+}
+
+void XmlDocVisitor::visitPre(DocSection *s)
+{
+  m_t << "<sect" << s->level()+1 << ">";
+  filter(s->title());
+  m_t << "</sect" << s->level()+1 << ">\n";
+}
+
+void XmlDocVisitor::visitPost(DocSection *) 
+{
+}
+
+void XmlDocVisitor::visitPre(DocHtmlList *s)
+{
+  if (s->type()==DocHtmlList::Ordered) 
+    m_t << "<orderedlist>\n"; 
+  else 
+    m_t << "<itemizedlist>\n";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlList *s) 
+{
+  if (s->type()==DocHtmlList::Ordered) 
+    m_t << "</orderedlist>\n"; 
+  else 
+    m_t << "</itemizedlist>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlListItem *)
+{
+  m_t << "<listitem>\n";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlListItem *) 
+{
+  m_t << "</listitem>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlPre *)
+{
+  m_t << "<preformatted>\n";
+  m_insidePre=TRUE;
+}
+
+void XmlDocVisitor::visitPost(DocHtmlPre *) 
+{
+  m_insidePre=FALSE;
+  m_t << "</preformatted>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlDescList *)
+{
+  m_t << "<variablelist>\n";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlDescList *) 
+{
+  m_t << "</variablelist>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlDescTitle *)
+{
+  m_t << "<varlistentry><term>";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlDescTitle *) 
+{
+  m_t << "</term></varlistentry>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlDescData *)
+{
+  m_t << "<listitem>";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlDescData *) 
+{
+  m_t << "</listitem>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlTable *t)
+{
+  m_t << "<table rows=\"" << t->numRows() 
+      << "\" cols=\"" << t->numCols() << "\">" ;
+}
+
+void XmlDocVisitor::visitPost(DocHtmlTable *) 
+{
+  m_t << "</table>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlRow *)
+{
+  m_t << "<row>\n";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlRow *) 
+{
+  m_t << "</row>\n";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlCell *c)
+{
+  if (c->isHeading()) m_t << "<entry thead=\"yes\">"; else m_t << "<entry thead=\"no\">";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlCell *) 
+{
+  m_t << "</entry>"; 
+}
+
+void XmlDocVisitor::visitPre(DocHtmlCaption *)
+{
+  m_t << "<caption>";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlCaption *) 
+{
+  m_t << "</caption>\n";
+}
+
+void XmlDocVisitor::visitPre(DocInternal *)
+{
+  m_t << "<internal>";
+}
+
+void XmlDocVisitor::visitPost(DocInternal *) 
+{
+  m_t << "</internal>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocHRef *href)
+{
+  m_t << "<ulink url=\"" << href->url() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocHRef *) 
+{
+  m_t << "</ulink>";
+}
+
+void XmlDocVisitor::visitPre(DocHtmlHeader *header)
+{
+  m_t << "<sect" << header->level() << ">";
+}
+
+void XmlDocVisitor::visitPost(DocHtmlHeader *header) 
+{
+  m_t << "</sect" << header->level() << ">\n";
+}
+
+void XmlDocVisitor::visitPre(DocImage *img)
+{
+  m_t << "<image type=\"";
+  switch(img->type())
+  {
+    case DocImage::Html:  m_t << "html"; break;
+    case DocImage::Latex: m_t << "latex"; break;
+    case DocImage::Rtf:   m_t << "rtf"; break;
+  }
+  m_t << "\"";
+
+  QCString baseName=img->name();
+  int i;
+  if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
+  {
+    baseName=baseName.right(baseName.length()-i-1);
+  }
+  m_t << " name=\"" << baseName << "\"";
+  if (!img->width().isEmpty())
+  {
+    m_t << " width=\"";
+    filter(img->width());
+    m_t << "\"";
+  }
+  else if (!img->height().isEmpty())
+  {
+    m_t << " height=\"";
+    filter(img->height());
+    m_t << "\"";
+  }
+  m_t << ">";
+}
+
+void XmlDocVisitor::visitPost(DocImage *) 
+{
+  m_t << "</image>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocDotFile *df)
+{
+  m_t << "<dotfile name=\"" << df->file() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocDotFile *) 
+{
+  m_t << "</dotfile>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocLink *lnk)
+{
+  startLink(lnk->ref(),lnk->file(),lnk->anchor());
+}
+
+void XmlDocVisitor::visitPost(DocLink *) 
+{
+  endLink();
+}
+
+void XmlDocVisitor::visitPre(DocRef *ref)
+{
+  startLink(ref->ref(),ref->file(),ref->anchor());
+  if (!ref->hasLinkText()) filter(ref->targetTitle());
+}
+
+void XmlDocVisitor::visitPost(DocRef *) 
+{
+  endLink();
+  m_t << " ";
+}
+
+void XmlDocVisitor::visitPre(DocSecRefItem *ref)
+{
+  m_t << "<tocitem id=\"" << ref->file() << "_1" << ref->anchor() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocSecRefItem *) 
+{
+  m_t << "</tocitem>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocSecRefList *)
+{
+  m_t << "<toclist>" << endl;
+}
+
+void XmlDocVisitor::visitPost(DocSecRefList *) 
+{
+  m_t << "</toclist>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocLanguage *l)
+{
+  m_t << "<language id=\"" << l->id() << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocLanguage *) 
+{
+  m_t << "</language>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocParamSect *s)
+{
+  m_t << "<parameterlist kind=\"";
+  switch(s->type())
+  {
+    case DocParamSect::Param: 
+      m_t << "param"; break;
+    case DocParamSect::RetVal: 
+      m_t << "retval"; break;
+    case DocParamSect::Exception: 
+      m_t << "exception"; break;
+    default:
+      ASSERT(0);
+  }
+  m_t << "\">";
+}
+
+void XmlDocVisitor::visitPost(DocParamSect *)
+{
+  m_t << "</parameterlist>" << endl;
+}
+
+void XmlDocVisitor::visitPre(DocParamList *pl)
+{
+  QStrListIterator li(pl->parameters());
+  const char *s;
+  for (li.toFirst();(s=li.current());++li)
+  {
+    m_t << "<parametername>";
+    filter(s);
+    m_t << "</parametername>" << endl;
+  }
+  m_t << "<parameterdescription>" << endl;
+}
+
+void XmlDocVisitor::visitPost(DocParamList *)
+{
+  m_t << "</parameterdescription>";
+}
+
+void XmlDocVisitor::visitPre(DocXRefItem *x)
+{
+  m_t << "<xrefsect id=\"";
+  m_t << x->file() << "_1" << x->anchor();
+  m_t << "\">";
+  m_t << "<xreftitle>";
+  filter(x->title());
+  m_t << "</xreftitle>";
+  m_t << "<xrefdescription>";
+}
+
+void XmlDocVisitor::visitPost(DocXRefItem *)
+{
+  m_t << "</xrefdescription>";
+  m_t << "</xrefsect>";
+}
+
+void XmlDocVisitor::visitPre(DocInternalRef *ref)
+{
+  startLink(0,ref->file(),ref->anchor());
+}
+
+void XmlDocVisitor::visitPost(DocInternalRef *) 
+{
+  endLink();
+  m_t << " ";
+}
+
+void XmlDocVisitor::visitPre(DocCopy *)
+{
+}
+
+void XmlDocVisitor::visitPost(DocCopy *)
+{
+}
+
+void XmlDocVisitor::filter(const char *str)
+{ 
+  if (str==0) return;
+  const char *p=str;
+  char c;
+  while (*p)
+  {
+    c=*p++;
+    switch(c)
+    {
+      case '<':  m_t << "&lt;"; break;
+      case '>':  m_t << "&gt;"; break;
+      case '&':  m_t << "&amp;"; break;
+      default:   m_t << c;
+    }
+  }
+}
+
+void XmlDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor)
+{
+  m_t << "<ref refid=\"" << file;
+  if (!anchor.isEmpty()) m_t << "_1" << anchor;
+  m_t << "\" kindref=\"";
+  if (!anchor.isEmpty()) m_t << "member"; else m_t << "compound";
+  m_t << "\"";
+  if (!ref.isEmpty()) m_t << " external=\"" << ref << "\"";
+  m_t << ">";
+}
+
+void XmlDocVisitor::endLink()
+{
+  m_t << "</ref>";
+}
+
diff --git a/src/xmldocvisitor.h b/src/xmldocvisitor.h
new file mode 100644
index 0000000..381c2b6
--- /dev/null
+++ b/src/xmldocvisitor.h
@@ -0,0 +1,147 @@
+/******************************************************************************
+ *
+ * 
+ *
+ *
+ * Copyright (C) 1997-2002 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby 
+ * granted. No representations are made about the suitability of this software 
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _XMLDOCVISITOR_H
+#define _XMLDOCVISITOR_H
+
+#include "docvisitor.h"
+
+class QTextStream;
+class BaseCodeDocInterface;
+class QCString;
+
+/*! @brief Concrete visitor implementation for HTML output. */
+class XmlDocVisitor : public DocVisitor
+{
+  public:
+    XmlDocVisitor(QTextStream &t,BaseCodeDocInterface &ci);
+    
+    //--------------------------------------
+    // visitor functions for leaf nodes
+    //--------------------------------------
+    
+    void visit(DocWord *);
+    void visit(DocLinkedWord *);
+    void visit(DocWhiteSpace *);
+    void visit(DocSymbol *);
+    void visit(DocURL *);
+    void visit(DocLineBreak *);
+    void visit(DocHorRuler *);
+    void visit(DocStyleChange *);
+    void visit(DocVerbatim *);
+    void visit(DocAnchor *);
+    void visit(DocInclude *);
+    void visit(DocIncOperator *);
+    void visit(DocFormula *);
+    void visit(DocIndexEntry *);
+
+    //--------------------------------------
+    // visitor functions for compound nodes
+    //--------------------------------------
+    
+    void visitPre(DocAutoList *);
+    void visitPost(DocAutoList *);
+    void visitPre(DocAutoListItem *);
+    void visitPost(DocAutoListItem *);
+    void visitPre(DocPara *) ;
+    void visitPost(DocPara *);
+    void visitPre(DocRoot *);
+    void visitPost(DocRoot *);
+    void visitPre(DocSimpleSect *);
+    void visitPost(DocSimpleSect *);
+    void visitPre(DocTitle *);
+    void visitPost(DocTitle *);
+    void visitPre(DocSimpleList *);
+    void visitPost(DocSimpleList *);
+    void visitPre(DocSimpleListItem *);
+    void visitPost(DocSimpleListItem *);
+    void visitPre(DocSection *);
+    void visitPost(DocSection *);
+    void visitPre(DocHtmlList *);
+    void visitPost(DocHtmlList *) ;
+    void visitPre(DocHtmlListItem *);
+    void visitPost(DocHtmlListItem *);
+    void visitPre(DocHtmlPre *);
+    void visitPost(DocHtmlPre *);
+    void visitPre(DocHtmlDescList *);
+    void visitPost(DocHtmlDescList *);
+    void visitPre(DocHtmlDescTitle *);
+    void visitPost(DocHtmlDescTitle *);
+    void visitPre(DocHtmlDescData *);
+    void visitPost(DocHtmlDescData *);
+    void visitPre(DocHtmlTable *);
+    void visitPost(DocHtmlTable *);
+    void visitPre(DocHtmlRow *);
+    void visitPost(DocHtmlRow *) ;
+    void visitPre(DocHtmlCell *);
+    void visitPost(DocHtmlCell *);
+    void visitPre(DocHtmlCaption *);
+    void visitPost(DocHtmlCaption *);
+    void visitPre(DocInternal *);
+    void visitPost(DocInternal *);
+    void visitPre(DocHRef *);
+    void visitPost(DocHRef *);
+    void visitPre(DocHtmlHeader *);
+    void visitPost(DocHtmlHeader *);
+    void visitPre(DocImage *);
+    void visitPost(DocImage *);
+    void visitPre(DocDotFile *);
+    void visitPost(DocDotFile *);
+    void visitPre(DocLink *);
+    void visitPost(DocLink *);
+    void visitPre(DocRef *);
+    void visitPost(DocRef *);
+    void visitPre(DocSecRefItem *);
+    void visitPost(DocSecRefItem *);
+    void visitPre(DocSecRefList *);
+    void visitPost(DocSecRefList *);
+    void visitPre(DocLanguage *);
+    void visitPost(DocLanguage *);
+    void visitPre(DocParamSect *);
+    void visitPost(DocParamSect *);
+    void visitPre(DocParamList *);
+    void visitPost(DocParamList *);
+    void visitPre(DocXRefItem *);
+    void visitPost(DocXRefItem *);
+    void visitPre(DocInternalRef *);
+    void visitPost(DocInternalRef *);
+    void visitPre(DocCopy *);
+    void visitPost(DocCopy *);
+
+  private:
+
+    //--------------------------------------
+    // helper functions 
+    //--------------------------------------
+    
+    void filter(const char *str);
+    void startLink(const QCString &ref,const QCString &file,
+                   const QCString &anchor);
+    void endLink();
+
+    //--------------------------------------
+    // state variables
+    //--------------------------------------
+
+    QTextStream &m_t;
+    BaseCodeDocInterface &m_ci;
+    bool m_insidePre;
+    bool m_hide;
+};
+
+#endif
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 5bb7226..f29af33 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -33,6 +33,8 @@
 #include "page.h"
 #include "filename.h"
 #include "version.h"
+#include "xmldocvisitor.h"
+#include "docparser.h"
 
 #include <qdir.h>
 #include <qfile.h>
@@ -47,34 +49,34 @@
 // debug inside output
 //#define XML_DB(x) QCString __t;__t.sprintf x;m_t << __t
 
-QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t)
-{
-  switch (t)
-  {
-    case BaseOutputDocInterface::See:         return "see";
-    case BaseOutputDocInterface::Return:      return "return";
-    case BaseOutputDocInterface::Author:      return "author";
-    case BaseOutputDocInterface::Version:     return "version";
-    case BaseOutputDocInterface::Since:       return "since";
-    case BaseOutputDocInterface::Date:        return "date";
-    case BaseOutputDocInterface::Bug:         return "bug";
-    case BaseOutputDocInterface::Note:        return "note";
-    case BaseOutputDocInterface::Warning:     return "warning";
-    case BaseOutputDocInterface::Par:         return "par";
-    case BaseOutputDocInterface::Deprecated:  return "deprecated";
-    case BaseOutputDocInterface::Pre:         return "pre";
-    case BaseOutputDocInterface::Post:        return "post";
-    case BaseOutputDocInterface::Invar:       return "invariant";
-    case BaseOutputDocInterface::Remark:      return "remark";
-    case BaseOutputDocInterface::Attention:   return "attention";
-    case BaseOutputDocInterface::Todo:        return "todo";
-    case BaseOutputDocInterface::Test:        return "test";
-    case BaseOutputDocInterface::RCS:         return "rcs";
-    case BaseOutputDocInterface::EnumValues:  return "enumvalues";
-    case BaseOutputDocInterface::Examples:    return "examples";
-  }
-  return "illegal";
-}
+// static QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t)
+// {
+//   switch (t)
+//   {
+//     case BaseOutputDocInterface::See:         return "see";
+//     case BaseOutputDocInterface::Return:      return "return";
+//     case BaseOutputDocInterface::Author:      return "author";
+//     case BaseOutputDocInterface::Version:     return "version";
+//     case BaseOutputDocInterface::Since:       return "since";
+//     case BaseOutputDocInterface::Date:        return "date";
+//     case BaseOutputDocInterface::Bug:         return "bug";
+//     case BaseOutputDocInterface::Note:        return "note";
+//     case BaseOutputDocInterface::Warning:     return "warning";
+//     case BaseOutputDocInterface::Par:         return "par";
+//     case BaseOutputDocInterface::Deprecated:  return "deprecated";
+//     case BaseOutputDocInterface::Pre:         return "pre";
+//     case BaseOutputDocInterface::Post:        return "post";
+//     case BaseOutputDocInterface::Invar:       return "invariant";
+//     case BaseOutputDocInterface::Remark:      return "remark";
+//     case BaseOutputDocInterface::Attention:   return "attention";
+//     case BaseOutputDocInterface::Todo:        return "todo";
+//     case BaseOutputDocInterface::Test:        return "test";
+//     case BaseOutputDocInterface::RCS:         return "rcs";
+//     case BaseOutputDocInterface::EnumValues:  return "enumvalues";
+//     case BaseOutputDocInterface::Examples:    return "examples";
+//   }
+//   return "illegal";
+// }
 
 
 inline void writeXMLString(QTextStream &t,const char *s)
@@ -82,6 +84,26 @@ inline void writeXMLString(QTextStream &t,const char *s)
   t << convertToXML(s);
 }
 
+static void writeXMLHeader(QTextStream &t)
+{
+  QCString dtdName = Config_getString("XML_DTD");
+  QCString schemaName = Config_getString("XML_SCHEMA");
+  t << "<?xml version='1.0' encoding='ISO-8859-1' standalone='";
+  if (dtdName.isEmpty() && schemaName.isEmpty()) t << "yes"; else t << "no";
+  t << "'?>" << endl;
+  if (!dtdName.isEmpty())
+  {
+    t << "<!DOCTYPE doxygen SYSTEM \"doxygen.dtd\">" << endl;
+  }
+  t << "<doxygen ";
+  if (!schemaName.isEmpty())
+  {
+    t << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
+    t << "xsi:noNamespaceSchemaLocation=\"doxygen.xsd\" ";
+  }
+  t << "version=\"" << versionString << "\">" << endl;
+}
+
 void writeXMLLink(QTextStream &t,const char *extRef,const char *compoundId,
                   const char *anchorId,const char *text)
 {
@@ -168,683 +190,86 @@ template<class T> class ValStack
     int m_size;
 };
 
-/*! This class is used by the documentation parser.
- *  Its methods are called when some XML text or markup
- *  needs to be written.
- */
-class XMLGenerator : public OutputDocInterface
+
+class XMLCodeGenerator : public BaseCodeDocInterface
 {
   public:
 
-    // helper functions
+    XMLCodeGenerator(QTextStream &t) : m_t(t), m_lineNumber(-1),
+      m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE), 
+      m_insideSpecialHL(FALSE) {}
+    virtual ~XMLCodeGenerator() {}
     
-    void startParMode()
-    {
-      if (!m_inParStack.isEmpty() && !m_inParStack.top())
-      {
-        m_inParStack.top() = TRUE;
-        m_t << "<para>";
-        XML_DB(("start par at level=%d\n",m_inParStack.count()));
-      }
-      else if (m_inParStack.isEmpty())
-      {
-        m_inParStack.push(TRUE);
-        m_t << "<para>";
-        XML_DB(("start par at level=%d\n",m_inParStack.count()));
-      }
-    }
-    void endParMode()
-    {
-      if (!m_inParStack.isEmpty() && m_inParStack.top())
-      {
-        m_inParStack.top() = FALSE;
-        m_t << "</para>" << endl;
-        XML_DB(("end par at level=%d\n",m_inParStack.count()));
-      }
-    }
-    void startNestedPar()
-    {
-      m_inParStack.push(FALSE);
-      XML_DB(("enter par level=%d\n",m_inParStack.count()));
-    }
-    void endNestedPar()
-    {
-      XML_DB(("leave par level=%d\n",m_inParStack.count()));
-      if (m_inParStack.pop())
-      {
-        m_t << "</para>" << endl;
-      }
-      else
-      {
-        //XML_DB(("ILLEGAL par level!\n"));
-      }
-    }
-  
-    // Standard generator functions to be implemented by all generators
-
-    void docify(const char *s) 
-    {
-      if (m_outputEnabled)
-      {
-        XML_DB(("(docify \"%s\")\n",s));
-        startParMode();
-        writeXMLString(m_t,s);
-      }
-    }
-    void writeChar(char c) 
-    {
-      char s[2];s[0]=c;s[1]=0;
-      docify(s);
-    }
-    void writeString(const char *text) 
-    {
-      //m_t << text;
-      docify(text);
-    }
-    void startItemList()       
-    { 
-      XML_DB(("(startItemList)\n"));
-      startParMode();
-      m_t << "<itemizedlist>" << endl;; 
-      m_inListStack.push(TRUE);
-    }
-    void startEnumList()       
-    { 
-      XML_DB(("(startEnumList)\n"));
-      startParMode();
-      m_t << "<orderedlist>"; 
-      m_inListStack.push(TRUE);
-    }
-    void writeListItem()       
-    { 
-      XML_DB(("(writeListItem)\n"));
-      if (!m_inListStack.isEmpty() && m_inListStack.top()) // first element
-      {
-        m_inListStack.top()=FALSE;
-      }
-      else // not first element, end previous element first
-      {
-        endParMode();
-        endNestedPar();
-        m_t << "</listitem>" << endl; 
-      }
-      m_t << "<listitem>"; 
-      startNestedPar();
-    }
-    void endItemList()         
-    {
-      XML_DB(("(endItemList)\n"));
-      if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element
-      {
-        endParMode(); 
-        endNestedPar();
-        m_t << "</listitem>" << endl; 
-      }
-      m_t << "</itemizedlist>" << endl; 
-    }
-    void endEnumList()         
-    { 
-      XML_DB(("(endEnumList)\n"));
-      if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element
-      {
-        endParMode(); 
-        m_t << "</listitem>" << endl; 
-        endNestedPar(); 
-      }
-      m_t << "</orderedlist>" << endl; 
-    }
-    void newParagraph()        
-    { 
-      XML_DB(("(newParagraph)\n"));
-      endParMode();
-      startParMode();
-    }
-    void startBold()           
-    { 
-      XML_DB(("(startBold)\n"));
-      startParMode();
-      m_t << "<bold>"; // non DocBook
-    }
-    void endBold()             
-    { 
-      XML_DB(("(endBold)\n"));
-      m_t << "</bold>"; // non DocBook
-    }
-    void startTypewriter()     
-    { 
-      XML_DB(("(startTypewriter)\n"));
-      startParMode();
-      m_t << "<computeroutput>";
-    }
-    void endTypewriter()       
-    { 
-      XML_DB(("(endTypewriter)\n"));
-      m_t << "</computeroutput>";
-    }
-    void startEmphasis()       
-    { 
-      XML_DB(("(startEmphasis)\n"));
-      startParMode();
-      m_t << "<emphasis>";
-    }
-    void endEmphasis()         
-    { 
-      XML_DB(("(endEmphasis)\n"));
-      m_t << "</emphasis>";
-    }
-    void startCodeFragment()   
-    { 
-      XML_DB(("(startCodeFragment)\n"));
-      startParMode();
-      m_t << "<programlisting>";
-    }
-    void endCodeFragment()     
-    { 
-      XML_DB(("(endCodeFragment)\n"));
-      m_t << "</programlisting>"; 
-    }
-    void startPreFragment()    
-    { 
-      XML_DB(("(startPreFragment)\n"));
-      startParMode();
-      m_t << "<preformatted>";
-    }
-    void endPreFragment()      
-    { 
-      XML_DB(("(endPreFragment)\n"));
-      m_t << "</preformatted>"; 
-    }
-    void startVerbatimFragment()    
-    { 
-      XML_DB(("(startVerbatimFragment)\n"));
-      startParMode();
-      m_t << "<preformatted>";
-    }
-    void endVerbatimFragment()      
-    { 
-      XML_DB(("(endVerbatimFragment)\n"));
-      m_t << "</preformatted>"; 
-    }
-    void writeRuler()          
-    { 
-      XML_DB(("(startParMode)\n"));
-      startParMode();
-      m_t << "<hruler/>"; 
-    }
-    void startDescription()    
-    { 
-      XML_DB(("(startDescription)\n"));
-      startParMode();
-      m_t << "<variablelist>"; 
-      m_inListStack.push(TRUE);
-    }
-    void endDescription()      
-    { 
-      XML_DB(("(endDescription)\n"));
-      if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element
-      {
-        endNestedPar(); 
-        m_t << "</listitem>" << endl; 
-      }
-      m_t << "</variablelist>"; 
-      if (!m_inListStack.isEmpty()) m_inListStack.pop();
-    }
-    void startDescItem()       
-    { 
-      XML_DB(("(startDescItem)\n"));
-      if (!m_inListStack.isEmpty() && m_inListStack.top()) // first element
-      {
-        m_inListStack.top()=FALSE;
-      }
-      else // not first element, end previous element first
-      {
-        endNestedPar();
-        m_t << "</listitem>"; 
-      }
-      m_t << "<varlistentry><term>"; 
-    }
-    void endDescItem()         
-    { 
-      XML_DB(("(endDescItem)\n"));
-      m_t << "</term></varlistentry><listitem>"; 
-      startNestedPar();
-    }
-    void startDescList(SectionTypes st)       
-    { 
-      XML_DB(("(startDescList)\n"));
-      endParMode();
-      m_t << "<simplesect kind=\"" << sectionTypeToString(st);
-      m_t << "\"><title>"; 
-      startNestedPar();
-      m_inParStack.top() = TRUE;
-    }
-    void endDescList()         
-    { 
-      XML_DB(("(endDescList)\n"));
-      endNestedPar();
-      m_t << "</simplesect>";
-    }
-    void startSimpleSect(SectionTypes st,const char *,const char *,const char *)
-    {
-      XML_DB(("(startSimpleSect)\n"));
-      m_t << "<simplesect kind=\"" << sectionTypeToString(st) << "\">"; 
-      startNestedPar();
-    }
-    void endSimpleSect()         
+    void codify(const char *text) 
     {
-      XML_DB(("(endSimpleSect)\n"));
-      endNestedPar();
-      m_t << "</simplesect>";
-    }
-    void startParamList(ParamListTypes t,const char *)      
-    { 
-      XML_DB(("(startParamList)\n"));
-      startParMode();
-      QCString kind;
-      switch(t)
+      XML_DB(("(codify \"%s\")\n",text));
+      if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
       {
-        case Param:       kind="param";     break;
-        case RetVal:      kind="retval";    break;
-        case Exception:   kind="exception"; break;
+        m_t << "<highlight class=\"normal\">";
+        m_normalHLNeedStartTag=FALSE;
       }
-      m_t << "<parameterlist kind=\"" << kind << "\">"; // non DocBook
-      startNestedPar();
-      m_inParStack.top() = TRUE;
-      m_inParamList = TRUE;
-    }
-    void endParamList()        
-    { 
-      XML_DB(("(endParamList)\n"));
-      m_inParamList = FALSE;
-      m_t << "</parameterlist>";
-    }
-    void endDescTitle()        
-    { 
-      m_inParStack.top() = FALSE;
-      endNestedPar();
-      XML_DB(("(endDescTitle)\n"));
-      m_t << "</title>"; 
-      if (!m_inParamList) startNestedPar();
-    }
-    void writeDescItem()       
-    { 
-      XML_DB(("(writeDescItem)\n"));
-    }
-    void startDescTable()      
-    { 
-      XML_DB(("(startDescTable)\n"));
-    }
-    void endDescTable()        
-    { 
-      XML_DB(("(endDescTable)\n"));
-    }
-    void startDescTableTitle() 
-    { 
-      XML_DB(("(startDescTableTitle)\n"));
-      m_t << "<parametername>"; // non docbook
-    }
-    void endDescTableTitle()   
-    { 
-      XML_DB(("(endDescTableTitle)\n"));
-      m_t << "</parametername>"; // non docbook
-    }
-    void startDescTableData()  
-    { 
-      XML_DB(("(startDescTableData)\n"));
-      m_t << "<parameterdescription>"; // non docbook
-      startNestedPar();
-    }
-    void endDescTableData()    
-    { 
-      XML_DB(("(endDescTableData)\n"));
-      endNestedPar();
-      m_t << "</parameterdescription>"; // non docbook
-    }
-    void lineBreak()           
-    { 
-      XML_DB(("(lineBreak)\n"));
-      startParMode();
-      m_t << "<linebreak/>"; // non docbook
-    }
-    void writeNonBreakableSpace(int num) 
-    { 
-      XML_DB(("(writeNonBreakableSpace)\n"));
-      int i;for (i=0;i<num;i++) m_t << "&nbsp;"; 
-    }
-    
-    void writeObjectLink(const char *ref,const char *file,
-                         const char *anchor, const char *text) 
-    {
-      XML_DB(("(writeObjectLink)\n"));
-      startParMode();
-      writeXMLLink(m_t,ref,file,anchor,text);
+      writeXMLString(m_t,text);
     }
     void writeCodeLink(const char *ref,const char *file,
                                const char *anchor,const char *text) 
     {
       XML_DB(("(writeCodeLink)\n"));
-      writeXMLLink(m_t,ref,file,anchor,text);
-    }
-    void startHtmlLink(const char *url)
-    {
-      XML_DB(("(startHtmlLink)\n"));
-      startParMode();
-      m_t << "<ulink url=\"" << url << "\">";
-    }
-    void endHtmlLink()
-    {
-      XML_DB(("(endHtmlLink)\n"));
-      m_t << "</ulink>";
-    }
-    void writeMailLink(const char *url) 
-    {
-      XML_DB(("(writeMailLink)\n"));
-      startParMode();
-      m_t << "<email>";
-      docify(url); 
-      m_t << "</email>";
-    }
-    void startSection(const char *id,const char *,SectionInfo::SectionType type) 
-    {
-      XML_DB(("(startSection)\n"));
-      endParMode();
-      m_t << "<sect";
-      switch(type)
-      {
-        case SectionInfo::Page:       m_t << "1"; break;
-        case SectionInfo::Section:    m_t << "2"; break;
-        case SectionInfo::Subsection: m_t << "3"; break;
-        default: ASSERT(0); break;
-      }
-      m_t << " id=\"" << id << "\">";
-      startNestedPar();
-      m_inParStack.top() = TRUE;
-    }
-    void endSection(const char *,SectionInfo::SectionType type)
-    {
-      XML_DB(("(endSection)\n"));
-      m_t << "</sect";
-      switch(type)
-      {
-        case SectionInfo::Page:       m_t << "1"; break;
-        case SectionInfo::Section:    m_t << "2"; break;
-        case SectionInfo::Subsection: m_t << "3"; break;
-        default: ASSERT(0); break;
-      }
-      m_t << ">";
-      m_inParStack.top() = FALSE;
-      endNestedPar();
-    }
-    void startSubsection() 
-    {
-      XML_DB(("(startSubsection)\n"));
-      endParMode();
-      m_t << "<sect2>";
-      startNestedPar();
-      m_inParStack.top() = TRUE;
-    }
-    void endSubsection() 
-    {
-      XML_DB(("(endSubsection)\n"));
-      m_t << "</sect2>";
-      m_inParStack.top() = FALSE;
-      endNestedPar();
-    }
-    void startSubsubsection() 
-    {
-      XML_DB(("(startSubsubsection)\n"));
-      endParMode();
-      m_t << "<sect3>";
-      startNestedPar();
-      m_inParStack.top() = TRUE;
-    }
-    void endSubsubsection() 
-    {
-      XML_DB(("(endSubsubsection)\n"));
-      m_t << "</sect3>";
-      m_inParStack.top() = FALSE;
-      endNestedPar();
-    }
-    void startCenter() 
-    {
-      XML_DB(("(startCenter)\n"));
-      startParMode();
-      m_t << "<center>"; // non docbook
-    }
-    void endCenter() 
-    {
-      XML_DB(("(endCenter)\n"));
-      m_t << "</center>"; // non docbook
-    }
-    void startSmall() 
-    {
-      XML_DB(("(startSmall)\n"));
-      startParMode();
-      m_t << "<small>"; // non docbook
-    }
-    void endSmall() 
-    {
-      XML_DB(("(endSmall)\n"));
-      m_t << "</small>"; // non docbook
-    }
-    void startSubscript() 
-    {
-      XML_DB(("(startSubscript)\n"));
-      startParMode();
-      m_t << "<subscript>";
-    }
-    void endSubscript() 
-    {
-      XML_DB(("(endSubscript)\n"));
-      m_t << "</subscript>";
-    }
-    void startSuperscript() 
-    {
-      XML_DB(("(startSuperscript)\n"));
-      startParMode();
-      m_t << "<superscript>";
-    }
-    void endSuperscript() 
-    {
-      XML_DB(("(endSuperscript)\n"));
-      m_t << "</superscript>";
-    }
-    void startTable(bool,int cols) 
-    {
-      XML_DB(("startTable\n"));
-      startParMode();
-      m_t << "<table cols=\"" << cols << "\">\n";
-    }
-    void endTable(bool hasCaption) 
-    {
-      XML_DB(("endTable\n"));
-      if (!hasCaption) m_t << "</row>\n";
-      m_t << "</table>";
-    }
-    void startCaption()
-    {
-      XML_DB(("startCaption"));
-      m_t << "</row><caption>";
-    }
-    void endCaption()
-    {
-      XML_DB(("encCaption"));
-      m_t << "</caption>";
-    }
-    void nextTableRow() 
-    {
-      XML_DB(("(nextTableRow)\n"));
-      m_t << "<row><entry>";
-
-      // we need manually add a para here because cells are
-      // parsed before the table is generated, and thus
-      // are already parsed as if they are inside a paragraph.
-      m_t << "<para>";
-    }
-    void endTableRow() 
-    {
-      XML_DB(("(endTableRow)\n"));
-      m_t << "</row>" << endl;
-    }
-    void nextTableColumn() 
-    {
-      XML_DB(("(nextTableColumn)\n"));
-      m_t << "<entry>";
-      
-      // we need manually add a para here because cells are
-      // parsed before the table is generated, and thus
-      // are already parsed as if they are inside a paragraph.
-      m_t << "<para>";
-    }
-    void endTableColumn() 
-    {
-      XML_DB(("(endTableColumn)\n"));
-      // we need manually add a para here because cells are
-      // parsed before the table is generated, and thus
-      // are already parsed as if they are inside a paragraph.
-      m_t << "</para>";
-      m_t << "</entry>";
-    }
-
-    void writeQuote()         { m_t << "\""; }
-    void writeCopyright()     { m_t << "&copy;"; }
-    void writeUmlaut(char c)  { m_t << "&" << c << "uml;"; }
-    void writeAcute(char c)   { m_t << "&" << c << "acute;"; }
-    void writeGrave(char c)   { m_t << "&" << c << "grave;"; }
-    void writeCirc(char c)    { m_t << "&" << c << "circ;"; }
-    void writeTilde(char c)   { m_t << "&" << c << "tilde;"; }
-    void writeRing(char c)    { m_t << "&" << c << "ring;"; }
-    void writeSharpS()        { m_t << "&szlig;"; }
-    void writeCCedil(char c)  { m_t << "&" << c << "cedil;"; }
-
-    void startTitle() 
-    {
-      XML_DB(("(startTitle)\n"));
-      m_t << "<title>";
-      startNestedPar();
-      m_inParStack.top() = TRUE;
-    }
-    void endTitle()   
-    {
-      m_inParStack.top() = FALSE;
-      endNestedPar();
-      XML_DB(("(endTitle)\n"));
-      m_t << "</title>" << endl;
-    }
-    void writeAnchor(const char *id,const char *name) 
-    {
-      XML_DB(("(writeAnchor)\n"));
-      startParMode();
-      m_t << "<anchor id=\"" << id << "_1" << name << "\"/>";
-    }
-    void writeSectionRef(const char *,const char *id,
-                         const char *name,const char *text) 
-    {
-      XML_DB(("(writeSectionRef)\n"));
-      startParMode();
-      m_t << "<link linkend=\"" << id << "_1" << name << "\">";
-      docify(text);
-      m_t << "</link>";
-    }
-    void writeSectionRefItem(const char *,const char *,const char *) 
-    {
-      m_t << "(writeSectionRefItem)";
-    }
-    void addIndexItem(const char *primaryie,const char *secondaryie) 
-    {
-      XML_DB(("(addIndexItem)\n"));
-      startParMode();
-      m_t << "<indexentry><primaryie>";
-      docify(primaryie);
-      m_t << "</primaryie><secondaryie>";
-      docify(secondaryie);
-      m_t << "</secondaryie></indexentry>";
-    }
-    void writeFormula(const char *id,const char *text) 
-    {
-      XML_DB(("(writeFormula)\n"));
-      startParMode();
-      m_t << "<formula id=\"" << id << "\">"; // non Docbook
-      docify(text);
-      m_t << "</formula>";
-    }
-    void startImage(const char *name,const char *size,bool /*caption*/) 
-    {
-      XML_DB(("(startImage)\n"));
-      startParMode();
-      m_t << "<image name=\"" << name << "\"";
-      if (size) m_t << " size=\"" << size << "\"";
-      m_t << ">"; // non docbook 
-    }
-    void endImage(bool) 
-    {
-      XML_DB(("(endImage)\n"));
-      m_t << "</image>";
-    }
-    void startDotFile(const char *name,bool /*caption*/) 
-    {
-      XML_DB(("(startDotFile)\n"));
-      startParMode();
-      m_t << "<dotfile name=\"" << name << "\">"; // non docbook 
-    }
-    void endDotFile(bool) 
-    {
-      XML_DB(("(endDotFile)\n"));
-      m_t << "</dotfile>";
-    }
-    void startTextLink(const char *name,const char *anchor) 
-    {
-      XML_DB(("(startTextLink)\n"));
-      startParMode();
-      m_t << "<ulink url=\"" << name << "#" << anchor << "\">";
-    }
-    void endTextLink() 
-    {
-      XML_DB(("(endTextLink)\n"));
-      m_t << "</ulink>";
-    }
-    void startPageRef() 
-    {
-      XML_DB(("(startPageRef)\n"));
-      m_outputEnabled = FALSE;
-    }
-    void endPageRef(const char *,const char *) 
-    {
-      XML_DB(("(endPageRef)\n"));
-      m_outputEnabled = TRUE;
-    }
-    void writeLineNumber(const char *extRef,const char *compId,
-                         const char *anchorId,int l)
-    {
-      XML_DB(("(writeLineNumber)\n"));
-      m_t << "<linenumber";
-      m_t << " line=\"" << l << "\"";
-      if (compId)
+      if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
       {
-        m_t << " refid=\"" << compId;
-        if (anchorId) m_t << "_1" << anchorId; 
-        m_t << "\" kindref=\"";
-        if (anchorId) m_t << "member"; else m_t << "compound"; 
-        m_t << "\"";
-        if (extRef) m_t << " external=\"" << extRef << "\"";
+        m_t << "<highlight class=\"normal\">";
+        m_normalHLNeedStartTag=FALSE;
       }
-      m_t << "/>";
+      writeXMLLink(m_t,ref,file,anchor,text);
     }
     void startCodeLine() 
     {
       XML_DB(("(startCodeLine)\n"));
-      startParMode();
-      m_t << "<codeline>"; // non DocBook
+      m_t << "<codeline";
+      if (m_lineNumber!=-1)
+      {
+        m_t << " lineno=\"" << m_lineNumber << "\"";
+        if (!m_refId.isEmpty())
+        {
+          m_t << " refid=\"" << m_refId << "\"";
+          if (m_isMemberRef)
+          {
+            m_t << " refkind=\"member\"";
+          }
+          else
+          {
+            m_t << " refkind=\"compound\"";
+          }
+        }
+        if (!m_external.isEmpty())
+        {
+          m_t << " external=\"" << m_external << "\"";
+        }
+      }
+      m_t << ">"; 
+      m_insideCodeLine=TRUE;
     }
     void endCodeLine() 
     {
       XML_DB(("(endCodeLine)\n"));
+      if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
+      {
+        m_t << "</highlight>";
+        m_normalHLNeedStartTag=TRUE;
+      }
       m_t << "</codeline>" << endl; // non DocBook
+      m_lineNumber = -1;
+      m_refId.resize(0);
+      m_external.resize(0);
+      m_insideCodeLine=FALSE;
     }
     void startCodeAnchor(const char *id) 
     {
       XML_DB(("(startCodeAnchor)\n"));
-      startParMode();
+      if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
+      {
+        m_t << "<highlight class=\"normal\">";
+        m_normalHLNeedStartTag=FALSE;
+      }
       m_t << "<anchor id=\"" << id << "\">";
     }
     void endCodeAnchor() 
@@ -855,134 +280,867 @@ class XMLGenerator : public OutputDocInterface
     void startFontClass(const char *colorClass) 
     {
       XML_DB(("(startFontClass)\n"));
+      if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
+      {
+        m_t << "</highlight>";
+        m_normalHLNeedStartTag=TRUE;
+      }
       m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
+      m_insideSpecialHL=TRUE;
     }
     void endFontClass()
     {
       XML_DB(("(endFontClass)\n"));
       m_t << "</highlight>"; // non DocBook
-    }
-    void codify(const char *text) 
-    {
-      XML_DB(("(codify \"%s\")\n",text));
-      docify(text);
-    }
-    void startHtmlOnly()  
-    {
-      XML_DB(("(startHtmlOnly)\n"));
-      m_t << "<htmlonly>" << endl;
-    }
-    void endHtmlOnly()    
-    {
-      XML_DB(("(endHtmlOnly)\n"));
-      m_t << "</htmlonly>" << endl;
-    }
-    void startLatexOnly() 
-    {
-      XML_DB(("(startLatexOnly)\n"));
-      m_t << "<latexonly>" << endl;
-    }
-    void endLatexOnly()   
-    {
-      XML_DB(("(endLatexOnly)\n"));
-      m_t << "</latexonly>" << endl;
-    }
-    void startSectionRefList()
-    {
-      XML_DB(("(startSectionRefList)\n"));
-    }
-    void endSectionRefList()
-    {
-      XML_DB(("(endSectionRefList)\n"));
+      m_insideSpecialHL=FALSE;
     }
     void writeCodeAnchor(const char *)
     {
       XML_DB(("(writeCodeAnchor)\n"));
     }
-    
-    // Generator specific functions
-    
-    /*! Create a clone of this generator. Uses the copy constructor */
-    OutputDocInterface *clone() 
+    void writeLineNumber(const char *extRef,const char *compId,
+                         const char *anchorId,int l)
     {
-      return new XMLGenerator(this);
+      XML_DB(("(writeLineNumber)\n"));
+      // we remember the information provided here to use it 
+      // at the <codeline> start tag.
+      m_lineNumber = l;
+      if (compId)
+      {
+        m_refId=compId;
+        if (anchorId) m_refId+=(QCString)"_1"+anchorId;
+        m_isMemberRef = anchorId!=0;
+        if (extRef) m_external=extRef;
+      }
     }
-    /*! Append the output written to generator \a g to this generator */
-    void append(const OutputDocInterface *g) 
-    {
-      const XMLGenerator *xg = (const XMLGenerator *)g;
 
-      //printf("Appending \n>>>>\n`%s'\n<<<<\n and \n>>>>\n`%s'\n<<<<\n",getContents().data(),xg->getContents().data());
-      m_t << xg->getContents();
-      m_inParStack  = xg->m_inParStack;
-      m_inListStack = xg->m_inListStack;
-      m_inParamList = xg->m_inParamList;
-    }
-    /*! constructor. 
-     */
-    XMLGenerator() 
-    {
-      m_b.setBuffer(m_a);
-      m_b.open( IO_WriteOnly );
-      m_t.setDevice(&m_b);
-      m_t.setEncoding(QTextStream::Latin1);
-      m_inParamList = FALSE;
-      m_outputEnabled = TRUE;
-    }
-    /*! copy constructor */
-    XMLGenerator(const XMLGenerator *xg)
-    {
-      m_b.setBuffer(m_a);
-      m_b.open( IO_WriteOnly );
-      m_t.setDevice(&m_b);
-      m_t.setEncoding(QTextStream::Latin1);
-
-      //printf("Cloning >>%s<< m_parStack.count()=%d\n",
-      //    xg->getContents().data(),xg->m_inParStack.count());
-       
-      // copy state variables
-      m_inParStack  = xg->m_inParStack;
-      m_inListStack = xg->m_inListStack;
-      m_inParamList = xg->m_inParamList;
-      m_outputEnabled = xg->m_outputEnabled;
-    } 
-    /*! destructor */
-    virtual ~XMLGenerator()
-    {
-    }
-    /*! Returns the output written to this generator as a string */
-    QCString getContents() const
-    {
-      QCString s;
-      s.resize(m_a.size()+1);
-      memcpy(s.data(),m_a.data(),m_a.size());
-      s.at(m_a.size())='\0';
-      return s;
-    }
-    
   private:
-    // only one destination stream, so these do not have to be implemented
-    void pushGeneratorState() {}
-    void popGeneratorState() {}
-    void disableAllBut(OutputGenerator::OutputType) {}
-    void enableAll() {}
-    void disableAll() {}
-    void disable(OutputGenerator::OutputType) {}
-    void enable(OutputGenerator::OutputType) {}
-    bool isEnabled(OutputGenerator::OutputType) { return TRUE; }
-
-    QTextStream m_t;  
-    QByteArray m_a;
-    QBuffer m_b;
-    
-    ValStack<bool> m_inParStack;  
-    ValStack<bool> m_inListStack;
-    bool m_inParamList;
-    bool m_outputEnabled;
-    
-    friend void writeXMLCodeBlock(QTextStream &t,FileDef *fd);
+    QTextStream &m_t;  
+    QCString m_refId;
+    QCString m_external;
+    int m_lineNumber;
+    bool m_isMemberRef;
+
+    bool m_insideCodeLine;
+    bool m_normalHLNeedStartTag;
+    bool m_insideSpecialHL;
 };
 
+// /*! This class is used by the documentation parser.
+//  *  Its methods are called when some XML text or markup
+//  *  needs to be written.
+//  */
+// class XMLGenerator : public OutputDocInterface
+// {
+//   public:
+// 
+//     // helper functions
+//     
+//     void startParMode()
+//     {
+//       if (!m_inParStack.isEmpty() && !m_inParStack.top())
+//       {
+//         m_inParStack.top() = TRUE;
+//         m_t << "<para>";
+//         XML_DB(("start par at level=%d\n",m_inParStack.count()));
+//       }
+//       else if (m_inParStack.isEmpty())
+//       {
+//         m_inParStack.push(TRUE);
+//         m_t << "<para>";
+//         XML_DB(("start par at level=%d\n",m_inParStack.count()));
+//       }
+//     }
+//     void endParMode()
+//     {
+//       if (!m_inParStack.isEmpty() && m_inParStack.top())
+//       {
+//         m_inParStack.top() = FALSE;
+//         m_t << "</para>" << endl;
+//         XML_DB(("end par at level=%d\n",m_inParStack.count()));
+//       }
+//     }
+//     void startNestedPar()
+//     {
+//       m_inParStack.push(FALSE);
+//       XML_DB(("enter par level=%d\n",m_inParStack.count()));
+//     }
+//     void endNestedPar()
+//     {
+//       XML_DB(("leave par level=%d\n",m_inParStack.count()));
+//       if (m_inParStack.pop())
+//       {
+//         m_t << "</para>" << endl;
+//       }
+//       else
+//       {
+//         //XML_DB(("ILLEGAL par level!\n"));
+//       }
+//     }
+//   
+//     // Standard generator functions to be implemented by all generators
+// 
+//     void docify(const char *s) 
+//     {
+//       if (m_outputEnabled)
+//       {
+//         XML_DB(("(docify \"%s\")\n",s));
+//         startParMode();
+//         writeXMLString(m_t,s);
+//       }
+//     }
+//     void writeChar(char c) 
+//     {
+//       char s[2];s[0]=c;s[1]=0;
+//       docify(s);
+//     }
+//     void writeString(const char *text) 
+//     {
+//       //m_t << text;
+//       docify(text);
+//     }
+//     void startItemList()       
+//     { 
+//       XML_DB(("(startItemList)\n"));
+//       startParMode();
+//       m_t << "<itemizedlist>" << endl;; 
+//       m_inListStack.push(TRUE);
+//     }
+//     void startEnumList()       
+//     { 
+//       XML_DB(("(startEnumList)\n"));
+//       startParMode();
+//       m_t << "<orderedlist>"; 
+//       m_inListStack.push(TRUE);
+//     }
+//     void writeListItem()       
+//     { 
+//       XML_DB(("(writeListItem)\n"));
+//       if (!m_inListStack.isEmpty() && m_inListStack.top()) // first element
+//       {
+//         m_inListStack.top()=FALSE;
+//       }
+//       else // not first element, end previous element first
+//       {
+//         endParMode();
+//         endNestedPar();
+//         m_t << "</listitem>" << endl; 
+//       }
+//       m_t << "<listitem>"; 
+//       startNestedPar();
+//     }
+//     void endItemList()         
+//     {
+//       XML_DB(("(endItemList)\n"));
+//       if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element
+//       {
+//         endParMode(); 
+//         endNestedPar();
+//         m_t << "</listitem>" << endl; 
+//       }
+//       m_t << "</itemizedlist>" << endl; 
+//     }
+//     void endEnumList()         
+//     { 
+//       XML_DB(("(endEnumList)\n"));
+//       if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element
+//       {
+//         endParMode(); 
+//         m_t << "</listitem>" << endl; 
+//         endNestedPar(); 
+//       }
+//       m_t << "</orderedlist>" << endl; 
+//     }
+//     void newParagraph()        
+//     { 
+//       XML_DB(("(newParagraph)\n"));
+//       endParMode();
+//       startParMode();
+//     }
+//     void startBold()           
+//     { 
+//       XML_DB(("(startBold)\n"));
+//       startParMode();
+//       m_t << "<bold>"; // non DocBook
+//     }
+//     void endBold()             
+//     { 
+//       XML_DB(("(endBold)\n"));
+//       m_t << "</bold>"; // non DocBook
+//     }
+//     void startTypewriter()     
+//     { 
+//       XML_DB(("(startTypewriter)\n"));
+//       startParMode();
+//       m_t << "<computeroutput>";
+//     }
+//     void endTypewriter()       
+//     { 
+//       XML_DB(("(endTypewriter)\n"));
+//       m_t << "</computeroutput>";
+//     }
+//     void startEmphasis()       
+//     { 
+//       XML_DB(("(startEmphasis)\n"));
+//       startParMode();
+//       m_t << "<emphasis>";
+//     }
+//     void endEmphasis()         
+//     { 
+//       XML_DB(("(endEmphasis)\n"));
+//       m_t << "</emphasis>";
+//     }
+//     void startCodeFragment()   
+//     { 
+//       XML_DB(("(startCodeFragment)\n"));
+//       startParMode();
+//       m_t << "<programlisting>";
+//     }
+//     void endCodeFragment()     
+//     { 
+//       XML_DB(("(endCodeFragment)\n"));
+//       m_t << "</programlisting>"; 
+//     }
+//     void startPreFragment()    
+//     { 
+//       XML_DB(("(startPreFragment)\n"));
+//       startParMode();
+//       m_t << "<preformatted>";
+//     }
+//     void endPreFragment()      
+//     { 
+//       XML_DB(("(endPreFragment)\n"));
+//       m_t << "</preformatted>"; 
+//     }
+//     void startVerbatimFragment()    
+//     { 
+//       XML_DB(("(startVerbatimFragment)\n"));
+//       startParMode();
+//       m_t << "<preformatted>";
+//     }
+//     void endVerbatimFragment()      
+//     { 
+//       XML_DB(("(endVerbatimFragment)\n"));
+//       m_t << "</preformatted>"; 
+//     }
+//     void writeRuler()          
+//     { 
+//       XML_DB(("(startParMode)\n"));
+//       startParMode();
+//       m_t << "<hruler/>"; 
+//     }
+//     void startDescription()    
+//     { 
+//       XML_DB(("(startDescription)\n"));
+//       startParMode();
+//       m_t << "<variablelist>"; 
+//       m_inListStack.push(TRUE);
+//     }
+//     void endDescription()      
+//     { 
+//       XML_DB(("(endDescription)\n"));
+//       if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element
+//       {
+//         endNestedPar(); 
+//         m_t << "</listitem>" << endl; 
+//       }
+//       m_t << "</variablelist>"; 
+//       if (!m_inListStack.isEmpty()) m_inListStack.pop();
+//     }
+//     void startDescItem()       
+//     { 
+//       XML_DB(("(startDescItem)\n"));
+//       if (!m_inListStack.isEmpty() && m_inListStack.top()) // first element
+//       {
+//         m_inListStack.top()=FALSE;
+//       }
+//       else // not first element, end previous element first
+//       {
+//         endNestedPar();
+//         m_t << "</listitem>"; 
+//       }
+//       m_t << "<varlistentry><term>"; 
+//     }
+//     void endDescItem()         
+//     { 
+//       XML_DB(("(endDescItem)\n"));
+//       m_t << "</term></varlistentry><listitem>"; 
+//       startNestedPar();
+//     }
+//     void startDescList(SectionTypes st)       
+//     { 
+//       XML_DB(("(startDescList)\n"));
+//       endParMode();
+//       m_t << "<simplesect kind=\"" << sectionTypeToString(st);
+//       m_t << "\"><title>"; 
+//       startNestedPar();
+//       m_inParStack.top() = TRUE;
+//     }
+//     void endDescList()         
+//     { 
+//       XML_DB(("(endDescList)\n"));
+//       endNestedPar();
+//       m_t << "</simplesect>";
+//     }
+//     void startSimpleSect(SectionTypes st,const char *,const char *,const char *)
+//     {
+//       XML_DB(("(startSimpleSect)\n"));
+//       m_t << "<simplesect kind=\"" << sectionTypeToString(st) << "\">"; 
+//       startNestedPar();
+//     }
+//     void endSimpleSect()         
+//     {
+//       XML_DB(("(endSimpleSect)\n"));
+//       endNestedPar();
+//       m_t << "</simplesect>";
+//     }
+//     void startParamList(ParamListTypes t,const char *)      
+//     { 
+//       XML_DB(("(startParamList)\n"));
+//       startParMode();
+//       QCString kind;
+//       switch(t)
+//       {
+//         case Param:       kind="param";     break;
+//         case RetVal:      kind="retval";    break;
+//         case Exception:   kind="exception"; break;
+//       }
+//       m_t << "<parameterlist kind=\"" << kind << "\">"; // non DocBook
+//       startNestedPar();
+//       m_inParStack.top() = TRUE;
+//       m_inParamList = TRUE;
+//     }
+//     void endParamList()        
+//     { 
+//       XML_DB(("(endParamList)\n"));
+//       m_inParamList = FALSE;
+//       m_t << "</parameterlist>";
+//     }
+//     void endDescTitle()        
+//     { 
+//       m_inParStack.top() = FALSE;
+//       endNestedPar();
+//       XML_DB(("(endDescTitle)\n"));
+//       m_t << "</title>"; 
+//       if (!m_inParamList) startNestedPar();
+//     }
+//     void writeDescItem()       
+//     { 
+//       XML_DB(("(writeDescItem)\n"));
+//     }
+//     void startDescTable()      
+//     { 
+//       XML_DB(("(startDescTable)\n"));
+//     }
+//     void endDescTable()        
+//     { 
+//       XML_DB(("(endDescTable)\n"));
+//     }
+//     void startDescTableTitle() 
+//     { 
+//       XML_DB(("(startDescTableTitle)\n"));
+//       m_t << "<parametername>"; // non docbook
+//     }
+//     void endDescTableTitle()   
+//     { 
+//       XML_DB(("(endDescTableTitle)\n"));
+//       m_t << "</parametername>"; // non docbook
+//     }
+//     void startDescTableData()  
+//     { 
+//       XML_DB(("(startDescTableData)\n"));
+//       m_t << "<parameterdescription>"; // non docbook
+//       startNestedPar();
+//     }
+//     void endDescTableData()    
+//     { 
+//       XML_DB(("(endDescTableData)\n"));
+//       endNestedPar();
+//       m_t << "</parameterdescription>"; // non docbook
+//     }
+//     void lineBreak()           
+//     { 
+//       XML_DB(("(lineBreak)\n"));
+//       startParMode();
+//       m_t << "<linebreak/>"; // non docbook
+//     }
+//     void writeNonBreakableSpace(int num) 
+//     { 
+//       XML_DB(("(writeNonBreakableSpace)\n"));
+//       int i;for (i=0;i<num;i++) m_t << "&nbsp;"; 
+//     }
+//     
+//     void writeObjectLink(const char *ref,const char *file,
+//                          const char *anchor, const char *text) 
+//     {
+//       XML_DB(("(writeObjectLink)\n"));
+//       startParMode();
+//       writeXMLLink(m_t,ref,file,anchor,text);
+//     }
+//     void writeCodeLink(const char *ref,const char *file,
+//                                const char *anchor,const char *text) 
+//     {
+//       XML_DB(("(writeCodeLink)\n"));
+//       writeXMLLink(m_t,ref,file,anchor,text);
+//     }
+//     void startHtmlLink(const char *url)
+//     {
+//       XML_DB(("(startHtmlLink)\n"));
+//       startParMode();
+//       m_t << "<ulink url=\"" << url << "\">";
+//     }
+//     void endHtmlLink()
+//     {
+//       XML_DB(("(endHtmlLink)\n"));
+//       m_t << "</ulink>";
+//     }
+//     void writeMailLink(const char *url) 
+//     {
+//       XML_DB(("(writeMailLink)\n"));
+//       startParMode();
+//       m_t << "<email>";
+//       docify(url); 
+//       m_t << "</email>";
+//     }
+//     void startSection(const char *id,const char *,SectionInfo::SectionType type) 
+//     {
+//       XML_DB(("(startSection)\n"));
+//       endParMode();
+//       m_t << "<sect";
+//       switch(type)
+//       {
+//         case SectionInfo::Page:       m_t << "1"; break;
+//         case SectionInfo::Section:    m_t << "2"; break;
+//         case SectionInfo::Subsection: m_t << "3"; break;
+//         default: ASSERT(0); break;
+//       }
+//       m_t << " id=\"" << id << "\">";
+//       startNestedPar();
+//       m_inParStack.top() = TRUE;
+//     }
+//     void endSection(const char *,SectionInfo::SectionType type)
+//     {
+//       XML_DB(("(endSection)\n"));
+//       m_t << "</sect";
+//       switch(type)
+//       {
+//         case SectionInfo::Page:       m_t << "1"; break;
+//         case SectionInfo::Section:    m_t << "2"; break;
+//         case SectionInfo::Subsection: m_t << "3"; break;
+//         default: ASSERT(0); break;
+//       }
+//       m_t << ">";
+//       m_inParStack.top() = FALSE;
+//       endNestedPar();
+//     }
+//     void startSubsection() 
+//     {
+//       XML_DB(("(startSubsection)\n"));
+//       endParMode();
+//       m_t << "<sect2>";
+//       startNestedPar();
+//       m_inParStack.top() = TRUE;
+//     }
+//     void endSubsection() 
+//     {
+//       XML_DB(("(endSubsection)\n"));
+//       m_t << "</sect2>";
+//       m_inParStack.top() = FALSE;
+//       endNestedPar();
+//     }
+//     void startSubsubsection() 
+//     {
+//       XML_DB(("(startSubsubsection)\n"));
+//       endParMode();
+//       m_t << "<sect3>";
+//       startNestedPar();
+//       m_inParStack.top() = TRUE;
+//     }
+//     void endSubsubsection() 
+//     {
+//       XML_DB(("(endSubsubsection)\n"));
+//       m_t << "</sect3>";
+//       m_inParStack.top() = FALSE;
+//       endNestedPar();
+//     }
+//     void startCenter() 
+//     {
+//       XML_DB(("(startCenter)\n"));
+//       startParMode();
+//       m_t << "<center>"; // non docbook
+//     }
+//     void endCenter() 
+//     {
+//       XML_DB(("(endCenter)\n"));
+//       m_t << "</center>"; // non docbook
+//     }
+//     void startSmall() 
+//     {
+//       XML_DB(("(startSmall)\n"));
+//       startParMode();
+//       m_t << "<small>"; // non docbook
+//     }
+//     void endSmall() 
+//     {
+//       XML_DB(("(endSmall)\n"));
+//       m_t << "</small>"; // non docbook
+//     }
+//     void startSubscript() 
+//     {
+//       XML_DB(("(startSubscript)\n"));
+//       startParMode();
+//       m_t << "<subscript>";
+//     }
+//     void endSubscript() 
+//     {
+//       XML_DB(("(endSubscript)\n"));
+//       m_t << "</subscript>";
+//     }
+//     void startSuperscript() 
+//     {
+//       XML_DB(("(startSuperscript)\n"));
+//       startParMode();
+//       m_t << "<superscript>";
+//     }
+//     void endSuperscript() 
+//     {
+//       XML_DB(("(endSuperscript)\n"));
+//       m_t << "</superscript>";
+//     }
+//     void startTable(bool,int cols) 
+//     {
+//       XML_DB(("startTable\n"));
+//       startParMode();
+//       m_t << "<table cols=\"" << cols << "\">\n";
+//     }
+//     void endTable(bool hasCaption) 
+//     {
+//       XML_DB(("endTable\n"));
+//       if (!hasCaption) m_t << "</row>\n";
+//       m_t << "</table>";
+//     }
+//     void startCaption()
+//     {
+//       XML_DB(("startCaption"));
+//       m_t << "</row><caption>";
+//     }
+//     void endCaption()
+//     {
+//       XML_DB(("encCaption"));
+//       m_t << "</caption>";
+//     }
+//     void nextTableRow() 
+//     {
+//       XML_DB(("(nextTableRow)\n"));
+//       m_t << "<row><entry>";
+// 
+//       // we need manually add a para here because cells are
+//       // parsed before the table is generated, and thus
+//       // are already parsed as if they are inside a paragraph.
+//       m_t << "<para>";
+//     }
+//     void endTableRow() 
+//     {
+//       XML_DB(("(endTableRow)\n"));
+//       m_t << "</row>" << endl;
+//     }
+//     void nextTableColumn() 
+//     {
+//       XML_DB(("(nextTableColumn)\n"));
+//       m_t << "<entry>";
+//       
+//       // we need manually add a para here because cells are
+//       // parsed before the table is generated, and thus
+//       // are already parsed as if they are inside a paragraph.
+//       m_t << "<para>";
+//     }
+//     void endTableColumn() 
+//     {
+//       XML_DB(("(endTableColumn)\n"));
+//       // we need manually add a para here because cells are
+//       // parsed before the table is generated, and thus
+//       // are already parsed as if they are inside a paragraph.
+//       m_t << "</para>";
+//       m_t << "</entry>";
+//     }
+// 
+//     void writeQuote()         { m_t << "\""; }
+//     void writeCopyright()     { m_t << "&copy;"; }
+//     void writeUmlaut(char c)  { m_t << "&" << c << "uml;"; }
+//     void writeAcute(char c)   { m_t << "&" << c << "acute;"; }
+//     void writeGrave(char c)   { m_t << "&" << c << "grave;"; }
+//     void writeCirc(char c)    { m_t << "&" << c << "circ;"; }
+//     void writeTilde(char c)   { m_t << "&" << c << "tilde;"; }
+//     void writeRing(char c)    { m_t << "&" << c << "ring;"; }
+//     void writeSharpS()        { m_t << "&szlig;"; }
+//     void writeCCedil(char c)  { m_t << "&" << c << "cedil;"; }
+// 
+//     void startTitle() 
+//     {
+//       XML_DB(("(startTitle)\n"));
+//       m_t << "<title>";
+//       startNestedPar();
+//       m_inParStack.top() = TRUE;
+//     }
+//     void endTitle()   
+//     {
+//       m_inParStack.top() = FALSE;
+//       endNestedPar();
+//       XML_DB(("(endTitle)\n"));
+//       m_t << "</title>" << endl;
+//     }
+//     void writeAnchor(const char *id,const char *name) 
+//     {
+//       XML_DB(("(writeAnchor)\n"));
+//       startParMode();
+//       m_t << "<anchor id=\"" << id << "_1" << name << "\"/>";
+//     }
+//     void writeSectionRef(const char *,const char *id,
+//                          const char *name,const char *text) 
+//     {
+//       XML_DB(("(writeSectionRef)\n"));
+//       startParMode();
+//       m_t << "<link linkend=\"" << id << "_1" << name << "\">";
+//       docify(text);
+//       m_t << "</link>";
+//     }
+//     void writeSectionRefItem(const char *,const char *,const char *) 
+//     {
+//       m_t << "(writeSectionRefItem)";
+//     }
+//     void addIndexItem(const char *primaryie,const char *secondaryie) 
+//     {
+//       XML_DB(("(addIndexItem)\n"));
+//       startParMode();
+//       m_t << "<indexentry><primaryie>";
+//       docify(primaryie);
+//       m_t << "</primaryie><secondaryie>";
+//       docify(secondaryie);
+//       m_t << "</secondaryie></indexentry>";
+//     }
+//     void writeFormula(const char *id,const char *text) 
+//     {
+//       XML_DB(("(writeFormula)\n"));
+//       startParMode();
+//       m_t << "<formula id=\"" << id << "\">"; // non Docbook
+//       docify(text);
+//       m_t << "</formula>";
+//     }
+//     void startImage(const char *name,const char *size,bool /*caption*/) 
+//     {
+//       XML_DB(("(startImage)\n"));
+//       startParMode();
+//       m_t << "<image name=\"" << name << "\"";
+//       if (size) m_t << " size=\"" << size << "\"";
+//       m_t << ">"; // non docbook 
+//     }
+//     void endImage(bool) 
+//     {
+//       XML_DB(("(endImage)\n"));
+//       m_t << "</image>";
+//     }
+//     void startDotFile(const char *name,bool /*caption*/) 
+//     {
+//       XML_DB(("(startDotFile)\n"));
+//       startParMode();
+//       m_t << "<dotfile name=\"" << name << "\">"; // non docbook 
+//     }
+//     void endDotFile(bool) 
+//     {
+//       XML_DB(("(endDotFile)\n"));
+//       m_t << "</dotfile>";
+//     }
+//     void startTextLink(const char *name,const char *anchor) 
+//     {
+//       XML_DB(("(startTextLink)\n"));
+//       startParMode();
+//       m_t << "<ulink url=\"" << name << "#" << anchor << "\">";
+//     }
+//     void endTextLink() 
+//     {
+//       XML_DB(("(endTextLink)\n"));
+//       m_t << "</ulink>";
+//     }
+//     void startPageRef() 
+//     {
+//       XML_DB(("(startPageRef)\n"));
+//       m_outputEnabled = FALSE;
+//     }
+//     void endPageRef(const char *,const char *) 
+//     {
+//       XML_DB(("(endPageRef)\n"));
+//       m_outputEnabled = TRUE;
+//     }
+//     void writeLineNumber(const char *extRef,const char *compId,
+//                          const char *anchorId,int l)
+//     {
+//       XML_DB(("(writeLineNumber)\n"));
+//       m_t << "<linenumber";
+//       m_t << " line=\"" << l << "\"";
+//       if (compId)
+//       {
+//         m_t << " refid=\"" << compId;
+//         if (anchorId) m_t << "_1" << anchorId; 
+//         m_t << "\" kindref=\"";
+//         if (anchorId) m_t << "member"; else m_t << "compound"; 
+//         m_t << "\"";
+//         if (extRef) m_t << " external=\"" << extRef << "\"";
+//       }
+//       m_t << "/>";
+//     }
+//     void startCodeLine() 
+//     {
+//       XML_DB(("(startCodeLine)\n"));
+//       startParMode();
+//       m_t << "<codeline>"; // non DocBook
+//     }
+//     void endCodeLine() 
+//     {
+//       XML_DB(("(endCodeLine)\n"));
+//       m_t << "</codeline>" << endl; // non DocBook
+//     }
+//     void startCodeAnchor(const char *id) 
+//     {
+//       XML_DB(("(startCodeAnchor)\n"));
+//       startParMode();
+//       m_t << "<anchor id=\"" << id << "\">";
+//     }
+//     void endCodeAnchor() 
+//     {
+//       XML_DB(("(endCodeAnchor)\n"));
+//       m_t << "</anchor>";
+//     }
+//     void startFontClass(const char *colorClass) 
+//     {
+//       XML_DB(("(startFontClass)\n"));
+//       m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
+//     }
+//     void endFontClass()
+//     {
+//       XML_DB(("(endFontClass)\n"));
+//       m_t << "</highlight>"; // non DocBook
+//     }
+//     void codify(const char *text) 
+//     {
+//       XML_DB(("(codify \"%s\")\n",text));
+//       docify(text);
+//     }
+//     void startHtmlOnly()  
+//     {
+//       XML_DB(("(startHtmlOnly)\n"));
+//       m_t << "<htmlonly>" << endl;
+//     }
+//     void endHtmlOnly()    
+//     {
+//       XML_DB(("(endHtmlOnly)\n"));
+//       m_t << "</htmlonly>" << endl;
+//     }
+//     void startLatexOnly() 
+//     {
+//       XML_DB(("(startLatexOnly)\n"));
+//       m_t << "<latexonly>" << endl;
+//     }
+//     void endLatexOnly()   
+//     {
+//       XML_DB(("(endLatexOnly)\n"));
+//       m_t << "</latexonly>" << endl;
+//     }
+//     void startSectionRefList()
+//     {
+//       XML_DB(("(startSectionRefList)\n"));
+//     }
+//     void endSectionRefList()
+//     {
+//       XML_DB(("(endSectionRefList)\n"));
+//     }
+//     void writeCodeAnchor(const char *)
+//     {
+//       XML_DB(("(writeCodeAnchor)\n"));
+//     }
+//     
+//     // Generator specific functions
+//     
+//     /*! Create a clone of this generator. Uses the copy constructor */
+//     OutputDocInterface *clone() 
+//     {
+//       return new XMLGenerator(this);
+//     }
+//     /*! Append the output written to generator \a g to this generator */
+//     void append(const OutputDocInterface *g) 
+//     {
+//       const XMLGenerator *xg = (const XMLGenerator *)g;
+// 
+//       //printf("Appending \n>>>>\n`%s'\n<<<<\n and \n>>>>\n`%s'\n<<<<\n",getContents().data(),xg->getContents().data());
+//       m_t << xg->getContents();
+//       m_inParStack  = xg->m_inParStack;
+//       m_inListStack = xg->m_inListStack;
+//       m_inParamList = xg->m_inParamList;
+//     }
+//     /*! constructor. 
+//      */
+//     XMLGenerator() 
+//     {
+//       m_b.setBuffer(m_a);
+//       m_b.open( IO_WriteOnly );
+//       m_t.setDevice(&m_b);
+//       m_t.setEncoding(QTextStream::Latin1);
+//       m_inParamList = FALSE;
+//       m_outputEnabled = TRUE;
+//     }
+//     /*! copy constructor */
+//     XMLGenerator(const XMLGenerator *xg)
+//     {
+//       m_b.setBuffer(m_a);
+//       m_b.open( IO_WriteOnly );
+//       m_t.setDevice(&m_b);
+//       m_t.setEncoding(QTextStream::Latin1);
+// 
+//       //printf("Cloning >>%s<< m_parStack.count()=%d\n",
+//       //    xg->getContents().data(),xg->m_inParStack.count());
+//        
+//       // copy state variables
+//       m_inParStack  = xg->m_inParStack;
+//       m_inListStack = xg->m_inListStack;
+//       m_inParamList = xg->m_inParamList;
+//       m_outputEnabled = xg->m_outputEnabled;
+//     } 
+//     /*! destructor */
+//     virtual ~XMLGenerator()
+//     {
+//     }
+//     /*! Returns the output written to this generator as a string */
+//     QCString getContents() const
+//     {
+//       QCString s;
+//       s.resize(m_a.size()+1);
+//       memcpy(s.data(),m_a.data(),m_a.size());
+//       s.at(m_a.size())='\0';
+//       return s;
+//     }
+//     
+//   private:
+//     // only one destination stream, so these do not have to be implemented
+//     void pushGeneratorState() {}
+//     void popGeneratorState() {}
+//     void disableAllBut(OutputGenerator::OutputType) {}
+//     void enableAll() {}
+//     void disableAll() {}
+//     void disable(OutputGenerator::OutputType) {}
+//     void enable(OutputGenerator::OutputType) {}
+//     bool isEnabled(OutputGenerator::OutputType) { return TRUE; }
+// 
+//     QTextStream m_t;  
+//     QByteArray m_a;
+//     QBuffer m_b;
+//     
+//     ValStack<bool> m_inParStack;  
+//     ValStack<bool> m_inListStack;
+//     bool m_inParamList;
+//     bool m_outputEnabled;
+//     
+//     friend void writeXMLCodeBlock(QTextStream &t,FileDef *fd);
+// };
+
 static void writeTemplateArgumentList(ArgumentList *al,QTextStream &t,const char *name,int indent)
 {
   QCString indentStr;
@@ -1037,11 +1195,25 @@ static void writeXMLDocBlock(QTextStream &t,
                       const QCString &fileName,
                       int lineNr,
                       const QCString &scope,
-                      MemberDef *md,
+                      MemberDef * md,
                       const QCString &text)
 {
   QCString stext = text.stripWhiteSpace();
   if (text.isEmpty()) return;
+  // convert the documentation string into an abstract syntax tree
+  DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,stext);
+  // create a code generator
+  XMLCodeGenerator *xmlCodeGen = new XMLCodeGenerator(t);
+  // create a parse tree visitor for XML
+  XmlDocVisitor *visitor = new XmlDocVisitor(t,*xmlCodeGen);
+  // visit all nodes
+  root->accept(visitor);
+  // clean up
+  delete visitor;
+  delete xmlCodeGen;
+  delete root;
+  
+/* 
   XMLGenerator *xmlGen = new XMLGenerator;
   //xmlGen->startParMode();
   parseDoc(*xmlGen,
@@ -1054,20 +1226,21 @@ static void writeXMLDocBlock(QTextStream &t,
   xmlGen->endParMode();
   t << xmlGen->getContents();
   delete xmlGen;
+*/
 }
 
 void writeXMLCodeBlock(QTextStream &t,FileDef *fd)
 {
   initParseCodeContext();
-  XMLGenerator *xmlGen = new XMLGenerator;
-  xmlGen->m_inParStack.push(TRUE);
+  XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t);
+  //xmlGen->m_inParStack.push(TRUE);
   parseCode(*xmlGen,
             0,
             fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")),
             FALSE,
             0,
             fd);
-  t << xmlGen->getContents();
+  //t << xmlGen->getContents();
   delete xmlGen;
 }
 
@@ -1466,8 +1639,7 @@ static void generateXMLForClass(ClassDef *cd,QTextStream &ti)
   }
   QTextStream t(&f);
 
-  t << "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>" << endl;
-  t << "<doxygen version=\"" << versionString << "\">" << endl;
+  writeXMLHeader(t);
   t << "  <compounddef id=\"" 
     << cd->getOutputFileBase() << "\" kind=\"" 
     << cd->compoundTypeString() << "\">" << endl;
@@ -1652,8 +1824,7 @@ static void generateXMLForNamespace(NamespaceDef *nd,QTextStream &ti)
   }
   QTextStream t(&f);
   
-  t << "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>" << endl;
-  t << "<doxygen version=\"" << versionString << "\">" << endl;
+  writeXMLHeader(t);
   t << "  <compounddef id=\"" 
     << nd->getOutputFileBase() << "\" kind=\"namespace\">" << endl;
   t << "    <compoundname>";
@@ -1743,8 +1914,7 @@ static void generateXMLForFile(FileDef *fd,QTextStream &ti)
   }
   QTextStream t(&f);
 
-  t << "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>" << endl;
-  t << "<doxygen version=\"" << versionString << "\">" << endl;
+  writeXMLHeader(t);
   t << "  <compounddef id=\"" 
     << fd->getOutputFileBase() << "\" kind=\"file\">" << endl;
   t << "    <compoundname>";
@@ -1876,8 +2046,7 @@ static void generateXMLForGroup(GroupDef *gd,QTextStream &ti)
   }
 
   QTextStream t(&f);
-  t << "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>" << endl;
-  t << "<doxygen version=\"" << versionString << "\">" << endl;
+  writeXMLHeader(t);
   t << "  <compounddef id=\"" 
     << gd->getOutputFileBase() << "\" kind=\"group\">" << endl;
   t << "    <compoundname>" << convertToXML(gd->name()) << "</compoundname>" << endl;
@@ -1975,11 +2144,14 @@ static void generateXMLForPage(PageInfo *pi,QTextStream &ti)
 
   if (pi->isReference()) return;
   
-  ti << "  <compound refid=\"" << pi->getOutputFileBase() 
+  QCString pageName = pi->getOutputFileBase();
+  if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page.
+  
+  ti << "  <compound refid=\"" << pageName
      << "\" kind=\"page\"><name>" << convertToXML(pi->name) << "</name>" << endl;
   
   QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
-  QCString fileName=outputDirectory+"/xml/"+pi->getOutputFileBase()+".xml";
+  QCString fileName=outputDirectory+"/xml/"+pageName+".xml";
   QFile f(fileName);
   if (!f.open(IO_WriteOnly))
   {
@@ -1988,8 +2160,7 @@ static void generateXMLForPage(PageInfo *pi,QTextStream &ti)
   }
 
   QTextStream t(&f);
-  t << "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>" << endl;
-  t << "<doxygen version=\"" << versionString << "\">" << endl;
+  writeXMLHeader(t);
   t << "  <compounddef id=\"";
   if (Config_getBool("CASE_SENSE_NAMES")) t << pi->name; else t << pi->name.lower();
   t << "\" kind=\"page\">" << endl;
@@ -2071,10 +2242,7 @@ void generateXML()
     return;
   }
   QTextStream t(&f);
-  t << "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>" << endl;
-  //t << "<!DOCTYPE doxygen SYSTEM \"doxygen.dtd\">" << endl;
-  t << "<doxygen version=\"" << versionString << "\">" << endl;
-  //t << "  <compoundlist>" << endl;
+  writeXMLHeader(t);
   ClassSDict::Iterator cli(Doxygen::classSDict);
   ClassDef *cd;
   for (cli.toFirst();(cd=cli.current());++cli)
@@ -2110,6 +2278,10 @@ void generateXML()
   {
     generateXMLForPage(pi,t);
   }
+  if (Doxygen::mainPage)
+  {
+    generateXMLForPage(Doxygen::mainPage,t);
+  }
 
   //t << "  </compoundlist>" << endl;
   t << "</doxygen>" << endl;
-- 
cgit v0.12