From fe67b8eb68129713327965c201f2d7226b83202f Mon Sep 17 00:00:00 2001
From: dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>
Date: Sun, 3 Dec 2000 19:13:07 +0000
Subject: Release-1.2.3-20001203

---
 INSTALL                        |    4 +-
 README                         |    4 +-
 VERSION                        |    2 +-
 addon/configgen/config_templ.l |   17 +
 addon/configgen/configgen.cpp  |   10 +
 doc/Makefile.win.in            |    2 +-
 doc/config.doc                 |   18 +
 doc/docblocks.doc              |    2 +-
 doc/index.doc                  |    5 +-
 packages/rpm/doxygen.spec      |    2 +-
 qtools/qcollection.h           |    4 +-
 qtools/qconfig.h               |    9 +-
 qtools/qcstring.cpp            |    2 +-
 qtools/qdatetime.cpp           |    2 +-
 qtools/qdir.cpp                |   22 +-
 qtools/qdir_unix.cpp           |   34 +-
 qtools/qfeatures.h             |  605 ++--
 qtools/qfile_unix.cpp          |   42 +-
 qtools/qglobal.h               |   49 +-
 qtools/qiodevice.cpp           |    6 +-
 qtools/qlist.h                 |    1 -
 qtools/qmap.cpp                |  254 ++
 qtools/qmap.h                  |  606 ++++
 qtools/qmodules.h              |   11 +
 qtools/qstring.cpp             |   37 +-
 qtools/qstring.h               |    5 +-
 qtools/qtextcodec.cpp          |  173 +-
 qtools/qtextstream.cpp         |  206 +-
 qtools/qtextstream.h           |    4 +
 qtools/qtools.pro.in           |   10 +-
 qtools/qvaluestack.h           |   64 +
 qtools/qxml.cpp                | 6007 ++++++++++++++++++++++++++++++++++++++++
 qtools/qxml.h                  |  645 +++++
 src/classdef.cpp               |    6 +-
 src/config.h                   |    3 +-
 src/config.l                   |   35 +-
 src/doc.l                      |   14 +-
 src/doxygen.cpp                |   94 +-
 src/filedef.cpp                |   10 +-
 src/ftvhelp.cpp                |   39 +-
 src/ftvhelp.h                  |    6 +-
 src/htmlgen.cpp                |    1 +
 src/index.cpp                  |   49 +-
 src/instdox.cpp                |   15 +-
 src/pre.l                      |   29 +-
 src/scanner.l                  |   71 +-
 src/translator_cn.h            |   13 +-
 src/treeview.h                 |   43 +-
 src/treeview.js                |   43 +-
 49 files changed, 8789 insertions(+), 546 deletions(-)
 create mode 100644 qtools/qmap.cpp
 create mode 100644 qtools/qmap.h
 create mode 100644 qtools/qmodules.h
 create mode 100644 qtools/qvaluestack.h
 create mode 100644 qtools/qxml.cpp
 create mode 100644 qtools/qxml.h

diff --git a/INSTALL b/INSTALL
index b97ceee..56ae336 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,6 @@
-DOXYGEN Version 1.2.3-20001126
+DOXYGEN Version 1.2.3-20001203
 
 Please read the installation section of the manual for instructions.
 
 --------
-Dimitri van Heesch (26 November 2000)
+Dimitri van Heesch (03 December 2000)
diff --git a/README b/README
index ccd8256..7d5098d 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.2.3-20001126
+DOXYGEN Version 1.2.3-20001203
 
 Please read INSTALL for compilation instructions.
 
@@ -7,4 +7,4 @@ The latest version of doxygen can be obtained at
 
 Enjoy,
 
-Dimitri van Heesch (26 November 2000)
+Dimitri van Heesch (03 December 2000)
diff --git a/VERSION b/VERSION
index af626bc..d2f09f2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.2.3-20001126
+1.2.3-20001203
diff --git a/addon/configgen/config_templ.l b/addon/configgen/config_templ.l
index 81d4acf..6cccca9 100644
--- a/addon/configgen/config_templ.l
+++ b/addon/configgen/config_templ.l
@@ -453,6 +453,23 @@ void configStrToVal()
     Config::enumValuesPerLine=cols;
   }
   
+  if (treeViewWidthString.isEmpty())
+  {
+    Config::treeViewWidth=250;
+  }
+  else
+  {
+    bool ok;
+    int width = treeViewWidthString.toInt(&ok);
+    if (!ok || width<0 || width>1500)
+    {
+      warn_cont("Warning: argument of TREEVIEW_WIDTH is not a valid number in the range [0..1500]!\n"
+	   "Using the default of 250!\n");
+      width = 250;
+    }
+    Config::treeViewWidth=width;
+  }
+
   if (maxDotGraphWidthString.isEmpty())
   {
     Config::maxDotGraphWidth=1024;
diff --git a/addon/configgen/configgen.cpp b/addon/configgen/configgen.cpp
index c05cca7..c7b4ab8 100644
--- a/addon/configgen/configgen.cpp
+++ b/addon/configgen/configgen.cpp
@@ -1313,6 +1313,16 @@ void init()
                     "or Internet explorer 4.0+). "
                  );
   addDependency("ftvHelpFlag","generateHtml");
+  ConfigInt::add(   "treeViewWidth",
+                    "TREEVIEW_WIDTH",
+                    "250",
+                    "What is the width of the treeview panel?",
+                    "If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \n"
+                    "used to set the initial width (in pixels) of the frame in which the tree \n"
+                    "is shown. \n",
+                    0,1500
+                 );
+  addDependency("treeViewWidth","generateHtml");
 
 //  TODO: integrate this option
 //  ConfigBool::add(  "htmlHelpGroupsOnly",
diff --git a/doc/Makefile.win.in b/doc/Makefile.win.in
index fd2dbc7..0e7624d 100644
--- a/doc/Makefile.win.in
+++ b/doc/Makefile.win.in
@@ -13,7 +13,7 @@
 # input used in their production; they are not affected by this license.
 
 all: FORCE
-	@xcopy /s /q ..\examples ..\html\examples
+	@xcopy /s /q /i ..\examples ..\html\examples
 	set DOXYGEN_DOCDIR=.
 	set VERSION=$(VERSION)
 	$(DOXYGEN)\bin\doxygen
diff --git a/doc/config.doc b/doc/config.doc
index 8debf84..684710f 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -110,6 +110,7 @@ followed by the descriptions of the tags grouped by category.
 <li> \refitem cfg_generate_tagfile GENERATE_TAGFILE
 <li> \refitem cfg_generate_testlist GENERATE_TESTLIST
 <li> \refitem cfg_generate_todolist GENERATE_TODOLIST
+<li> \refitem cfg_generate_treeview GENERATE_TREEVIEW
 <li> \refitem cfg_graphical_hierarchy GRAPHICAL_HIERARCHY
 <li> \refitem cfg_have_dot HAVE_DOT
 <li> \refitem cfg_hide_scope_names HIDE_SCOPE_NAMES
@@ -162,6 +163,7 @@ followed by the descriptions of the tags grouped by category.
 <li> \refitem cfg_strip_from_path STRIP_FROM_PATH
 <li> \refitem cfg_tab_size TAB_SIZE
 <li> \refitem cfg_tagfiles TAGFILES
+<li> \refitem cfg_treeview_width TREEVIEW_WIDTH
 <li> \refitem cfg_verbatim_headers VERBATIM_HEADERS
 <li> \refitem cfg_warn_format WARN_FORMAT
 <li> \refitem cfg_warn_if_undocumented WARN_IF_UNDOCUMENTED
@@ -737,6 +739,22 @@ followed by the descriptions of the tags grouped by category.
  This tag can be used to set the number of enum values (range [1..20])
  that doxygen will group on one line in the generated HTML documentation.
 
+\anchor cfg_generate_treeview
+<dt>\c GENERATE_TREEVIEW <dd>
+ \addindex GENERATE_TREEVIEW
+ If the \c GENERATE_TREEVIEW tag is set to YES, a side pannel will be
+ generated containing a tree-like index structure (just like the one that
+ is generated for HTML Help). For this to work a browser that supports
+ JavaScript and frames is required (for instance Netscape 4.0+
+ or Internet explorer 4.0+).
+
+\anchor cfg_treeview_width
+<dt>\c TREEVIEW_WIDTH <dd>
+ \addindex TREEVIEW_WIDTH
+ If the treeview is enabled (see \c GENERATE_TREEVIEW) then this tag can be
+ used to set the initial width (in pixels) of the frame in which the tree
+ is shown.
+
 </dl>
 \subsection latex_output LaTeX related options
 \anchor cfg_generate_latex
diff --git a/doc/docblocks.doc b/doc/docblocks.doc
index 7500eb5..8241c43 100644
--- a/doc/docblocks.doc
+++ b/doc/docblocks.doc
@@ -151,7 +151,7 @@ Here is an example of a C header named \c structcmd.h that is documented
 using structural commands:
 \verbinclude structcmd.h
  \htmlonly
- Click <a href="$(DOXYGEN_DOCDIR)/examples/structcmd/html/structcmd.h.html">here</a>
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/structcmd/html/structcmd_h.html">here</a>
  for the corresponding HTML documentation that is generated by doxygen.
  \endhtmlonly
 
diff --git a/doc/index.doc b/doc/index.doc
index 39069ec..86e10bb 100644
--- a/doc/index.doc
+++ b/doc/index.doc
@@ -169,8 +169,9 @@ Thanks go to:
 <li>Jens Breitenstein, Christophe Bordeaux, Samuel H�gglund, Xet Erixon, 
     Vlastimil Havran, Petr Prikryl, Ahmed Also Faisal, Alessandro Falappa, 
     Kenji Nagamatsu, Francisco Oltra Thennet, Olli Korhonen, 
-    Boris Bralo, Nickolay Semyonov, and Grzegorz Kowal for providing 
-    translations into various languages.
+    Boris Bralo, Nickolay Semyonov, Richard Kim, F�ldv�ri Gy�rgy,
+    Grzegorz Kowal, and Wang Weihan 
+    for providing translations into various languages.
 <li>many, many others for suggestions, patches and bug reports.
 </ul>
 */
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index a426ee4..efbe6aca 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,5 +1,5 @@
 Name: doxygen
-Version: 1.2.3-20001126
+Version: 1.2.3-20001203
 Summary: documentation system for C, C++ and IDL
 Release: 1
 Source0: doxygen-%{version}.src.tar.gz
diff --git a/qtools/qcollection.h b/qtools/qcollection.h
index c7ba00f..a169b7c 100644
--- a/qtools/qcollection.h
+++ b/qtools/qcollection.h
@@ -66,8 +66,8 @@ protected:
 
     bool del_item;				// default FALSE
 
-    virtual Item	     newItem( Item );		// create object
-    virtual void     deleteItem( Item );		// delete object
+    virtual Item     newItem( Item );		// create object
+    virtual void     deleteItem( Item );	// delete object
 };
 
 
diff --git a/qtools/qconfig.h b/qtools/qconfig.h
index fe14e97..7a880f9 100644
--- a/qtools/qconfig.h
+++ b/qtools/qconfig.h
@@ -1,8 +1 @@
-// Empty leaves all features enabled.  See doc/html/features.html for choices.
-
-// Note that disabling some features will produce a libqt that is not
-// compatible with other libqt builds. Such modifications are only
-// supported on Qt/Embedded where reducing the library size is important
-// and where the application-suite is often a fixed set.
-
-#define QT_DLL // Internal
+// Everything
diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp
index 77dc386..2d2e0c5 100644
--- a/qtools/qcstring.cpp
+++ b/qtools/qcstring.cpp
@@ -183,7 +183,7 @@ int qstricmp( const char *str1, const char *str2 )
     int res;
     uchar c;
     if ( !s1 || !s2 )
-	return s1 == s1 ? 0 : (int)((long)s2 - (long)s1);
+	return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
     for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
 	if ( !c )				// strings are equal
 	    break;
diff --git a/qtools/qdatetime.cpp b/qtools/qdatetime.cpp
index 521a022..cecb855 100644
--- a/qtools/qdatetime.cpp
+++ b/qtools/qdatetime.cpp
@@ -355,7 +355,7 @@ bool QDate::setYMD( int y, int m, int d )
     }
     jd = greg2jul( y, m, d );
 #if defined(DEBUG)
-    ASSERT( year() == y && month() == m && day() == d );
+    ASSERT( year() == (y > 99 ? y : 1900+y) && month() == m && day() == d );
 #endif
     return TRUE;
 }
diff --git a/qtools/qdir.cpp b/qtools/qdir.cpp
index c4b4987..185933a 100644
--- a/qtools/qdir.cpp
+++ b/qtools/qdir.cpp
@@ -241,7 +241,7 @@ QDir::~QDir()
   is using a relative or an absolute file path. You can call the function
   convertToAbs() to convert a relative QDir to an absolute one.
 
-  \sa path(), absPath(), exists, cleanDirPath(), dirName(),
+  \sa path(), absPath(), exists(), cleanDirPath(), dirName(),
       absFilePath(), isRelative(), convertToAbs()
 */
 
@@ -469,7 +469,6 @@ bool QDir::cdUp()
 /*!
   \fn QString QDir::nameFilter() const
   Returns the string set by setNameFilter()
-  \sa setNameFilter()
 */
 
 /*!
@@ -481,7 +480,7 @@ bool QDir::cdUp()
   ".cpp" and all files ending with ".h", you simply call
   dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h")
 
-  \sa nameFilter()
+  \sa nameFilter(), setFilter()
 */
 
 void QDir::setNameFilter( const QString &nameFilter )
@@ -495,7 +494,6 @@ void QDir::setNameFilter( const QString &nameFilter )
 /*!
   \fn QDir::FilterSpec QDir::filter() const
   Returns the value set by setFilter()
-  \sa setFilter()
 */
 
 /*! \enum QDir::FilterSpec
@@ -533,7 +531,8 @@ void QDir::setNameFilter( const QString &nameFilter )
   Sets the filter used by entryList() and entryInfoList(). The filter is used
   to specify the kind of files that should be returned by entryList() and
   entryInfoList().
-  \sa nameFilter()
+
+  \sa filter(), setNameFilter()
 */
 
 void QDir::setFilter( int filterSpec )
@@ -1030,7 +1029,20 @@ QStringList qt_makeFilterList( const QString &filter )
 	QString s = *it;
 	if ( s[ (int)s.length() - 1 ] == ';' )
 	    s.remove( s.length() - 1, 1 );
+	if ( s[0] == '\"' ) {
+	    s.remove( 0, 1 );
+	    while( ++it != lst.end() ) {
+		QString s2 = *it;
+		s += " "+s2;
+		if ( s2[(int)s2.length() -1] == '\"' ) {
+		    s.remove( s.length() -1, 1 );
+		    break;
+		}
+	    }
+	}
 	lst2 << s;
+	if ( it == lst.end() )
+	    break;
     }
     return lst2;
 }
diff --git a/qtools/qdir_unix.cpp b/qtools/qdir_unix.cpp
index 3b12de9..46a3b69 100644
--- a/qtools/qdir_unix.cpp
+++ b/qtools/qdir_unix.cpp
@@ -243,23 +243,25 @@ bool QDir::readDirEntries( const QString &nameFilter,
     }
 
     // Sort...
-    QDirSortItem* si= new QDirSortItem[fiList->count()];
-    QFileInfo* itm;
-    i=0;
-    for (itm = fiList->first(); itm; itm = fiList->next())
-	si[i++].item = itm;
-    qt_cmp_si_sortSpec = sortSpec;
-    qsort( si, i, sizeof(si[0]), qt_cmp_si );
-    // put them back in the list
-    fiList->setAutoDelete( FALSE );
-    fiList->clear();
-    int j;
-    for ( j=0; j<i; j++ ) {
-	fiList->append( si[j].item );
-	fList->append( si[j].item->fileName() );
+    if(fiList->count()) {
+	QDirSortItem* si= new QDirSortItem[fiList->count()];
+	QFileInfo* itm;
+	i=0;
+	for (itm = fiList->first(); itm; itm = fiList->next())
+	    si[i++].item = itm;
+	qt_cmp_si_sortSpec = sortSpec;
+	qsort( si, i, sizeof(si[0]), qt_cmp_si );
+	// put them back in the list
+	fiList->setAutoDelete( FALSE );
+	fiList->clear();
+	int j;
+	for ( j=0; j<i; j++ ) {
+	    fiList->append( si[j].item );
+	    fList->append( si[j].item->fileName() );
+	}
+	delete [] si;
+	fiList->setAutoDelete( TRUE );
     }
-    delete [] si;
-    fiList->setAutoDelete( TRUE );
 
     if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
 	 nameFilter == nameFilt )
diff --git a/qtools/qfeatures.h b/qtools/qfeatures.h
index 5f6f663..e2e356c 100644
--- a/qtools/qfeatures.h
+++ b/qtools/qfeatures.h
@@ -42,7 +42,29 @@
     ...
 */
 
+// Qt ships with a number of pre-defined configurations. If none suit
+// your needs, define QCONFIG_LOCAL and create a "qconfig-local.h" file.
+//
+// Note that disabling some features will produce a libqt that is not
+// compatible with other libqt builds. Such modifications are only
+// supported on Qt/Embedded where reducing the library size is important
+// and where the application-suite is often a fixed set.
+//
+#if defined(QCONFIG_LOCAL)
+#include <qconfig-local.h>
+#elif defined(QCONFIG_QPE)
+#include <qconfig-qpe.h>
+#elif defined(QCONFIG_MINIMAL)
+#include <qconfig-minimal.h>
+#elif defined(QCONFIG_SMALL)
+#include <qconfig-small.h>
+#elif defined(QCONFIG_MEDIUM)
+#include <qconfig-medium.h>
+#elif defined(QCONFIG_LARGE)
+#include <qconfig-large.h>
+#else // everything...
 #include <qconfig.h>
+#endif
 
 
 // Data structures
@@ -51,6 +73,13 @@
 */
 //#define QT_NO_STRINGLIST
 
+#if defined(QT_NO_IMAGE_SMOOTHSCALE)
+/*!
+    QIconSet
+*/
+# define QT_NO_ICONSET
+#endif
+
 // File I/O
 #if defined(QT_NO_STRINGLIST)
     /*!
@@ -60,6 +89,11 @@
 #endif
 
 /*!
+  Palettes
+*/
+//#define QT_NO_PALETTE
+
+/*!
     QTextStream
 */
 //#define QT_NO_TEXTSTREAM
@@ -68,6 +102,12 @@
 */
 //#define QT_NO_DATASTREAM
 
+/*!
+  Dynamic module linking
+*/
+//#define QT_NO_PLUGIN
+
+
 // Images
 /*!
     BMP image I/O
@@ -196,50 +236,112 @@
 # define QT_NO_UNICODETABLES
 #endif
 
-// MIME-typed data
 /*!
     MIME
 */
 #if defined(QT_NO_DIR)
 # define QT_NO_MIME
 #endif
-#if defined(QT_NO_MIME) || defined(QT_NO_TEXTSTREAM)
+#if defined(QT_NO_MIME) || defined(QT_NO_TEXTSTREAM) || defined(QT_NO_DRAWUTIL) || defined(QT_NO_IMAGE_SMOOTHSCALE)
     /*!
 	RichText (HTML) display
     */
 # define QT_NO_RICHTEXT
 #endif
 
-//XML
-
-#if defined(QT_NO_STRINGLIST)
+/*!
+  XML
+*/
+#if defined(QT_NO_STRINGLIST) || defined(QT_NO_TEXTSTREAM) || defined(QT_NO_TEXTCODEC)
 # define QT_NO_XML
 #endif
 
-/*! Document Object Model */
-#if defined(QT_NO_XML) ||defined(QT_NO_MIME)
+/*!
+  Document Object Model
+*/
+#if defined(QT_NO_XML) || defined(QT_NO_MIME)
 # define QT_NO_DOM
 #endif
 
 // Sound
 /*!
-    QSound
+    Playing sounds
 */
 //#define QT_NO_SOUND
 
-// Scripting
 /*!
     Properties
 */
-#if defined(QT_NO_STRINGLIST)
+#if defined(QT_NO_STRINGLIST) || defined(QT_NO_ICONSET)
 # define QT_NO_PROPERTIES
 #endif
 
+
+
+// Networking
+
+/*!
+  Network support
+*/
+//#define QT_NO_NETWORK
+
+#if defined(QT_NO_NETWORK) || defined(QT_NO_STRINGLIST) || defined(QT_NO_TEXTSTREAM)
+   /*!
+     DNS
+   */
+# define QT_NO_DNS
+#endif
+/*!
+    Network file access
+*/
+#if defined(QT_NO_NETWORK) || defined(QT_NO_DIR) || defined(QT_NO_STRINGLIST)
+# define QT_NO_NETWORKPROTOCOL
+#endif
+#if defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_DNS)
+    /*!
+	FTP file access
+    */
+# define QT_NO_NETWORKPROTOCOL_FTP
+    /*!
+	HTTP file access
+    */
+# define QT_NO_NETWORKPROTOCOL_HTTP
+#endif
+
+/*!
+  External process invocation.
+*/
+//#define QT_NO_PROCESS
+
+
 // Qt/Embedded-specific
+
+#if defined(QT_NO_NETWORK)
+    /*!
+      Multi-process support.
+    */
+# define QT_NO_QWS_MULTIPROCESS
+#endif
+
+#if defined(QT_NO_QWS_MULTIPROCESS) || defined(QT_NO_DATASTREAM)
+    /*!
+      Palmtop Communication Protocol
+    */
+# define QT_NO_COP
+#endif
+
+/*!
+    Console keyboard support
+*/
+//#define QT_NO_QWS_KEYBOARD
+
 /*!
     Visible cursor
 */
-//#define QT_NO_QWS_CURSOR
+#if defined(QT_NO_CURSOR)
+# define QT_NO_QWS_CURSOR
+#endif
+
 /*!
     Alpha-blended cursor
 */
@@ -247,20 +349,25 @@
 /*!
     Mach64 acceleration
 */
-#define QT_NO_QWS_MACH64
+//#define QT_NO_QWS_MACH64
 /*!
     Voodoo3 acceleration
 */
-#define QT_NO_QWS_VOODOO3
+//#define QT_NO_QWS_VOODOO3
 /*!
     Matrox MGA acceleration (Millennium/Millennium II/Mystique/G200/G400)
 */
-#define QT_NO_QWS_MATROX
+//#define QT_NO_QWS_MATROX
 /*!
     Virtual frame buffer
 */
+                                        
 //#define QT_NO_QWS_VFB
 /*!
+    Transformed frame buffer
+*/
+//#define QT_NO_QWS_TRANSFORMED
+/*!
     Remote frame buffer (VNC)
 */
 #define QT_NO_QWS_VNC
@@ -270,9 +377,13 @@
 //#define QT_NO_QWS_DEPTH_1
 /*!
     4-bit VGA
-    Not yet implemented
 */
-#define QT_NO_QWS_VGA_16
+//#define QT_NO_QWS_VGA_16
+/*!
+    SVGALib Support
+    Not implemented yet
+*/
+#define QT_NO_QWS_SVGALIB
 /*!
     8-bit grayscale
 */
@@ -282,11 +393,7 @@
 */
 //#define QT_NO_QWS_DEPTH_8
 /*!
-    15-bit color
-*/
-#define QT_NO_QWS_DEPTH_15
-/*!
-    16-bit color
+    15 or 16-bit color (define QT_QWS_DEPTH16_RGB as 555 for 15-bit)
 */
 //#define QT_NO_QWS_DEPTH_16
 /*!
@@ -302,7 +409,7 @@
 /*!
     Saving of fonts
 */
-#define QT_NO_QWS_SAVEFONTS
+//#define QT_NO_QWS_SAVEFONTS
 
 /*!
     Favour code size over graphics speed
@@ -316,8 +423,10 @@
 */
 //#define QT_NO_QWS_PROPERTIES
 
-#if defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_MIME) && !defined(_WS_QWS_)
-/*! Cut and paste */
+#if defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_MIME)
+    /*!
+      Cut and paste
+    */
 # define QT_NO_CLIPBOARD
 #endif
 
@@ -328,6 +437,13 @@
 # define QT_NO_DRAGANDDROP
 #endif
 
+#if defined(QT_NO_PROPERTIES)
+    /*!
+	SQL
+    */
+# define QT_NO_SQL
+#endif
+
 #if defined(QT_NO_CLIPBOARD) || defined(QT_NO_MIME) || defined(_WS_QWS_)
     /*!
 	Cut and paste of complex data types (non-text)
@@ -362,36 +478,10 @@
     */
 # define QT_NO_IMAGE_16_BIT
 #endif
-#if defined(QT_NO_QWS_CURSOR) && defined(_WS_QWS_)
-    /*!
-	Cursors
-    */
-# define QT_NO_CURSOR
-#endif
-
-
-
-// Networking
-/*!
-    DNS
-*/
-//#define QT_NO_DNS
 /*!
-    Network file access
+    Cursors
 */
-#if defined(QT_NO_DIR) || defined(QT_NO_STRINGLIST)
-# define QT_NO_NETWORKPROTOCOL
-#endif
-#if defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_DNS)
-    /*!
-	FTP file access
-    */
-# define QT_NO_NETWORKPROTOCOL_FTP
-    /*!
-	HTTP file access
-    */
-# define QT_NO_NETWORKPROTOCOL_HTTP
-#endif
+//#define QT_NO_CURSOR
 
 // Painting
 /*!
@@ -403,7 +493,6 @@
 */
 //#define QT_NO_TRANSFORMATIONS
 
-// Printing
 /*!
     Printing
 */
@@ -411,7 +500,6 @@
 # define QT_NO_PRINTER
 #endif
 
-// Metafiles
 /*!
     QPicture
 */
@@ -426,64 +514,266 @@
 //#define QT_NO_LAYOUT
 
 // Widgets
+#if defined(QT_NO_DRAWUTIL) || defined(QT_NO_PALETTE)
 /*!
     QStyle
 */
-//#define QT_NO_STYLE
+# define QT_NO_STYLE
+#endif
 
 
-#if defined QT_NO_IMAGE_SMOOTHSCALE
 /*!
-    QIconSet
-*/
-# define QT_NO_ICONSET
-#endif
-/*!
-  QDialog
+  Dialogs
 */
 //#define QT_NO_DIALOG
 /*!
-  QSemiModal
+  Semi-modal dialogs
 */
 //#define QT_NO_SEMIMODAL
 /*!
-  QFrame
+  Framed widgets
 */
 //#define QT_NO_FRAME
 
-#if defined(QT_NO_FRAME) ||defined(QT_NO_PALETTE) || defined(QT_NO_STYLE) ||defined(QT_NO_DRAWUTIL)
-    /*! 
-      Basic widgets: QLAbel, QPushbutton, ...
-    */  
-# define QT_NO_SIMPLEWIDGETS
-#endif
+/*!
+  Special widget effects (fading, scrolling)
+*/
+//#define QT_NO_EFFECTS
 
-#if defined(QT_NO_SIMPLEWIDGETS)
-    /*!
-      QLabel
-    */
+
+/*!
+  QLabel
+*/
+#ifdef QT_NO_FRAME
 # define QT_NO_LABEL
-    /*!
-      QPushButton (not implemented).
-    */
-# define QT_NO_PUSHBUTTON
-    /*!
-      QLineEdit (not implemented).
-    */
+#endif
+
+/*!
+  Toolbars
+*/
+#ifdef QT_NO_LAYOUT
+# define QT_NO_TOOLBAR
+#endif
+
+/*!
+  Buttons
+*/
+#if defined(QT_NO_BUTTON) || defined(QT_NO_STYLE)
+/*!
+  Check-boxes
+*/
+# define QT_NO_CHECKBOX
+/*!
+  Radio-buttons
+*/
+# define QT_NO_RADIOBUTTON
+#endif
+#if defined(QT_NO_BUTTON) || defined(QT_NO_TOOLBAR) || defined(QT_NO_ICONSET)
+/*!
+  Tool-buttons
+*/
+# define QT_NO_TOOLBUTTON
+#endif
+/*!
+  Grid layout widgets
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_GRID
+#endif
+/*!
+  Group boxes
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_GROUPBOX
+#endif
+#if defined(QT_NO_GROUPBOX)
+/*!
+  Button groups
+*/
+# define QT_NO_BUTTONGROUP
+/*!
+  Horizontal group boxes
+*/
+# define QT_NO_HGROUPBOX
+#endif
+#if defined(QT_NO_HGROUPBOX)
+/*!
+  Vertical group boxes
+*/
+# define QT_NO_VGROUPBOX
+#endif
+#if defined(QT_NO_BUTTONGROUP)
+/*!
+  Horizontal button groups
+*/
+#  define QT_NO_HBUTTONGROUP
+#endif
+#if defined(QT_NO_HBUTTONGROUP)
+/*!
+  Vertical button groups
+*/
+#   define QT_NO_VBUTTONGROUP
+#endif
+/*!
+  Horizonal box layout widgets
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_HBOX
+#endif
+#if defined(QT_NO_HBOX)
+/*!
+  Vertical box layout widgets
+*/
+# define QT_NO_VBOX
+#endif
+/*!
+  Single-line edits
+*/
+#if defined(QT_NO_PALETTE)
 # define QT_NO_LINEEDIT
 #endif
-#if  defined(QT_NO_ICONSET) || defined(QT_NO_IMAGE_SMOOTHSCALE) || defined(QT_NO_SIMPLEWIDGETS)
-    /*!
-	Pre-defined complex widgets
-    */
-# define QT_NO_COMPLEXWIDGETS
+#if defined(QT_NO_TOOLBAR)
+/*!
+  Main-windows
+*/
+# define QT_NO_MAINWINDOW
+#endif
+#if defined(QT_NO_ICONSET)
+/*!
+  Menu-like widgets
+*/
+# define QT_NO_MENUDATA
+#endif
+#if defined(QT_NO_MENUDATA)
+/*!
+  Popup-menus
+*/
+# define QT_NO_POPUPMENU
+/*!
+  Menu bars
+*/
+# define QT_NO_MENUBAR
+#endif
+#if defined(QT_NO_BUTTON) || defined(QT_NO_ICONSET) || defined(QT_NO_POPUPMENU)
+/*!
+  Push-buttons
+*/
+# define QT_NO_PUSHBUTTON
+#endif
+/*!
+  Progress bars
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_PROGRESSBAR
+#endif
+/*!
+  Range-control widgets
+*/
+//#define QT_NO_RANGECONTROL
+#if defined(QT_NO_RANGECONTROL) || defined(QT_NO_STYLE)
+/*!
+  Scroll bars
+*/
+# define QT_NO_SCROLLBAR
+/*!
+  Sliders
+*/
+# define QT_NO_SLIDER
+/*!
+  Spin boxes
+*/
+# define QT_NO_SPINBOX
+/*!
+  Dials
+*/
+# define QT_NO_DIAL
+#endif
+
+
+#if defined(QT_NO_SCROLLBAR) || defined(QT_NO_FRAME)
+/*!
+  Scrollable view widgets
+*/
+# define QT_NO_SCROLLVIEW
+#endif
+#if defined(QT_NO_SCROLLVIEW)
+/*!
+    QCanvas
+*/
+# define QT_NO_CANVAS
+/*!
+    QIconView
+*/
+# define QT_NO_ICONVIEW
+#endif
+
+#if defined(QT_NO_SCROLLBAR)
+/*!
+  Table-like widgets
+*/
+# define QT_NO_TABLEVIEW
+#endif
+#if defined(QT_NO_TABLEVIEW)
+/*!
+  Multi-line edits
+*/
+# define QT_NO_MULTILINEEDIT
+#endif
+
+/*!
+  Splitters
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_SPLITTER
+#endif
+/*!
+  Status bars
+*/
+#ifdef QT_NO_LAYOUT
+# define QT_NO_STATUSBAR
+#endif
+/*!
+  Tab-bars
+*/
+#if defined(QT_NO_ICONSET)
+# define QT_NO_TABBAR
+#endif
+#if defined(QT_NO_TABBAR)
+/*!
+  Tab widgets
+*/
+# define QT_NO_TABWIDGET
+#endif
+/*!
+  Tool tips
+*/
+#if defined( QT_NO_LABEL ) || defined( QT_NO_PALETTE )
+# define QT_NO_TOOLTIP
+#endif
+/*!
+  Input validators
+*/
+//#define QT_NO_VALIDATOR
+/*!
+  "What's this" help
+*/
+#if defined( QT_NO_TOOLTIP )
+# define QT_NO_WHATSTHIS
+#endif
+/*!
+  Widget stacks
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_WIDGETSTACK
 #endif
-#if defined(QT_NO_COMPLEXWIDGETS) || defined(QT_NO_RICHTEXT)
+
+#if defined(QT_NO_RICHTEXT) || defined(QT_NO_SCROLLVIEW)
     /*!
 	QTextView
     */
 # define QT_NO_TEXTVIEW
 #endif
+
 #if defined(QT_NO_TEXTVIEW)
     /*!
 	QTextBrowser
@@ -503,84 +793,74 @@
 #endif
 
 #if defined(QT_NO_STYLE_MOTIF)
+    /*!
+	Motif-plus style
+    */
 # define QT_NO_STYLE_MOTIFPLUS
 #endif
 
 
-#if defined(QT_NO_COMPLEXWIDGETS) || defined(QT_NO_STRINGLIST)
+#if defined(QT_NO_SCROLLVIEW) || defined(QT_NO_STRINGLIST)
     /*!
 	QListBox
     */
 # define QT_NO_LISTBOX
 #endif
 
-#if defined(QT_NO_COMPLEXWIDGETS)
-    /*!
-	QAccel
-    */
-# define QT_NO_ACCEL
+/*!
+    QAccel
+*/
+//#define QT_NO_ACCEL
 
-    /*!
-	QSizeGrip
-    */
+/*!
+    QSizeGrip
+*/
+#ifdef QT_NO_PALETTE
 # define QT_NO_SIZEGRIP
-    /*!
-	QHeader
-    */
+#endif
+/*!
+    QHeader
+*/
+#ifdef QT_NO_ICONSET
 # define QT_NO_HEADER
-    /*!
-	QMenuBar
-    */
-# define QT_NO_MENUBAR
-    /*!
-	QCanvas
-    */
-# define QT_NO_CANVAS
-    /*!
-	QDial
-    */
-# define QT_NO_DIAL
-    /*!
-	QWorkSpace
-    */
+#endif
+/*!
+    QWorkSpace
+*/
+#ifdef QT_NO_FRAME
 # define QT_NO_WORKSPACE
-    /*!
-	QLCDNumber
-    */
+#endif
+/*!
+    QLCDNumber
+*/
+#ifdef QT_NO_FRAME
 # define QT_NO_LCDNUMBER
-    /*!
-	QAction
-    */
-# define QT_NO_ACTION
+#endif
+/*!
+    QAction
+*/
+//#define QT_NO_ACTION
+
+#if defined(QT_NO_HEADER)
     /*!
 	QTable
     */
 # define QT_NO_TABLE
 #endif
-#if defined(QT_NO_LISTBOX) || defined(QT_NO_COMPLEXWIDGETS)
+
+#if defined(QT_NO_LISTBOX)
     /*!
 	QComboBox
     */
 # define QT_NO_COMBOBOX
 #endif    
-#if defined(QT_NO_COMPLEXWIDGETS)
-    /*!
-	QIconView
-    */
-# define QT_NO_ICONVIEW
-#endif
-#if defined(QT_NO_HEADER)
+
+#if defined(QT_NO_HEADER) || defined(QT_NO_SCROLLVIEW)
     /*!
 	QListView
     */
 # define QT_NO_LISTVIEW
 #endif
-#if defined(QT_NO_COMPLEXWIDGETS) || defined(QT_NO_DIALOG)
-   /*!
-	Built-in dialogs
-    */
-# define QT_NO_DIALOGS
-#endif
 
 #if defined(QT_NO_STYLE_WINDOWS)
     /*!
@@ -589,7 +869,7 @@
 # define QT_NO_STYLE_COMPACT
 #endif
 
-#if defined(QT_NO_STYLE_MOTIF)
+#if defined(QT_NO_STYLE_MOTIF) || defined(QT_NO_TRANSFORMATIONS)
     /*!
 	CDE style
     */
@@ -606,53 +886,60 @@
 # define QT_NO_STYLE_PLATINUM
 #endif
 
-#if defined(QT_NO_DIALOGS)
-    /*!
-	QColorDialog
-    */
+/*!
+    QColorDialog
+*/
+#if defined(QT_NO_LAYOUT) || defined(QT_NO_LABEL) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_DIALOG)
 # define QT_NO_COLORDIALOG
-    /*!
-	QMessageBox
-    */
+#endif
+#if defined(QT_NO_DIALOG)
+/*!
+    QMessageBox
+*/
 # define QT_NO_MESSAGEBOX
-    /*!
-	QTabDialog
-    */
-# define QT_NO_TABDIALOG
-    /*!
-	QWizard
-    */
+#endif
+#if defined(QT_NO_DIALOG) || defined(QT_NO_TABBAR)
+/*!
+    QTabDialog
+*/
+#define QT_NO_TABDIALOG
+#endif
+
+#if defined(QT_NO_DIALOG)
+/*!
+    QWizard
+*/
 # define QT_NO_WIZARD
 #endif
 
-#if defined(QT_NO_DIALOGS) || defined(QT_NO_LISTVIEW) || defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR) || defined(QT_NO_MESSAGEBOX)
+#if defined(QT_NO_DIALOG) || defined(QT_NO_LISTVIEW) || defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR) || defined(QT_NO_MESSAGEBOX) || defined(QT_NO_SEMIMODAL)
     /*!
 	QFileDialog
     */
 # define QT_NO_FILEDIALOG
 #endif
 
-#if defined(QT_NO_DIALOGS) || defined(QT_NO_FONTDATABASE) || defined(QT_NO_COMBOBOX)
+#if defined(QT_NO_DIALOG) || defined(QT_NO_FONTDATABASE) || defined(QT_NO_COMBOBOX)
     /*!
 	QFontDialog
     */
 # define QT_NO_FONTDIALOG
 #endif
 
-#if defined(QT_NO_DIALOGS) || defined(QT_NO_LISTVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR)
+#if defined(QT_NO_DIALOG) || defined(QT_NO_LISTVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR) || defined(QT_NO_LAYOUT) || defined(QT_NO_LABEL)
     /*!
 	QPrintDialog
     */
 # define QT_NO_PRINTDIALOG
 #endif
 
-#if defined(QT_NO_DIALOGS) || defined(QT_NO_SEMIMODAL)
+#if defined(QT_NO_SEMIMODAL)
     /*!
 	QProgressDialog
     */
 # define QT_NO_PROGRESSDIALOG
 #endif
-#if defined(QT_NO_DIALOGS) || defined(QT_NO_COMBOBOX)
+#if defined(QT_NO_DIALOG) || defined(QT_NO_COMBOBOX)
     /*!
 	QInputDialog
     */
@@ -660,12 +947,10 @@
 #endif
 
 #if defined(QT_NO_STRINGLIST)
-    // Desktop features
-    /*! Session management support */
+    /*!
+	Session management support
+    */
 # define QT_NO_SESSIONMANAGER
 #endif
 
-/*! Special widget effects (fading, scrolling) */
-//#define QT_NO_EFFECTS
-
 #endif // QFEATURES_H
diff --git a/qtools/qfile_unix.cpp b/qtools/qfile_unix.cpp
index 5c27988..e074eed 100644
--- a/qtools/qfile_unix.cpp
+++ b/qtools/qfile_unix.cpp
@@ -236,7 +236,7 @@ bool QFile::open( int m )
 	} else {
 	    length = (int)st.st_size;
 	    ioIndex  = (flags() & IO_Append) == 0 ? 0 : length;
-	    if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+	    if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
 		// try if you can read from it (if you can, it's a sequential
 		// device; e.g. a file in the /proc filesystem)
 		int c = getch();
@@ -300,13 +300,13 @@ bool QFile::open( int m, FILE *f )
     STATBUF st;
     FSTAT( FILENO(fh), &st );
     ioIndex = (int)ftell( fh );
-    if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+    if ( (st.st_mode & STAT_MASK) != STAT_REG || f == stdin ) { //stdin is non seekable
 	// non-seekable
 	setType( IO_Sequential );
 	length = INT_MAX;
     } else {
 	length = (int)st.st_size;
-	if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+	if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
 	    // try if you can read from it (if you can, it's a sequential
 	    // device; e.g. a file in the /proc filesystem)
 	    int c = getch();
@@ -350,7 +350,7 @@ bool QFile::open( int m, int f )
     STATBUF st;
     FSTAT( fd, &st );
     ioIndex  = (int)LSEEK(fd, 0, SEEK_CUR);
-    if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+    if ( (st.st_mode & STAT_MASK) != STAT_REG || f == 0 ) { // stdin is not seekable...
 	// non-seekable
 	setType( IO_Sequential );
 	length = INT_MAX;
@@ -365,6 +365,7 @@ bool QFile::open( int m, int f )
 		setType( IO_Sequential );
 		length = INT_MAX;
 	    }
+	    resetStatus();
 	}
     }
     return TRUE;
@@ -466,18 +467,31 @@ int QFile::readBlock( char *p, uint len )
 	return -1;
     }
 #endif
-    int nread;					// number of bytes read
-    if ( isRaw() ) {				// raw file
-	nread = READ( fd, p, len );
-	if ( len && nread <= 0 ) {
-	    nread = 0;
-	    setStatus(IO_ReadError);
+    int nread = 0;					// number of bytes read
+    if ( !ungetchBuffer.isEmpty() ) {
+	// need to add these to the returned string.
+	int l = ungetchBuffer.length();
+	while( nread < l ) {
+	    *p = ungetchBuffer[ l - nread - 1 ];
+	    p++;
+	    nread++;
 	}
-    } else {					// buffered file
-	nread = fread( p, 1, len, fh );
-	if ( (uint)nread != len ) {
-	    if ( ferror( fh ) || nread==0 )
+	ungetchBuffer.truncate( l - nread );
+    }
+    
+    if ( nread < (int)len ) {
+	if ( isRaw() ) {				// raw file
+	    nread += READ( fd, p, len-nread );
+	    if ( len && nread <= 0 ) {
+		nread = 0;
 		setStatus(IO_ReadError);
+	    }
+	} else {					// buffered file
+	    nread += fread( p, 1, len-nread, fh );
+	    if ( (uint)nread != len ) {
+		if ( ferror( fh ) || nread==0 )
+		    setStatus(IO_ReadError);
+	    }
 	}
     }
     ioIndex += nread;
diff --git a/qtools/qglobal.h b/qtools/qglobal.h
index 314043a..c58e466 100644
--- a/qtools/qglobal.h
+++ b/qtools/qglobal.h
@@ -39,8 +39,8 @@
 #define QGLOBAL_H
 
 
-#define QT_VERSION	220
-#define QT_VERSION_STR	"2.2.0"
+#define QT_VERSION	222
+#define QT_VERSION_STR	"2.2.2"
 
 
 //
@@ -98,9 +98,6 @@
 #define _OS_RELIANTUNIX_
 #elif defined(linux) || defined(__linux) || defined(__linux__)
 #define _OS_LINUX_
-#if defined(__alpha__) || defined(__alpha)
-#define _OS_ALPHA_LINUX_
-#endif
 #elif defined(__FreeBSD__)
 #define _OS_FREEBSD_
 #elif defined(__NetBSD__)
@@ -153,18 +150,19 @@
 //
 //   SYM	- Symantec C++ for both PC and Macintosh
 //   MPW	- MPW C++
-//   MWERKS	- Metroworks CodeWarrior
+//   MWERKS	- Metrowerks CodeWarrior
 //   MSVC	- Microsoft Visual C/C++
 //   BOR	- Borland/Turbo C++
 //   WAT	- Watcom C++
 //   GNU	- GNU C++
 //   COMEAU	- Comeau C++
 //   EDG	- Edison Design Group C++
-//   OC		- CenterLine ObjectCenter C++
+//   OC		- CenterLine C++
 //   SUN	- Sun C++
 //   DEC	- DEC C++
 //   HP		- HPUX C++
-//   USLC	- SCO UnixWare C++
+//   USLC	- SCO UnixWare7 C++
+//   CDS	- Reliant C++
 //   KAI	- KAI C++
 //
 
@@ -175,6 +173,7 @@
 #define _CC_SYM_
 #elif defined( __KCC )
 #define _CC_KAI_
+#define _CC_EDG_
 #define Q_HAS_BOOL_TYPE
 #elif defined(applec)
 #define _CC_MPW_
@@ -196,6 +195,9 @@
 #define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
 #define Q_SPURIOUS_NON_VOID_WARNING
 #endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 95
+#define Q_DELETING_VOID_UNDEFINED
+#endif
 #if __GNUC__ == 2 && __GNUC_MINOR__ >= 96
 #define Q_DELETING_VOID_UNDEFINED
 #define Q_FP_CCAST_BROKEN
@@ -206,9 +208,17 @@
 #elif defined(__xlC__)
 #define _CC_XLC_
 #define Q_FULL_TEMPLATE_INSTANTIATION
+#if __xlC__ >= 0x400
+#define Q_HAS_BOOL_TYPE
+#endif
+#if __xlC__ <= 0x0306
+#define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
+#endif
 #elif defined(como40)
 #define _CC_EDG_
 #define _CC_COMEAU_
+#define Q_HAS_BOOL_TYPE
+#define Q_C_CALLBACKS
 #elif defined(__USLC__)
 #define _CC_USLC_
 #ifdef __EDG__ // UnixWare7
@@ -216,19 +226,24 @@
 #endif
 #elif defined(__EDG) || defined(__EDG__)
 // one observed on SGI DCC, the other documented
-#define Q_HAS_BOOL_TYPE
 #define _CC_EDG_
 #elif defined(OBJECTCENTER) || defined(CENTERLINE_CLPP)
 #define _CC_OC_
+#if defined(_BOOL)
+#define Q_HAS_BOOL_TYPE
+#endif
 #elif defined(__SUNPRO_CC)
 #define _CC_SUN_
 #if __SUNPRO_CC >= 0x500
 #define Q_HAS_BOOL_TYPE
-#define Q_SPARCWORKS_FUNCP_BUG
+#define Q_FP_CCAST_BROKEN
 #define Q_C_CALLBACKS
 #endif
 #elif defined(__DECCXX)
 #define _CC_DEC_
+#if __DECCXX_VER >= 60060005
+#define Q_HAS_BOOL_TYPE
+#endif
 #elif defined(__CDS__)
 #define _CC_CDS_
 #define Q_HAS_BOOL_TYPE
@@ -248,10 +263,6 @@
 #error "Qt has not been tested with this compiler - talk to qt-bugs@trolltech.com"
 #endif
 
-#if defined(_CC_COMEAU_)
-#define Q_C_CALLBACKS
-#endif
-
 #ifndef Q_PACKED
 #define Q_PACKED
 #endif
@@ -302,13 +313,7 @@
 #define Q_HAS_BOOL_TYPE
 #elif _MSC_VER >= 1100 || __BORLANDC__ >= 0x500
 #define Q_HAS_BOOL_TYPE
-#elif defined(_CC_COMEAU_)
-#define Q_HAS_BOOL_TYPE
-#elif defined(sgi) && ( (_COMPILER_VERSION >= 710) || defined(_BOOL) )
-#define Q_HAS_BOOL_TYPE
-#elif defined(__DECCXX) && (__DECCXX_VER >= 60060005)
-#define Q_HAS_BOOL_TYPE
-#elif defined(_AIX) && (__xlC__ >= 0x500)
+#elif defined(sgi) && defined(_BOOL)
 #define Q_HAS_BOOL_TYPE
 #endif
 
@@ -478,6 +483,8 @@ Q_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian );
 #pragma warning(disable: 4275)
 #pragma warning(disable: 4514)
 #pragma warning(disable: 4800)
+#pragma warning(disable: 4097)
+#pragma warning(disable: 4706)
 #elif defined(_CC_BOR_)
 #pragma option -w-inl
 #pragma option -w-aus
diff --git a/qtools/qiodevice.cpp b/qtools/qiodevice.cpp
index b2a6751..43b2787 100644
--- a/qtools/qiodevice.cpp
+++ b/qtools/qiodevice.cpp
@@ -425,8 +425,10 @@ void QIODevice::setStatus( int s )
   <li>\c IO_Append sets the file index to the end of the file.
   <li>\c IO_Truncate truncates the file.
   <li>\c IO_Translate enables carriage returns and linefeed translation
-  for text files under MS-DOS, Window, OS/2 and Macintosh.  Cannot be
-  combined with \c IO_Raw.
+  for text files under MS-DOS, Window, OS/2 and Macintosh.  On Unix systems 
+  this flag has no effect. Use with caution as it will also transform every linefeed
+  written to the file into a CRLF pair. This is likely to corrupt your file when
+  writing binary data to it. Cannot be combined with \c IO_Raw.
   </ul>
 
   This virtual function must be reimplemented by all subclasses.
diff --git a/qtools/qlist.h b/qtools/qlist.h
index 678e92d..a4608fb 100644
--- a/qtools/qlist.h
+++ b/qtools/qlist.h
@@ -105,7 +105,6 @@ template<class type> inline void QList<type>::deleteItem( QCollection::Item d )
 }
 
 
-
 template<class type> class Q_EXPORT QListIterator : public QGListIterator
 {
 public:
diff --git a/qtools/qmap.cpp b/qtools/qmap.cpp
new file mode 100644
index 0000000..1d2510a
--- /dev/null
+++ b/qtools/qmap.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+** 
+**
+** Implementation of QMap
+**
+** Created : 990406
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qmap.h"
+
+typedef QMapNodeBase* NodePtr;
+typedef QMapNodeBase Node;
+
+
+void QMapPrivateBase::rotateLeft( NodePtr x, NodePtr& root)
+{
+    NodePtr y = x->right;
+    x->right = y->left;
+    if (y->left !=0)
+	y->left->parent = x;
+    y->parent = x->parent;
+    if (x == root)
+	root = y;
+    else if (x == x->parent->left)
+	x->parent->left = y;
+    else
+	x->parent->right = y;
+    y->left = x;
+    x->parent = y;
+}
+
+
+void QMapPrivateBase::rotateRight( NodePtr x, NodePtr& root )
+{
+    NodePtr y = x->left;
+    x->left = y->right;
+    if (y->right != 0)
+	y->right->parent = x;
+    y->parent = x->parent;
+    if (x == root)
+	root = y;
+    else if (x == x->parent->right)
+	x->parent->right = y;
+    else
+	x->parent->left = y;
+    y->right = x;
+    x->parent = y;
+}
+
+
+void QMapPrivateBase::rebalance( NodePtr x, NodePtr& root)
+{
+    x->color = Node::Red;
+    while ( x != root && x->parent->color == Node::Red ) {
+	if ( x->parent == x->parent->parent->left ) {
+	    NodePtr y = x->parent->parent->right;
+	    if (y && y->color == Node::Red) {
+		x->parent->color = Node::Black;
+		y->color = Node::Black;
+		x->parent->parent->color = Node::Red;
+		x = x->parent->parent;
+	    } else {
+		if (x == x->parent->right) {
+		    x = x->parent;
+		    rotateLeft( x, root );
+		}
+		x->parent->color = Node::Black;
+		x->parent->parent->color = Node::Red;
+		rotateRight (x->parent->parent, root );
+	    }
+	} else {
+	    NodePtr y = x->parent->parent->left;
+	    if ( y && y->color == Node::Red ) {
+		x->parent->color = Node::Black;
+		y->color = Node::Black;
+		x->parent->parent->color = Node::Red;
+		x = x->parent->parent;
+	    } else {
+		if (x == x->parent->left) { 
+		    x = x->parent;
+		    rotateRight( x, root );
+		}
+		x->parent->color = Node::Black;
+		x->parent->parent->color = Node::Red;
+		rotateLeft( x->parent->parent, root );
+	    }
+	}
+    }
+    root->color = Node::Black;
+}
+
+
+NodePtr QMapPrivateBase::removeAndRebalance( NodePtr z, NodePtr& root,
+					     NodePtr& leftmost,
+					     NodePtr& rightmost )
+{
+    NodePtr y = z;
+    NodePtr x;
+    NodePtr x_parent;
+    if (y->left == 0) {
+	x = y->right;
+    } else {
+	if (y->right == 0)
+	    x = y->left;
+	else
+	    {
+		y = y->right;
+		while (y->left != 0)
+		    y = y->left;
+		x = y->right;
+	    }
+    }
+    if (y != z) {
+	z->left->parent = y; 
+	y->left = z->left;
+	if (y != z->right) {
+	    x_parent = y->parent;
+	    if (x)
+		x->parent = y->parent;
+	    y->parent->left = x;
+	    y->right = z->right;
+	    z->right->parent = y;
+	} else {
+	    x_parent = y;  
+	}
+	if (root == z)
+	    root = y;
+	else if (z->parent->left == z)
+	    z->parent->left = y;
+	else 
+	    z->parent->right = y;
+	y->parent = z->parent;
+	// Swap the colors
+	Node::Color c = y->color;
+	y->color = z->color;
+	z->color = c;
+	y = z;
+    } else {       
+	x_parent = y->parent;
+	if (x)
+	    x->parent = y->parent;   
+	if (root == z)
+	    root = x;
+	else if (z->parent->left == z)
+	    z->parent->left = x;
+	else
+	    z->parent->right = x;
+	if ( leftmost == z ) {
+	    if (z->right == 0)
+		leftmost = z->parent;
+	    else
+		leftmost = x->minimum();
+	}
+	if (rightmost == z) {
+	    if (z->left == 0)
+		rightmost = z->parent;  
+	    else
+		rightmost = x->maximum();
+	}
+    }
+    if (y->color != Node::Red) { 
+	while (x != root && (x == 0 || x->color == Node::Black)) {
+	    if (x == x_parent->left) {
+		NodePtr w = x_parent->right;
+		if (w->color == Node::Red) {
+		    w->color = Node::Black;
+		    x_parent->color = Node::Red;
+		    rotateLeft(x_parent, root);
+		    w = x_parent->right;
+		}
+		if ((w->left == 0 || w->left->color == Node::Black) &&
+		    (w->right == 0 || w->right->color == Node::Black)) {
+		    w->color = Node::Red;
+		    x = x_parent;
+		    x_parent = x_parent->parent;
+		} else {
+		    if (w->right == 0 || w->right->color == Node::Black) {
+			if (w->left)
+			    w->left->color = Node::Black;
+			w->color = Node::Red;
+			rotateRight(w, root);
+			w = x_parent->right;
+		    }
+		    w->color = x_parent->color;
+		    x_parent->color = Node::Black;
+		    if (w->right)
+			w->right->color = Node::Black;
+		    rotateLeft(x_parent, root);
+		    break;
+		}
+	    } else {
+		NodePtr w = x_parent->left;
+		if (w->color == Node::Red) {
+		    w->color = Node::Black;
+		    x_parent->color = Node::Red;
+		    rotateRight(x_parent, root);
+		    w = x_parent->left;
+		}
+		if ((w->right == 0 || w->right->color == Node::Black) &&
+		    (w->left == 0 || w->left->color == Node::Black)) {
+		    w->color = Node::Red;
+		    x = x_parent;
+		    x_parent = x_parent->parent;
+		} else {
+		    if (w->left == 0 || w->left->color == Node::Black) {
+			if (w->right) 
+			    w->right->color = Node::Black;
+			w->color = Node::Red;
+			rotateLeft(w, root);
+			w = x_parent->left;
+		    }
+		    w->color = x_parent->color;
+		    x_parent->color = Node::Black;
+		    if (w->left)
+			w->left->color = Node::Black;
+		    rotateRight(x_parent, root);
+		    break;
+		}
+	    }
+	}
+	if (x)
+	    x->color = Node::Black;
+    }
+    return y;
+}
diff --git a/qtools/qmap.h b/qtools/qmap.h
new file mode 100644
index 0000000..f384a3d
--- /dev/null
+++ b/qtools/qmap.h
@@ -0,0 +1,606 @@
+/****************************************************************************
+** 
+**
+** Definition of QMap class
+**
+** Created : 990406
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QMAP_H
+#define QMAP_H
+
+#ifndef QT_H
+#include "qshared.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+
+struct QMapNodeBase
+{
+    enum Color { Red, Black };
+
+    QMapNodeBase* left;
+    QMapNodeBase* right;
+    QMapNodeBase* parent;
+
+    Color color;
+
+    QMapNodeBase* minimum() {
+	QMapNodeBase* x = this;
+	while ( x->left )
+	    x = x->left;
+	return x;
+    }
+
+    QMapNodeBase* maximum() {
+	QMapNodeBase* x = this;
+	while ( x->right )
+	    x = x->right;
+	return x;
+    }
+};
+
+
+template <class K, class T>
+struct QMapNode : public QMapNodeBase
+{
+    QMapNode( const K& _key, const T& _data ) { data = _data; key = _key; }
+    QMapNode( const K& _key )	   { key = _key; }
+    QMapNode( const QMapNode<K,T>& _n ) { key = _n.key; data = _n.data; }
+    QMapNode() { }
+    T data;
+    K key;
+};
+
+
+template<class K, class T>
+class Q_EXPORT QMapIterator
+{
+ public:
+    /**
+     * Typedefs
+     */
+    typedef QMapNode< K, T >* NodePtr;
+
+    /**
+     * Variables
+     */
+    QMapNode<K,T>* node;
+
+    /**
+     * Functions
+     */
+    QMapIterator() : node( 0 ) {}
+    QMapIterator( QMapNode<K,T>* p ) : node( p ) {}
+    QMapIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
+
+    bool operator==( const QMapIterator<K,T>& it ) const { return node == it.node; }
+    bool operator!=( const QMapIterator<K,T>& it ) const { return node != it.node; }
+    T& operator*() { return node->data; }
+    const T& operator*() const { return node->data; }
+
+    // Cannot have this - some compilers are too stupid
+    //T* operator->() const { return &(node->data); }
+
+    const K& key() const { return node->key; }
+    T& data() { return node->data; }
+    const T& data() const { return node->data; }
+
+private:
+    int inc() {
+	QMapNodeBase* tmp = node;
+	if ( tmp->right ) {
+	    tmp = tmp->right;
+	    while ( tmp->left )
+		tmp = tmp->left;
+	} else {
+	    QMapNodeBase* y = tmp->parent;
+	    while (tmp == y->right) {
+		tmp = y;
+		y = y->parent;
+	    }
+	    if (tmp->right != y)
+		tmp = y;
+	}
+	node = (NodePtr)tmp;
+	return 0;
+    }
+
+    int dec() {
+	QMapNodeBase* tmp = node;
+	if (tmp->color == QMapNodeBase::Red &&
+	    tmp->parent->parent == tmp ) {
+	    tmp = tmp->right;
+	} else if (tmp->left != 0) {
+	    QMapNodeBase* y = tmp->left;
+	    while ( y->right )
+		y = y->right;
+	    tmp = y;
+	} else {
+	    QMapNodeBase* y = tmp->parent;
+	    while (tmp == y->left) {
+		tmp = y;
+		y = y->parent;
+	    }
+	    tmp = y;
+	}
+	node = (NodePtr)tmp;
+	return 0;
+    }
+
+public:
+    QMapIterator<K,T>& operator++() {
+	inc();
+	return *this;
+    }
+
+    QMapIterator<K,T> operator++(int) {
+	QMapIterator<K,T> tmp = *this;
+	inc();
+	return tmp;
+    }
+
+    QMapIterator<K,T>& operator--() {
+	dec();
+	return *this;
+    }
+
+    QMapIterator<K,T> operator--(int) {
+	QMapIterator<K,T> tmp = *this;
+	dec();
+	return tmp;
+    }
+};
+
+template<class K, class T>
+class Q_EXPORT QMapConstIterator
+{
+ public:
+    /**
+     * Typedefs
+     */
+    typedef QMapNode< K, T >* NodePtr;
+
+    /**
+     * Variables
+     */
+    QMapNode<K,T>* node;
+
+    /**
+     * Functions
+     */
+    QMapConstIterator() : node( 0 ) {}
+    QMapConstIterator( QMapNode<K,T>* p ) : node( p ) {}
+    QMapConstIterator( const QMapConstIterator<K,T>& it ) : node( it.node ) {}
+    QMapConstIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
+
+    bool operator==( const QMapConstIterator<K,T>& it ) const { return node == it.node; }
+    bool operator!=( const QMapConstIterator<K,T>& it ) const { return node != it.node; }
+    const T& operator*()  const { return node->data; }
+
+    // Cannot have this - some compilers are too stupid
+    //const T* operator->() const { return &(node->data); }
+
+    const K& key() const { return node->key; }
+    const T& data() const { return node->data; }
+
+private:
+    int inc() {
+        QMapNodeBase* tmp = node;
+	if ( tmp->right ) {
+	    tmp = tmp->right;
+	    while ( tmp->left )
+		tmp = tmp->left;
+	} else {
+	    QMapNodeBase* y = tmp->parent;
+	    while (tmp == y->right) {
+		tmp = y;
+		y = y->parent;
+	    }
+	    if (tmp->right != y)
+		tmp = y;
+	}
+	node = (NodePtr)tmp;
+	return 0;
+    }
+
+    int dec() {
+	QMapNodeBase* tmp = node;
+	if (tmp->color == QMapNodeBase::Red &&
+	    tmp->parent->parent == tmp ) {
+	    tmp = tmp->right;
+	} else if (tmp->left != 0) {
+	    QMapNodeBase* y = tmp->left;
+	    while ( y->right )
+		y = y->right;
+	    tmp = y;
+	} else {
+	    QMapNodeBase* y = tmp->parent;
+	    while (tmp == y->left) {
+		tmp = y;
+		y = y->parent;
+	    }
+	    tmp = y;
+	}
+	node = (NodePtr)tmp;
+	return 0;
+    }
+
+public:
+    QMapConstIterator<K,T>& operator++() {
+	inc();
+	return *this;
+    }
+
+    QMapConstIterator<K,T> operator++(int) {
+	QMapConstIterator<K,T> tmp = *this;
+	inc();
+	return tmp;
+    }
+
+    QMapConstIterator<K,T>& operator--() {
+	dec();
+	return *this;
+    }
+
+    QMapConstIterator<K,T> operator--(int) {
+	QMapConstIterator<K,T> tmp = *this;
+	dec();
+	return tmp;
+    }
+};
+
+
+class Q_EXPORT QMapPrivateBase : public QShared
+{
+public:
+    QMapPrivateBase() {
+	node_count = 0;
+    }
+    QMapPrivateBase( const QMapPrivateBase* _map) {
+	node_count = _map->node_count;
+    }
+
+    /**
+     * Implementations of basic tree algorithms
+     */
+    void rotateLeft( QMapNodeBase* x, QMapNodeBase*& root);
+    void rotateRight( QMapNodeBase* x, QMapNodeBase*& root );
+    void rebalance( QMapNodeBase* x, QMapNodeBase*& root );
+    QMapNodeBase* removeAndRebalance( QMapNodeBase* z, QMapNodeBase*& root,
+				      QMapNodeBase*& leftmost,
+				      QMapNodeBase*& rightmost );
+
+    /**
+     * Variables
+     */
+    int node_count;
+};
+
+
+template <class Key, class T>
+class QMapPrivate : public QMapPrivateBase
+{
+public:
+    /**
+     * Typedefs
+     */
+    typedef QMapIterator< Key, T > Iterator;
+    typedef QMapConstIterator< Key, T > ConstIterator;
+    typedef QMapNode< Key, T > Node;
+    typedef QMapNode< Key, T >* NodePtr;
+
+    /**
+     * Functions
+     */
+    QMapPrivate() {
+	header = new Node;
+	header->color = QMapNodeBase::Red; // Mark the header
+	header->parent = 0;
+	header->left = header->right = header;
+    }
+    QMapPrivate( const QMapPrivate< Key, T >* _map ) : QMapPrivateBase( _map ) {
+	header = new Node;
+	header->color = QMapNodeBase::Red; // Mark the header
+	if ( _map->header->parent == 0 ) {
+	    header->parent = 0;
+	    header->left = header->right = header;
+	} else {
+	    header->parent = copy( (NodePtr)(_map->header->parent) );
+	    header->parent->parent = header;
+	    header->left = header->parent->minimum();
+	    header->right = header->parent->maximum();
+	}
+    }
+    ~QMapPrivate() { clear(); delete header; }
+
+    NodePtr copy( NodePtr p ) {
+	if ( !p )
+	    return 0;
+	NodePtr n = new Node( *p );
+	n->color = p->color;
+	if ( p->left ) {
+	    n->left = copy( (NodePtr)(p->left) );
+	    n->left->parent = n;
+	} else {
+	    n->left = 0;
+	}
+	if ( p->right ) {
+	    n->right = copy( (NodePtr)(p->right) );
+	    n->right->parent = n;
+	} else {
+	    n->right = 0;
+	}
+	return n;
+    }
+
+    void clear() {
+	clear( (NodePtr)(header->parent) );
+	header->color = QMapNodeBase::Red;
+	header->parent = 0;
+	header->left = header->right = header;
+	node_count = 0;
+    }
+
+    void clear( NodePtr p ) {
+	while ( p != 0 ) {
+	    clear( (NodePtr)p->right );
+	    NodePtr y = (NodePtr)p->left;
+	    delete p;
+	    p = y;
+	}
+    }
+
+    Iterator begin()	{ return Iterator( (NodePtr)(header->left ) ); }
+    Iterator end()	{ return Iterator( header ); }
+    ConstIterator begin() const { return ConstIterator( (NodePtr)(header->left ) ); }
+    ConstIterator end() const { return ConstIterator( header ); }
+
+    ConstIterator find(const Key& k) const {
+	QMapNodeBase* y = header;        // Last node
+	QMapNodeBase* x = header->parent; // Root node.
+
+	while ( x != 0 ) {
+	    // If as k <= key(x) go left
+	    if ( !( key(x) < k ) ) {
+		y = x;
+		x = x->left;
+	    } else {
+		x = x->right;
+	    }
+	}
+
+	// Was k bigger/smaller then the biggest/smallest
+	// element of the tree ? Return end()
+	if ( y == header || k < key(y) )
+	    return ConstIterator( header );
+	return ConstIterator( (NodePtr)y );
+    }
+
+    void remove( Iterator it ) {
+	NodePtr del = (NodePtr) removeAndRebalance( it.node, header->parent, header->left, header->right );
+	delete del;
+	--node_count;
+    }
+
+#ifdef QT_QMAP_DEBUG
+    void inorder( QMapNodeBase* x = 0, int level = 0 ){
+	if ( !x )
+	    x = header->parent;
+	if ( x->left )
+	    inorder( x->left, level + 1 );
+    //cout << level << " Key=" << key(x) << " Value=" << ((NodePtr)x)->data << endl;
+	if ( x->right )
+	    inorder( x->right, level + 1 );
+    }
+#endif
+
+    Iterator insertMulti(const Key& v){
+	QMapNodeBase* y = header;
+	QMapNodeBase* x = header->parent;
+	while (x != 0){
+	    y = x;
+	    x = ( v < key(x) ) ? x->left : x->right;
+	}
+	return insert(x, y, v);
+    }
+
+    Iterator insertSingle( const Key& k ) {
+	// Search correct position in the tree
+	QMapNodeBase* y = header;
+	QMapNodeBase* x = header->parent;
+	bool result = TRUE;
+	while ( x != 0 ) {
+	    result = ( k < key(x) );
+	    y = x;
+	    x = result ? x->left : x->right;
+	}
+	// Get iterator on the last not empty one
+	Iterator j( (NodePtr)y );
+	if ( result ) {
+	    // Smaller then the leftmost one ?
+	    if ( j == begin() ) {
+		return insert(x, y, k );
+	    } else {
+		// Perhaps daddy is the right one ?
+		--j;
+	    }
+	}
+	// Really bigger ?
+	if ( (j.node->key) < k )
+	    return insert(x, y, k );
+	// We are going to replace a node
+	return j;
+    }
+
+    Iterator insert( QMapNodeBase* x, QMapNodeBase* y, const Key& k ) {
+	NodePtr z = new Node( k );
+	if (y == header || x != 0 || k < key(y) ) {
+	    y->left = z;                // also makes leftmost = z when y == header
+	    if ( y == header ) {
+		header->parent = z;
+		header->right = z;
+	    } else if ( y == header->left )
+		header->left = z;           // maintain leftmost pointing to min node
+	} else {
+	    y->right = z;
+	    if ( y == header->right )
+		header->right = z;          // maintain rightmost pointing to max node
+	}
+	z->parent = y;
+	z->left = 0;
+	z->right = 0;
+	rebalance( z, header->parent );
+	++node_count;
+	return Iterator(z);
+    }
+
+protected:
+    /**
+     * Helpers
+     */
+    const Key& key( QMapNodeBase* b ) const { return ((NodePtr)b)->key; }
+
+    /**
+     * Variables
+     */
+    NodePtr header;
+};
+
+
+template<class Key, class T>
+class Q_EXPORT QMap
+{
+public:
+    /**
+     * Typedefs
+     */
+    typedef QMapIterator< Key, T > Iterator;
+    typedef QMapConstIterator< Key, T > ConstIterator;
+    typedef T ValueType;
+    typedef QMapPrivate< Key, T > Priv;
+
+    /**
+     * API
+     */
+    QMap() { sh = new QMapPrivate< Key, T >; }
+    QMap( const QMap<Key,T>& m ) { sh = m.sh; sh->ref(); }
+    ~QMap() { if ( sh->deref() ) delete sh; }
+
+    QMap<Key,T>& operator= ( const QMap<Key,T>& m )
+      { m.sh->ref(); if ( sh->deref() ) delete sh; sh = m.sh; return *this; }
+
+    Iterator begin() { detach(); return sh->begin(); }
+    Iterator end() { detach(); return sh->end(); }
+    ConstIterator begin() const { return ((const Priv*)sh)->begin(); }
+    ConstIterator end() const { return ((const Priv*)sh)->end(); }
+
+    Iterator find ( const Key& k )
+	{ detach(); return Iterator( sh->find( k ).node ); }
+    ConstIterator find ( const Key& k ) const
+	{ return sh->find( k ); }
+    T& operator[] ( const Key& k ) {
+	detach(); QMapNode<Key,T>* p = sh->find( k ).node;
+	if ( p != sh->end().node ) return p->data;
+	return insert( k, T() ).data(); }
+    const T& operator[] ( const Key& k ) const
+	{ return sh->find( k ).data(); }
+    bool contains ( const Key& k ) const
+	{ return find( k ) != end(); }
+	//{ return sh->find( k ) != ((const Priv*)sh)->end(); }
+
+    uint count() const { return sh->node_count; }
+
+    bool isEmpty() const { return sh->node_count == 0; }
+
+    Iterator insert( const Key& key, const T& value ) {
+        detach();
+        Iterator it = sh->insertSingle( key );
+        it.data() = value;
+        return it;
+    }
+
+    void remove( Iterator it ) { detach(); sh->remove( it ); }
+    void remove( const Key& k ) {
+        detach();
+        Iterator it( sh->find( k ).node );
+        if ( it != end() )
+            sh->remove( it );
+    }
+
+    Iterator replace( const Key& k, const T& v ) {
+	remove( k );
+	return insert( k, v );
+    }
+
+    void clear() { if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new QMapPrivate<Key,T>; } }
+
+#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
+    bool operator==( const QMap<Key,T>& ) const { return FALSE; }
+#endif
+
+protected:
+    /**
+     * Helpers
+     */
+    void detach() { if ( sh->count > 1 ) { sh->deref(); sh = new QMapPrivate<Key,T>( sh ); } }
+
+    Priv* sh;
+};
+
+
+#ifndef QT_NO_DATASTREAM
+template<class Key, class T>
+inline QDataStream& operator>>( QDataStream& s, QMap<Key,T>& m ) {
+    m.clear();
+    Q_UINT32 c;
+    s >> c;
+    for( Q_UINT32 i = 0; i < c; ++i ) {
+	Key k; T t;
+	s >> k >> t;
+	m.insert( k, t );
+    }
+    return s;
+}
+
+
+template<class Key, class T>
+inline QDataStream& operator<<( QDataStream& s, const QMap<Key,T>& m ) {
+    s << (Q_UINT32)m.count();
+    QMapConstIterator<Key,T> it = m.begin();
+    for( ; it != m.end(); ++it )
+	s << it.key() << it.data();
+    return s;
+}
+#endif
+
+#endif // QMAP_H
diff --git a/qtools/qmodules.h b/qtools/qmodules.h
new file mode 100644
index 0000000..08f0baf
--- /dev/null
+++ b/qtools/qmodules.h
@@ -0,0 +1,11 @@
+// These modules are licensed to you
+#define QT_MODULE_TOOLS
+#define QT_MODULE_KERNEL
+#define QT_MODULE_WIDGETS
+#define QT_MODULE_DIALOGS
+#define QT_MODULE_ICONVIEW
+#define QT_MODULE_WORKSPACE
+#define QT_MODULE_NETWORK
+#define QT_MODULE_CANVAS
+#define QT_MODULE_TABLE
+#define QT_MODULE_XML
diff --git a/qtools/qstring.cpp b/qtools/qstring.cpp
index 44d4e6b..85962b2 100644
--- a/qtools/qstring.cpp
+++ b/qtools/qstring.cpp
@@ -367,8 +367,6 @@ __END__
 
 // START OF GENERATED DATA
 
-#ifndef QT_NO_UNICODETABLES
-
 static const Q_UINT8 ui_00[] = {
     10, 10, 10, 10, 10, 10, 10, 10,
     10, 10, 10, 10, 10, 10, 10, 10,
@@ -404,6 +402,8 @@ static const Q_UINT8 ui_00[] = {
     16, 16, 16, 16, 16, 16, 16, 16,
 };
 
+#ifndef QT_NO_UNICODETABLES
+
 static const Q_UINT8 ui_01[] = {
     15, 16, 15, 16, 15, 16, 15, 16,
     15, 16, 15, 16, 15, 16, 15, 16,
@@ -11100,19 +11100,7 @@ QChar::Category QChar::category() const
 #else
 // ### just ASCII
     if ( rw == 0 ) {
-	if ( cl >= '0' && cl <='9' )
-	    return Number_DecimalDigit;
-	if ( cl >= 'a' && cl <='z' )
-	    return Letter_Lowercase;
-	if ( cl >= 'A' && cl <='Z' )
-	    return Letter_Uppercase;
-	if ( cl == ' ' )
-	    return Separator_Space;
-	if ( cl == '\n' )
-	    return Separator_Line;
-	if ( cl < ' ' )
-	    return Other_Control;
-	return Symbol_Other; //#######
+	return (Category)(ui_00[cell()]);
     }
     return Letter_Uppercase; //#######
 #endif
@@ -12241,6 +12229,7 @@ QString::QString( const QChar* unicode, uint length )
 {
     if ( !unicode && !length ) {
 	d = shared_null ? shared_null : makeSharedNull();
+	d->ref();
     } else {
 	QChar* uc = QT_ALLOC_QCHAR_VEC( length );
 	if ( unicode )
@@ -12295,6 +12284,8 @@ void QString::real_detach()
 void QString::deref()
 {
     if ( d->deref() ) {
+	if ( d == shared_null )
+	    shared_null = 0;
 	delete d;
 	d = 0; // helps debugging
     }
@@ -12749,7 +12740,7 @@ QString &QString::sprintf( const char* cformat, ... )
 		  case 2: ::sprintf( out, in, width, decimals, value ); break;
 		}
 	      } break;
-	      case 'e': case 'E': case 'f': case 'g': {
+	      case 'e': case 'E': case 'f': case 'g': case 'G': {
 		double value = va_arg(ap, double);
 		switch (params) {
 		  case 0: ::sprintf( out, in, value ); break;
@@ -13896,6 +13887,13 @@ ushort QString::toUShort( bool *ok, int base ) const
 /*!
   Returns the string converted to a <code>int</code> value.
 
+  \code
+  QString str("FF");
+  bool ok;
+  int hex = str.toInt( &ok, 16 ); // will return 255, and ok set to TRUE
+  int dec = str.toInt( &ok, 10 ); // will return 0, and ok set to FALSE
+  \endcode
+
   If \a ok is non-null, \a *ok is set to TRUE if there are no
   conceivable errors, and FALSE if the string is not a number at all,
   or if it has trailing garbage.
@@ -14146,8 +14144,8 @@ QString QString::number( uint n, int base )
 }
 
 /*!
-  This static function returns the printed value of \a n, formatted in the \f
-  format with \a prec precision.
+  This static function returns the printed value of \a n, formatted in the
+  \a f format with \a prec precision.
 
   \a f can be 'f', 'F', 'e', 'E', 'g' or 'G', all of which have the
   same meaning as for sprintf().
@@ -14574,6 +14572,7 @@ QString& QString::setUnicode( const QChar *unicode, uint len )
 	if ( d != shared_null ) {		// beware of nullstring being set to nullstring
 	    deref();
 	    d = shared_null ? shared_null : makeSharedNull();
+	    d->ref();
 	}
     } else if ( d->count != 1 || len > d->maxl ||
 	 ( len*4 < d->maxl && d->maxl > 4 ) ) {	// detach, grown or shrink
@@ -14947,8 +14946,10 @@ QDataStream &operator<<( QDataStream &s, const QString &str )
 QDataStream &operator>>( QDataStream &s, QString &str )
 {
 #ifdef QT_QSTRING_UCS_4
+#if defined(_CC_GNU_)
 #warning "operator>> not working properly"
 #endif
+#endif
     if ( s.version() == 1 ) {
 	QCString l;
 	s >> l;
diff --git a/qtools/qstring.h b/qtools/qstring.h
index f955f32..f131446 100644
--- a/qtools/qstring.h
+++ b/qtools/qstring.h
@@ -646,8 +646,11 @@ inline QString::QString() :
 //
 inline QString::~QString()
 {
-    if ( d->deref() )
+    if ( d->deref() ) {
+	if ( d == shared_null )
+	    shared_null = 0;
 	d->deleteSelf();
+    }
 }
 
 inline QString &QString::operator=( QChar c )
diff --git a/qtools/qtextcodec.cpp b/qtools/qtextcodec.cpp
index af43a3a..9f94cb6 100644
--- a/qtools/qtextcodec.cpp
+++ b/qtools/qtextcodec.cpp
@@ -450,6 +450,9 @@ static const char * const iso8859_2locales[] = {
 static const char * const iso8859_3locales[] = {
     "eo", 0 };
 
+static const char * const iso8859_4locales[] = {
+    "ee", "ee_EE", "lt", "lt_LT", "lv", "lv_LV", 0 };
+
 static const char * const iso8859_5locales[] = {
     "bg", "bg_BG", "bulgarian", "mk", "mk_MK",
     "sp", "sp_YU", 0 };
@@ -461,13 +464,19 @@ static const char * const iso8859_7locales[] = {
     "el", "el_GR", "greek", 0 };
 
 static const char * const iso8859_8locales[] = {
-    "hebrew", "iw", "iw_IL", 0 };
+    "hebrew", "he", "he_IL", "iw", "iw_IL", 0 };
 
 static const char * const iso8859_9locales[] = {
     "tr", "tr_TR", "turkish", 0 };
 
 static const char * const iso8859_15locales[] = {
-    "fr", "fi", "french", "finnish", 0 };
+    "fr", "fi", "french", "finnish", "et", "et_EE", 0 };
+
+static const char * const koi8_ulocales[] = {
+    "uk", "uk_UA", "ru_UA", "ukrainian", 0 };
+
+static const char * const tis_620locales[] = {
+    "th", "th_TH", "thai", 0 };
 
 
 static bool try_locale_list( const char * const locale[], const char * lang )
@@ -523,6 +532,11 @@ static QTextCodec * ru_RU_hack( const char * i ) {
 
 static QTextCodec * localeMapper = 0;
 
+void qt_set_locale_codec( QTextCodec *codec )
+{
+    localeMapper = codec;
+}
+
 /*!  Returns a pointer to the codec most suitable for this locale. */
 
 QTextCodec* QTextCodec::codecForLocale()
@@ -572,19 +586,25 @@ QTextCodec* QTextCodec::codecForLocale()
             localeMapper = codecForName( "ISO 8859-2" );
         else if ( try_locale_list( iso8859_3locales, lang ) )
             localeMapper = codecForName( "ISO 8859-3" );
+        else if ( try_locale_list( iso8859_4locales, lang ) )
+            localeMapper = codecForName( "ISO 8859-4" );
         else if ( try_locale_list( iso8859_5locales, lang ) )
             localeMapper = codecForName( "ISO 8859-5" );
         else if ( try_locale_list( iso8859_6locales, lang ) )
-            localeMapper = codecForName( "ISO 8859-6" );
+            localeMapper = codecForName( "ISO 8859-6-I" );
         else if ( try_locale_list( iso8859_7locales, lang ) )
             localeMapper = codecForName( "ISO 8859-7" );
         else if ( try_locale_list( iso8859_8locales, lang ) )
-            localeMapper = codecForName( "ISO 8859-8" );
+            localeMapper = codecForName( "ISO 8859-8-I" );
         else if ( try_locale_list( iso8859_9locales, lang ) )
             localeMapper = codecForName( "ISO 8859-9" );
         else if ( try_locale_list( iso8859_15locales, lang ) )
             localeMapper = codecForName( "ISO 8859-15" );
-        else if ( try_locale_list( probably_koi8_rlocales, lang ) )
+        else if ( try_locale_list( tis_620locales, lang ) )
+            localeMapper = codecForName( "ISO 8859-11" );
+        else if ( try_locale_list( koi8_ulocales, lang ) )
+            localeMapper = codecForName( "KOI8-U" );
+         else if ( try_locale_list( probably_koi8_rlocales, lang ) )
             localeMapper = ru_RU_hack( lang );
         else if (!lang || !(localeMapper = codecForName(lang) ))
             localeMapper = codecForName( "ISO 8859-1" );
@@ -1335,6 +1355,25 @@ static struct {
     // /**/  - The BULLET OPERATOR is confused.  Some people think
     //          it should be 0x2022 (BULLET).
 
+    // from RFC 2319, ftp://ftp.isi.edu/in-notes/rfc2319.txt
+    { "KOI8-U", 2088,
+      { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
+	0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
+	0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
+	0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
+	0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
+	0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E,
+	0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
+	0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 0x256C, 0x00A9,
+	0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+	0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
+	0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+	0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
+	0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+	0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
+	0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+	0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A } },
+
     // next bits generated from tables on the Unicode 2.0 CD.  we can
     // use these tables since this is part of the transition to using
     // unicode everywhere in qt.
@@ -1342,23 +1381,6 @@ static struct {
     // $ for A in 8 9 A B C D E F ; do for B in 0 1 2 3 4 5 6 7 8 9 A B C D E F ; do echo 0x${A}${B} 0xFFFD ; done ; done > /tmp/digits ; for a in 8859-* ; do ( awk '/^0x[89ABCDEF]/{ print $1, $2 }' < $a ; cat /tmp/digits ) | sort | uniq -w4 | cut -c6- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/$a ; done
 
     // then I inserted the files manually.
-    { "ISO 8859-1", 4,
-        { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
-              0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
-              0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
-              0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
-              0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
-              0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
-              0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
-              0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
-              0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
-              0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
-              0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
-              0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
-              0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
-              0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
-              0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
-              0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} },
     { "ISO 8859-2", 5,
         { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
               0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
@@ -1512,7 +1534,7 @@ static struct {
               0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
               0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169,
               0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138} },
-    { "ISO 8859-13", 0, // ############# what is the mib?
+    { "ISO 8859-13", 109,
         { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
               0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
               0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -1529,7 +1551,7 @@ static struct {
               0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
               0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
               0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019} },
-    { "ISO 8859-14", 0, // ############# what is the mib?
+    { "ISO 8859-14", 110,
         { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
               0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
               0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -1546,7 +1568,7 @@ static struct {
               0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
               0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B,
               0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF} },
-    { "ISO 8859-15", 0, // ############# what is the mib?
+    { "ISO 8859-15", 111,
         { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
               0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
               0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -1762,6 +1784,8 @@ static struct {
               0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
               0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
 
+    // change LAST_MIB if you add more, and edit unicodevalues in
+    // kernel/qpsprinter.cpp too.
 };
 
 
@@ -1787,13 +1811,21 @@ QSimpleTextCodec::~QSimpleTextCodec()
 // what happens if strlen(chars)<len?  what happens if !chars?  if len<1?
 QString QSimpleTextCodec::toUnicode(const char* chars, int len) const
 {
+    if(len <= 0)
+        return QString::null;
+
+    int clen = qstrlen(chars);
+    len = QMIN(len, clen); // Note: NUL ends string
+
     QString r;
+    r.setUnicode(0, len);
+    QChar* uc = (QChar*)r.unicode(); // const_cast
     const unsigned char * c = (const unsigned char *)chars;
-    for( int i=0; i<len && c[i]; i++ ) { // Note: NUL ends string
+    for( int i=0; i<len; i++ ) {
         if ( c[i] > 127 )
-            r[i] = unicodevalues[forwardIndex].values[c[i]-128];
+            uc[i] = unicodevalues[forwardIndex].values[c[i]-128];
         else
-            r[i] = c[i];
+            uc[i] = c[i];
     }
     return r;
 }
@@ -1829,12 +1861,17 @@ QCString QSimpleTextCodec::fromUnicode(const QString& uc, int& len ) const
     if ( len <0 || len > (int)uc.length() )
         len = uc.length();
     QCString r( len+1 );
-    int i;
+    int i = len;
     int u;
-    for( i=0; i<len; i++ ) {
-        u = uc[i].cell() + 256* uc[i].row();
-        r[i] = u < 128 ? u : (
-            ( u < (int)reverseMap->size() ) ? (*reverseMap)[u] :  '?' );
+    const QChar* ucp = uc.unicode();
+    char* rp = r.data();
+    char* rmp = reverseMap->data();
+    int rmsize = (int) reverseMap->size();
+    while( i-- )
+    {
+        u = ucp->unicode();
+        *rp++ = u < 128 ? u : (( u < rmsize ) ? (*(rmp+u)) : '?' );
+        ucp++;
     }
     r[len] = 0;
     return r;
@@ -1862,7 +1899,9 @@ int QSimpleTextCodec::heuristicNameMatch(const char* hint) const
             return QTextCodec::heuristicNameMatch("koi8-r")-1;
     } else if ( hint[0] == 't' && QCString(name()) == "ISO 8859-11" ) {
 	// 8859-11 and tis620 are byte by bute equivalent
-	int i = simpleHeuristicNameMatch("tis-620", hint);
+	int i = simpleHeuristicNameMatch("tis620-0", hint);
+	if( !i )
+	    i = simpleHeuristicNameMatch("tis-620", hint);
 	if( i ) return i;
     }
     return QTextCodec::heuristicNameMatch(hint);
@@ -1892,27 +1931,7 @@ int QSimpleTextCodec::heuristicContentMatch(const char* chars, int len) const
 }
 
 
-static void setupBuiltinCodecs()
-{
-    int i = 0;
-    do {
-        (void)new QSimpleTextCodec( i );
-    } while( unicodevalues[i++].mib != LAST_MIB );
-
-    (void)new QEucJpCodec;
-    (void)new QSjisCodec;
-    (void)new QJisCodec;
-    (void)new QEucKrCodec;
-    (void)new QGbkCodec;
-    (void)new QBig5Codec;
-    (void)new QUtf8Codec;
-    (void)new QUtf16Codec;
-    (void)new QHebrewCodec;
-    (void)new QArabicCodec;
-    (void)new QTsciiCodec;
-}
-
-#else
+#endif // QT_NO_CODECS
 
 class QLatin1Codec: public QTextCodec
 {
@@ -1948,12 +1967,10 @@ QLatin1Codec::~QLatin1Codec()
 // what happens if strlen(chars)<len?  what happens if !chars?  if len<1?
 QString QLatin1Codec::toUnicode(const char* chars, int len) const
 {
-    QString r;
-    const unsigned char * c = (const unsigned char *)chars;
-    for( int i=0; i<len && c[i]; i++ ) { // Note: NUL ends string
-            r[i] = c[i];
-    }
-    return r;
+    if(len <= 0)
+        return QString::null;
+
+    return QString::fromLatin1(chars, len);
 }
 
 
@@ -1962,11 +1979,12 @@ QCString QLatin1Codec::fromUnicode(const QString& uc, int& len ) const
     if ( len <0 || len > (int)uc.length() )
         len = uc.length();
     QCString r( len+1 );
-    int i;
-    int u;
-    for( i=0; i<len; i++ ) {
-        u = uc[i].cell() + 256* uc[i].row();
-        r[i] = u < 255 ? u : '?';
+    int i = 0;
+    const QChar *ch = uc.unicode();
+    while ( i < len ) {
+	r[i] = ch->row() ? '?' : ch->cell();
+	i++;
+	ch++;
     }
     r[len] = 0;
     return r;
@@ -1975,7 +1993,7 @@ QCString QLatin1Codec::fromUnicode(const QString& uc, int& len ) const
 
 const char* QLatin1Codec::name() const
 {
-    return "iso8859-1";
+    return "ISO 8859-1";
 }
 
 
@@ -2009,11 +2027,28 @@ int QLatin1Codec::heuristicContentMatch(const char* chars, int len) const
 }
 
 
-
 static void setupBuiltinCodecs()
 {
     (void)new QLatin1Codec;
-}
+
+#ifndef QT_NO_CODECS
+    int i = 0;
+    do {
+        (void)new QSimpleTextCodec( i );
+    } while( unicodevalues[i++].mib != LAST_MIB );
+
+    (void)new QEucJpCodec;
+    (void)new QSjisCodec;
+    (void)new QJisCodec;
+    (void)new QEucKrCodec;
+    (void)new QGbkCodec;
+    (void)new QBig5Codec;
+    (void)new QUtf8Codec;
+    (void)new QUtf16Codec;
+    (void)new QHebrewCodec;
+    (void)new QArabicCodec;
+    (void)new QTsciiCodec;
 #endif // QT_NO_CODECS
+}
 
 #endif // QT_NO_TEXTCODEC
diff --git a/qtools/qtextstream.cpp b/qtools/qtextstream.cpp
index 774b730..6686f81 100644
--- a/qtools/qtextstream.cpp
+++ b/qtools/qtextstream.cpp
@@ -193,10 +193,14 @@ const int QTextStream::floatfield  = ( QTextStream::scientific |
 
 class QTextStreamPrivate {
 public:
-    QTextStreamPrivate(): decoder( 0 ), sourceType( NotSet ) {}
+#ifndef QT_NO_TEXTCODEC
+    QTextStreamPrivate() : decoder( 0 ), sourceType( NotSet ) {}
     ~QTextStreamPrivate() { delete decoder; }
-
     QTextDecoder *decoder;		//???
+#else
+    QTextStreamPrivate() : sourceType( NotSet ) {}
+    ~QTextStreamPrivate() { }
+#endif
     QString ungetcBuf;
 
     enum SourceType { NotSet, IODevice, String, ByteArray, File };
@@ -664,14 +668,41 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
 	}
     }
 
+#ifndef QT_NO_TEXTCODEC
     if ( mapper ) {
+	bool shortRead = FALSE;
 	if ( !d->decoder )
 	    d->decoder = mapper->makeDecoder();
 	while( rnum < len ) {
 	    QString s;
-	    while ( s.isEmpty() ) {
-		// TODO: can this getch() call be optimized to read
-		// more than one character after another?  YES!
+	    bool readBlock = !( len == 1+rnum );
+	    while ( TRUE ) {
+		// for efficiency: normally read a whole block
+		if ( readBlock ) {
+		    // guess buffersize; this may be wrong (too small or too
+		    // big). But we can handle this (either iterate reading
+		    // or use ungetcBuf).
+		    // Note that this might cause problems for codecs where
+		    // one byte can result in >1 Unicode Characters if bytes
+		    // are written to the stream in the meantime (loss of
+		    // synchronicity).
+		    uint rlen = len - rnum;
+		    char *cbuf = new char[ rlen ];
+		    if ( ungetHack != EOF ) {
+			rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+			cbuf[0] = (char)ungetHack;
+			ungetHack = EOF;
+		    } else {
+			rlen = dev->readBlock( cbuf, rlen );
+		    }
+		    s  += d->decoder->toUnicode( cbuf, rlen );
+		    delete[] cbuf;
+		    // use buffered reading only for the first time, because we
+		    // have to get the stream synchronous again (this is easier
+		    // with single character reading)
+		    readBlock = FALSE;
+		}
+		// get stream (and codec) in sync
 		int c;
 		if ( ungetHack == EOF ) {
 		    c = dev->getch();
@@ -679,10 +710,15 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
 		    c = ungetHack;
 		    ungetHack = EOF;
 		}
-		if ( c == EOF )
-		    return rnum;
+		if ( c == EOF ) {
+		    shortRead = TRUE;
+		    break;
+		}
 		char b = c;
-		s  = d->decoder->toUnicode( &b, 1 );
+		uint lengthBefore = s.length();
+		s  += d->decoder->toUnicode( &b, 1 );
+		if ( s.length() > lengthBefore )
+		    break; // it seems we are in sync now
 	    }
 	    uint i = 0;
 	    while( rnum < len && i < s.length() )
@@ -690,8 +726,12 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
 	    if ( s.length() > i )
 		// could be = but append is clearer
 		d->ungetcBuf.append( s.mid( i ) );
+	    if ( shortRead )
+		return rnum;
 	}
-    } else if ( latin1 ) {
+    } else
+#endif
+    if ( latin1 ) {
 	if ( len == 1+rnum ) {
 	    // use this method for one character because it is more efficient
 	    // (arnt doubts whether it makes a difference, but lets it stand)
@@ -699,14 +739,18 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
 	    if ( c != EOF )
 		buf[rnum++] = (char)c;
 	} else {
-	    if ( (QChar)ungetHack != QEOF )
+	    if ( ungetHack != EOF ) {
 		buf[rnum++] = (char)ungetHack;
-	    uint rlen = len - rnum;
-	    char *cbuf = new char[rlen];
-	    rlen = dev->readBlock( cbuf, rlen );
-	    uint i = 0;
-	    while( i < rlen )
-		buf[rnum++] = cbuf[i++];
+		ungetHack = EOF;
+	    }
+	    char *cbuf = new char[len - rnum];
+	    while ( !dev->atEnd() && rnum < len ) {
+		uint rlen = len - rnum;
+		rlen = dev->readBlock( cbuf, rlen );
+		uint i = 0;
+		while( i < rlen )
+		    buf[rnum++] = cbuf[i++];
+	    }
 	    delete[] cbuf;
 	}
     } else { // UCS-2 or UTF-16
@@ -722,29 +766,34 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
 	    else
 		buf[rnum++] = QChar( c1, c2 );
 	} else {
-	    uint rlen = 2 * ( len-rnum );
-	    char *cbuf = new char[rlen]; // for paranoids: overflow possible
-	    if ( (QChar)ungetHack != QEOF ) {
-		rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
-		cbuf[0] = (char)ungetHack;
-	    } else {
-		rlen = dev->readBlock( cbuf, rlen );
-	    }
-	    // is this right? we can't use an odd number of bytes, but
-	    // if there -is- an odd number, with this code we'll never
-	    // get to EOF.
-	    if ( (rlen & 1) == 1 )
-		dev->ungetch( cbuf[--rlen] );
-	    uint i = 0;
-	    if ( isNetworkOrder() ) {
-		while( i < rlen ) {
-		    buf[rnum++] = QChar( cbuf[i+1], cbuf[i] );
-		    i+=2;
+	    char *cbuf = new char[ 2*( len - rnum ) ]; // for paranoids: overflow possible
+	    while ( !dev->atEnd() && rnum < len ) {
+		uint rlen = 2 * ( len-rnum );
+		if ( ungetHack != EOF ) {
+		    rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+		    cbuf[0] = (char)ungetHack;
+		    ungetHack = EOF;
+		} else {
+		    rlen = dev->readBlock( cbuf, rlen );
 		}
-	    } else {
-		while( i < rlen ) {
-		    buf[rnum++] = QChar( cbuf[i], cbuf[i+1] );
-		    i+=2;
+		// We can't use an odd number of bytes, so put it back. But
+		// do it only if we are capable of reading more -- normally
+		// there should not be an odd number, but the file might be
+		// truncated or not in UTF-16...
+		if ( (rlen & 1) == 1 )
+		    if ( !dev->atEnd() )
+			dev->ungetch( cbuf[--rlen] );
+		uint i = 0;
+		if ( isNetworkOrder() ) {
+		    while( i < rlen ) {
+			buf[rnum++] = QChar( cbuf[i+1], cbuf[i] );
+			i+=2;
+		    }
+		} else {
+		    while( i < rlen ) {
+			buf[rnum++] = QChar( cbuf[i], cbuf[i+1] );
+			i+=2;
+		    }
 		}
 	    }
 	    delete[] cbuf;
@@ -759,12 +808,15 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
 */
 void QTextStream::ts_putc( QChar c )
 {
+#ifndef QT_NO_TEXTCODEC
     if ( mapper ) {
 	int len = 1;
 	QString s = c;
 	QCString block = mapper->fromUnicode( s, len );
 	dev->writeBlock( block, len );
-    } else if ( latin1 ) {
+    } else
+#endif
+    if ( latin1 ) {
 	if( c.row() )
 	    dev->putch( '?' ); //######unknown character???
 	else
@@ -820,7 +872,7 @@ void QTextStream::ts_ungetc( QChar c )
 
   The buffer \e s must be preallocated.
 
-  \note No Encoding is done by this function.
+  Note that no encoding is done by this function.
 
   \warning The behaviour of this function is undefined unless the
   stream's encoding is set to Unicode or Latin1.
@@ -838,7 +890,7 @@ QTextStream &QTextStream::readRawBytes( char *s, uint len )
   Writes the \e len bytes from \e s to the stream and returns a reference to
   the stream.
 
-  \note No Encoding is done by this function.
+  Note that no encoding is done by this function.
 
   \sa QIODevice::writeBlock()
 */
@@ -1428,19 +1480,28 @@ QString QTextStream::readLine()
 	return QString::null;
     }
 #endif
-    QChar c = ts_getc();
-    if ( c == QEOF )
+    QString result( "" );
+    const int buf_size = 256;
+    QChar c[buf_size];
+    int pos = 0;
+
+    c[pos] = ts_getc();
+    if ( c[pos] == QEOF )
 	return QString::null;
 
-    QString result( "" );
-    while ( c != QEOF && c != '\n' ) {
-	result += c;
-	c = ts_getc();
+    while ( c[pos] != QEOF && c[pos] != '\n' ) {
+	pos++;
+	if ( pos >= buf_size ) {
+	    result += QString( c, pos );
+	    pos = 0;
+	}
+	c[pos] = ts_getc();
     }
+    result += QString( c, pos );
 
     int len = (int)result.length();
     if ( len && result[len-1] == '\r' )
-	result.truncate(len-1);		// (if there are two \r, let one stay)
+	result.truncate(len-1); // (if there are two \r, let one stay)
 
     return result;
 }
@@ -1456,7 +1517,7 @@ QString QTextStream::read()
 {
 #if defined(CHECK_STATE)
     if ( !dev ) {
-	qWarning( "QTextStream::readLine: No device" );
+	qWarning( "QTextStream::read: No device" );
 	return QString::null;
     }
 #endif
@@ -1507,8 +1568,20 @@ QString QTextStream::read()
 
 /*!
   Writes a \c char to the stream and returns a reference to the stream.
+
+  The character \a c is assumed to be Latin1 encoded independent of the Encoding set
+  for the QTextStream.
 */
+QTextStream &QTextStream::operator<<( QChar c )
+{
+    CHECK_STREAM_PRECOND
+    ts_putc( c );
+    return *this;
+}
 
+/*!
+  Writes a \c char to the stream and returns a reference to the stream.
+*/
 QTextStream &QTextStream::operator<<( char c )
 {
     CHECK_STREAM_PRECOND
@@ -1737,6 +1810,9 @@ QTextStream &QTextStream::operator<<( double f )
 
 /*!
   Writes a string to the stream and returns a reference to the stream.
+
+  The string \a s is assumed to be Latin1 encoded independent of the Encoding set
+  for the QTextStream.
 */
 
 QTextStream &QTextStream::operator<<( const char* s )
@@ -1774,6 +1850,9 @@ QTextStream &QTextStream::operator<<( const char* s )
 
 /*!
   Writes \a s to the stream and returns a reference to the stream.
+
+  The string \a s is assumed to be Latin1 encoded independent of the Encoding set
+  for the QTextStream.
 */
 
 QTextStream &QTextStream::operator<<( const QCString & s )
@@ -2064,11 +2143,12 @@ QTextStream &reset( QTextStream &s )
   writing to non-persistent storage used by a single process.
   </ul>
 
-  \c Locale and all Unicode encodings, except \c RawUnicode, will look
-  at the first two bytes in a input stream to determine the byte
-  order. The initial byte order marker will be stripped off before data is read.
+  \c Locale and all Unicode encodings, except \c RawUnicode, will look at
+  the first two bytes in a input stream to determine the byte order. The
+  initial byte order marker will be stripped off before data is read.
 
-  \note This function should be called before any data is read to/written from the stream.
+  Note that this function should be called before any data is read
+  to/written from the stream.
   \sa setCodec()
 */
 
@@ -2084,10 +2164,16 @@ void QTextStream::setEncoding( Encoding e )
 	internalOrder = TRUE;
 	break;
     case UnicodeUTF8:
+#ifndef QT_NO_CODECS
 	mapper = QTextCodec::codecForMib( 106 );
 	latin1 = FALSE;
 	doUnicodeHeader = TRUE;
 	internalOrder = TRUE;
+#else
+	mapper = 0;
+	latin1 = TRUE;
+	doUnicodeHeader = TRUE;
+#endif
 	break;
     case UnicodeNetworkOrder:
 	mapper = 0;
@@ -2109,12 +2195,14 @@ void QTextStream::setEncoding( Encoding e )
 	break;
     case Locale:
 	latin1 = TRUE; 				// fallback to Latin 1
+#ifndef QT_NO_TEXTCODEC
 	mapper = QTextCodec::codecForLocale();
 #if defined(_OS_WIN32_)
 	if ( GetACP() == 1252 )
 	    mapper = 0;				// Optimized latin1 processing
 #endif
 	if ( mapper && mapper->mibEnum() == 4 )
+#endif
 	    mapper = 0;				// Optimized latin1 processing
 	doUnicodeHeader = TRUE; // If it reads as Unicode, accept it
 	break;
@@ -2127,11 +2215,14 @@ void QTextStream::setEncoding( Encoding e )
 }
 
 
-/*!
-  Sets the codec for this stream to \a codec. Will not try to autodetect Unicode.
+#ifndef QT_NO_TEXTCODEC
+/*!  Sets the codec for this stream to \a codec. Will not try to
+  autodetect Unicode.
 
-    \note This function should be called before any data is read to/written from the stream.
-    \sa setEncoding()
+  Note that this function should be called before any data is read
+  to/written from the stream.
+
+  \sa setEncoding()
 */
 
 void QTextStream::setCodec( QTextCodec *codec )
@@ -2141,5 +2232,6 @@ void QTextStream::setCodec( QTextCodec *codec )
     mapper = codec;
     doUnicodeHeader = FALSE;
 }
+#endif
 
 #endif // QT_NO_TEXTSTREAM
diff --git a/qtools/qtextstream.h b/qtools/qtextstream.h
index d7adbd3..c5f5ba1 100644
--- a/qtools/qtextstream.h
+++ b/qtools/qtextstream.h
@@ -57,7 +57,10 @@ public:
 		    UnicodeReverse, RawUnicode, UnicodeUTF8 };
 
     void	setEncoding( Encoding );
+#ifndef QT_NO_TEXTCODEC
     void	setCodec( QTextCodec* );
+#endif
+
     //    Encoding encoding() const { return cmode; }
 
     QTextStream();
@@ -89,6 +92,7 @@ public:
     QTextStream &operator>>( QString & );
     QTextStream &operator>>( QCString & );
 
+    QTextStream &operator<<( QChar );
     QTextStream &operator<<( char );
     QTextStream &operator<<( signed short );
     QTextStream &operator<<( unsigned short );
diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in
index 17c6626..156ad09 100644
--- a/qtools/qtools.pro.in
+++ b/qtools/qtools.pro.in
@@ -36,7 +36,11 @@ HEADERS		= qarray.h \
 		  qtextstream.h \
 		  qtl.h \
 		  qvaluelist.h \
-		  qvector.h
+		  qvector.h \
+                  qxml.h \
+                  qvaluestack.h \
+                  qmap.h \
+		  qmodules.h
 SOURCES		= qbuffer.cpp \
 		  qcollection.cpp \
 		  qcstring.cpp \
@@ -55,7 +59,9 @@ SOURCES		= qbuffer.cpp \
 		  qstring.cpp \
                   qtextstream.cpp \
 		  qtextcodec.cpp \
-		  qstringlist.cpp
+		  qstringlist.cpp \
+	          qxml.cpp \
+                  qmap.cpp
 
 unix:SOURCES +=   qfile_unix.cpp \
 		  qdir_unix.cpp \
diff --git a/qtools/qvaluestack.h b/qtools/qvaluestack.h
new file mode 100644
index 0000000..9728d6c
--- /dev/null
+++ b/qtools/qvaluestack.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+** 
+**
+** Definition of QValueStack class
+**
+** Created : 990925
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QVALUESTACK_H
+#define QVALUESTACK_H
+
+#ifndef QT_H
+#include "qvaluelist.h"
+#endif // QT_H
+
+
+template<class T>
+class Q_EXPORT QValueStack : public QValueList<T>
+{
+public:
+    QValueStack() {}
+   ~QValueStack() {}
+    void  push( const T& d ) { append(d); }
+    T pop()
+    {
+	T elem( this->last() );
+	if ( !this->isEmpty() )
+	    remove( this->fromLast() );
+	return elem;
+    }
+    T& top() { return this->last(); }
+    const T& top() const { return this->last(); }
+};
+
+#endif
diff --git a/qtools/qxml.cpp b/qtools/qxml.cpp
new file mode 100644
index 0000000..d171828
--- /dev/null
+++ b/qtools/qxml.cpp
@@ -0,0 +1,6007 @@
+/****************************************************************************
+** 
+**
+** Implementation of QXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qxml.h"
+#include "qtextcodec.h"
+#include "qbuffer.h"
+
+#ifndef QT_NO_XML
+// NOT REVISED
+
+// Error strings for the XML reader
+#define XMLERR_OK                         "no error occured"
+#define XMLERR_TAGMISMATCH                "tag mismatch"
+#define XMLERR_UNEXPECTEDEOF              "unexpected end of file"
+#define XMLERR_FINISHEDPARSINGWHILENOTEOF "parsing is finished but end of file is not reached"
+#define XMLERR_LETTEREXPECTED             "letter is expected"
+#define XMLERR_ERRORPARSINGELEMENT        "error while parsing element"
+#define XMLERR_ERRORPARSINGPROLOG         "error while parsing prolog"
+#define XMLERR_ERRORPARSINGMAINELEMENT    "error while parsing main element"
+#define XMLERR_ERRORPARSINGCONTENT        "error while parsing content"
+#define XMLERR_ERRORPARSINGNAME           "error while parsing name"
+#define XMLERR_ERRORPARSINGNMTOKEN        "error while parsing Nmtoken"
+#define XMLERR_ERRORPARSINGATTRIBUTE      "error while parsing attribute"
+#define XMLERR_ERRORPARSINGMISC           "error while parsing misc"
+#define XMLERR_ERRORPARSINGCHOICE         "error while parsing choice or seq"
+#define XMLERR_ERRORBYCONSUMER            "error triggered by consumer"
+#define XMLERR_UNEXPECTEDCHARACTER        "unexpected character"
+#define XMLERR_EQUALSIGNEXPECTED          "expected '=' but not found"
+#define XMLERR_QUOTATIONEXPECTED          "expected \" or ' but not found"
+#define XMLERR_ERRORPARSINGREFERENCE      "error while parsing reference"
+#define XMLERR_ERRORPARSINGPI             "error while parsing processing instruction"
+#define XMLERR_ERRORPARSINGATTLISTDECL    "error while parsing attribute list declaration"
+#define XMLERR_ERRORPARSINGATTTYPE        "error while parsing attribute type declaration"
+#define XMLERR_ERRORPARSINGATTVALUE       "error while parsing attribute value declaration"
+#define XMLERR_ERRORPARSINGELEMENTDECL    "error while parsing element declaration"
+#define XMLERR_ERRORPARSINGENTITYDECL     "error while parsing entity declaration"
+#define XMLERR_ERRORPARSINGNOTATIONDECL   "error while parsing notation declaration"
+#define XMLERR_ERRORPARSINGEXTERNALID     "error while parsing external id"
+#define XMLERR_ERRORPARSINGCOMMENT        "error while parsing comment"
+#define XMLERR_ERRORPARSINGENTITYVALUE    "error while parsing entity value declaration"
+#define XMLERR_CDSECTHEADEREXPECTED       "expected the header for a cdata section"
+#define XMLERR_MORETHANONEDOCTYPE         "more than one document type definition"
+#define XMLERR_ERRORPARSINGDOCTYPE        "error while parsing document type definition"
+#define XMLERR_INVALIDNAMEFORPI           "invalid name for processing instruction"
+#define XMLERR_VERSIONEXPECTED            "version expected while reading the XML declaration"
+#define XMLERR_EDECLORSDDECLEXPECTED      "EDecl or SDDecl expected while reading the XML declaration"
+#define XMLERR_SDDECLEXPECTED             "SDDecl expected while reading the XML declaration"
+#define XMLERR_WRONGVALUEFORSDECL         "wrong value for standalone declaration"
+#define XMLERR_UNPARSEDENTITYREFERENCE    "unparsed entity reference"
+#define XMLERR_INTERNALGENERALENTITYINDTD "internal general entity reference not allowed in DTD"
+#define XMLERR_EXTERNALGENERALENTITYINDTD "external parsed general entity reference not allowed in DTD"
+#define XMLERR_EXTERNALGENERALENTITYINAV  "external parsed general entity reference not allowed in attribute value"
+
+
+// the constants for the lookup table
+static const signed char cltWS      =  0; // white space
+static const signed char cltPer     =  1; // %
+static const signed char cltAmp     =  2; // &
+static const signed char cltGt      =  3; // >
+static const signed char cltLt      =  4; // <
+static const signed char cltSlash   =  5; // /
+static const signed char cltQm      =  6; // ?
+static const signed char cltEm      =  7; // !
+static const signed char cltDash    =  8; // -
+static const signed char cltCB      =  9; // ]
+static const signed char cltOB      = 10; // [
+static const signed char cltEq      = 11; // =
+static const signed char cltDq      = 12; // "
+static const signed char cltSq      = 13; // '
+static const signed char cltUnknown = 14;
+
+// character lookup table
+static const signed char charLookupTable[256]={
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07
+    cltUnknown, // 0x08
+    cltWS,      // 0x09 \t
+    cltWS,      // 0x0A \n
+    cltUnknown, // 0x0B
+    cltUnknown, // 0x0C
+    cltWS,      // 0x0D \r
+    cltUnknown, // 0x0E
+    cltUnknown, // 0x0F
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F
+    cltWS,      // 0x20 Space
+    cltEm,      // 0x21 !
+    cltDq,      // 0x22 "
+    cltUnknown, // 0x23
+    cltUnknown, // 0x24
+    cltPer,     // 0x25 %
+    cltAmp,     // 0x26 &
+    cltSq,      // 0x27 '
+    cltUnknown, // 0x28
+    cltUnknown, // 0x29
+    cltUnknown, // 0x2A
+    cltUnknown, // 0x2B
+    cltUnknown, // 0x2C
+    cltDash,    // 0x2D -
+    cltUnknown, // 0x2E
+    cltSlash,   // 0x2F /
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37
+    cltUnknown, // 0x38
+    cltUnknown, // 0x39
+    cltUnknown, // 0x3A
+    cltUnknown, // 0x3B
+    cltLt,      // 0x3C <
+    cltEq,      // 0x3D =
+    cltGt,      // 0x3E >
+    cltQm,      // 0x3F ?
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57
+    cltUnknown, // 0x58
+    cltUnknown, // 0x59
+    cltUnknown, // 0x5A
+    cltOB,      // 0x5B [
+    cltUnknown, // 0x5C
+    cltCB,      // 0x5D ]
+    cltUnknown, // 0x5E
+    cltUnknown, // 0x5F
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7
+    cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown  // 0xF8 - 0xFF
+};
+
+
+class QXmlNamespaceSupportPrivate
+{
+};
+class QXmlAttributesPrivate
+{
+};
+class QXmlInputSourcePrivate
+{
+};
+class QXmlParseExceptionPrivate
+{
+};
+class QXmlLocatorPrivate
+{
+};
+class QXmlDefaultHandlerPrivate
+{
+};
+
+#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
+bool operator==( const QMap<QString, QString>, const QMap<QString, QString> )
+{
+    return FALSE;
+}
+#endif
+
+/*!
+  \class QXmlParseException qxml.h
+  \brief The QXmlParseException class is used to report errors with the
+  QXmlErrorHandler interface.
+
+  \module XML
+
+  \sa QXmlErrorHandler
+*/
+/*!
+  \fn QXmlParseException::QXmlParseException( const QString& name, int c, int l, const QString& p, const QString& s )
+
+  Constructs a parse exception with the error string \a name in the column
+  \a c and line \a l for the public identifier \a p and the system identifier
+  \a s.
+*/
+/*!
+  Returns the error message.
+*/
+QString QXmlParseException::message() const
+{
+    return msg;
+}
+/*!
+  Returns the column number the error occured.
+*/
+int QXmlParseException::columnNumber() const
+{
+    return column;
+}
+/*!
+  Returns the line number the error occured.
+*/
+int QXmlParseException::lineNumber() const
+{
+    return line;
+}
+/*!
+  Returns the public identifier the error occured.
+*/
+QString QXmlParseException::publicId() const
+{
+    return pub;
+}
+/*!
+  Returns the system identifier the error occured.
+*/
+QString QXmlParseException::systemId() const
+{
+    return sys;
+}
+
+
+/*!
+  \class QXmlLocator qxml.h
+  \brief The QXmlLocator class provides the XML handler classes with
+  information about the actual parsing position.
+
+  \module XML
+
+  The reader reports a QXmlLocator to the content handler before he starts to
+  parse the document. This is done with the
+  QXmlContentHandler::setDocumentLocator() function. The handler classes can
+  now use this locator to get the actual position the reader is at.
+*/
+/*!
+    \fn QXmlLocator::QXmlLocator( QXmlSimpleReader* parent )
+
+    Constructor.
+*/
+/*!
+    \fn QXmlLocator::~QXmlLocator()
+
+    Destructor.
+*/
+/*!
+    Gets the column number (starting with 1) or -1 if there is no column number
+    available.
+*/
+int QXmlLocator::columnNumber()
+{
+    return ( reader->columnNr == -1 ? -1 : reader->columnNr + 1 );
+}
+/*!
+    Gets the line number (starting with 1) or -1 if there is no line number
+    available.
+*/
+int QXmlLocator::lineNumber()
+{
+    return ( reader->lineNr == -1 ? -1 : reader->lineNr + 1 );
+}
+
+
+/*********************************************
+ *
+ * QXmlNamespaceSupport
+ *
+ *********************************************/
+
+/*!
+  \class QXmlNamespaceSupport qxml.h
+  \brief The QXmlNamespaceSupport class is a helper class for XML readers which
+  want to include namespace support.
+
+  \module XML
+
+  It provides some functions that makes it easy to handle namespaces. Its main
+  use is for subclasses of QXmlReader which want to provide namespace
+  support.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+
+/*!
+  Constructs a QXmlNamespaceSupport.
+*/
+QXmlNamespaceSupport::QXmlNamespaceSupport()
+{
+    reset();
+}
+
+/*!
+  Destructs a QXmlNamespaceSupport.
+*/
+QXmlNamespaceSupport::~QXmlNamespaceSupport()
+{
+}
+
+/*!
+  This function declares a prefix in the current namespace context; the prefix
+  will remain in force until this context is popped, unless it is shadowed in a
+  descendant context.
+
+  Note that there is an asymmetry in this library: while prefix() will not
+  return the default "" prefix, even if you have declared one; to check for a
+  default prefix, you have to look it up explicitly using uri(). This
+  asymmetry exists to make it easier to look up prefixes for attribute names,
+  where the default prefix is not allowed.
+*/
+void QXmlNamespaceSupport::setPrefix( const QString& pre, const QString& uri )
+{
+    if( pre.isNull() ) {
+	ns.insert( "", uri );
+    } else {
+	ns.insert( pre, uri );
+    }
+}
+
+/*!
+  Returns one of the prefixes mapped to a namespace URI.
+
+  If more than one prefix is currently mapped to the same URI, this function
+  will make an arbitrary selection; if you want all of the prefixes, use the
+  prefixes() function instead.
+
+  Note: this will never return the empty (default) prefix; to check for a
+  default prefix, use the uri() function with an argument of "".
+*/
+QString QXmlNamespaceSupport::prefix( const QString& uri ) const
+{
+    QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+    while ( (itc=it) != ns.end() ) {
+	++it;
+	if ( itc.data() == uri && !itc.key().isEmpty() )
+	    return itc.key();
+    }
+    return "";
+}
+
+/*!
+  Looks up a prefix in the current context and returns the currently-mapped
+  namespace URI. Use the empty string ("") for the default namespace.
+*/
+QString QXmlNamespaceSupport::uri( const QString& prefix ) const
+{
+    const QString& returi = ns[ prefix ];
+    return returi;
+}
+
+/*!
+  Splits the name at the ':' and returns the prefix and the local name.
+*/
+void QXmlNamespaceSupport::splitName( const QString& qname,
+	QString& prefix, QString& localname ) const
+{
+    uint pos;
+    // search the ':'
+    for( pos=0; pos<qname.length(); pos++ ) {
+	if ( qname.at(pos) == ':' )
+	    break;
+    }
+    // and split
+    prefix = qname.left( pos );
+    localname = qname.mid( pos+1 );
+}
+
+/*!
+  Processes a raw XML 1.0 name in the current context by removing the prefix
+  and looking it up among the prefixes currently declared.
+
+  First parameter is the raw XML 1.0 name to be processed. The second parameter
+  is a flag wheter the name is the name of an attribute (TRUE) or not (FALSE).
+
+  The return values will be stored in the last two parameters as follows:
+  <ul>
+  <li> The namespace URI, or an empty string if none is in use.
+  <li> The local name (without prefix).
+  </ul>
+
+  If the raw name has a prefix that has not been declared, then the return
+  value will be empty.
+
+  Note that attribute names are processed differently than element names: an
+  unprefixed element name will received the default namespace (if any), while
+  an unprefixed element name will not
+*/
+void QXmlNamespaceSupport::processName( const QString& qname,
+	bool isAttribute,
+	QString& nsuri, QString& localname ) const
+{
+    uint pos;
+    // search the ':'
+    for( pos=0; pos<qname.length(); pos++ ) {
+	if ( qname.at(pos) == ':' )
+	    break;
+    }
+    if ( pos < qname.length() ) {
+	// there was a ':'
+	nsuri = uri( qname.left( pos ) );
+	localname = qname.mid( pos+1 );
+    } else {
+	// there was no ':'
+	if ( isAttribute ) {
+	    nsuri = ""; // attributes don't take default namespace
+	} else {
+	    nsuri = uri( "" ); // get default namespace
+	}
+	localname = qname;
+    }
+}
+
+/*!
+  Returns an enumeration of all prefixes currently declared.
+
+  Note: if there is a default prefix, it will not be returned in this
+  enumeration; check for the default prefix using uri() with an argument
+  of "".
+*/
+QStringList QXmlNamespaceSupport::prefixes() const
+{
+    QStringList list;
+
+    QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+    while ( (itc=it) != ns.end() ) {
+	++it;
+	if ( !itc.key().isEmpty() )
+	    list.append( itc.key() );
+    }
+    return list;
+}
+
+/*!
+  Returns a list of all prefixes currently declared for a URI.
+
+  The xml: prefix will be included. If you want only one prefix that's
+  mapped to the namespace URI, and you don't care which one you get, use the
+  prefix() function instead.
+
+  Note: the empty (default) prefix is never included in this enumeration; to
+  check for the presence of a default namespace, use uri() with an
+  argument of "".
+*/
+QStringList QXmlNamespaceSupport::prefixes( const QString& uri ) const
+{
+    QStringList list;
+
+    QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+    while ( (itc=it) != ns.end() ) {
+	++it;
+	if ( itc.data() == uri && !itc.key().isEmpty() )
+	    list.append( itc.key() );
+    }
+    return list;
+}
+
+/*!
+  Starts a new namespace context.
+
+  Normally, you should push a new context at the beginning of each XML element:
+  the new context will automatically inherit the declarations of its parent
+  context, but it will also keep track of which declarations were made within
+  this context.
+*/
+void QXmlNamespaceSupport::pushContext()
+{
+    nsStack.push( ns );
+}
+
+/*!
+  Reverts to the previous namespace context.
+
+  Normally, you should pop the context at the end of each XML element.  After
+  popping the context, all namespace prefix mappings that were previously in
+  force are restored.
+*/
+void QXmlNamespaceSupport::popContext()
+{
+    if( !nsStack.isEmpty() )
+	ns = nsStack.pop();
+}
+
+/*!
+  Resets this namespace support object for reuse.
+*/
+void QXmlNamespaceSupport::reset()
+{
+    nsStack.clear();
+    ns.clear();
+    ns.insert( "xml", "http://www.w3.org/XML/1998/namespace" ); // the XML namespace
+}
+
+
+
+/*********************************************
+ *
+ * QXmlAttributes
+ *
+ *********************************************/
+
+/*!
+  \class QXmlAttributes qxml.h
+  \brief The QXmlAttributes class provides XML attributes.
+
+  \module XML
+
+  If attributes are reported by QXmlContentHandler::startElement() this
+  class is used to pass the attribute values. It provides you with different
+  functions to access the attribute names and values.
+*/
+/*!
+  \fn QXmlAttributes::QXmlAttributes()
+
+  Constructs an empty attribute list.
+*/
+/*!
+  \fn QXmlAttributes::~QXmlAttributes()
+
+  Destructs attributes.
+*/
+
+/*!
+  Look up the index of an attribute by an XML 1.0 qualified name.
+
+  Returns the index of the attribute (starting with 0) or -1 if it wasn't
+  found.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+int QXmlAttributes::index( const QString& qName ) const
+{
+    return qnameList.findIndex( qName );
+}
+
+/*!
+  Looks up the index of an attribute by a namespace name.
+
+  \a uri specifies the namespace URI, or the empty string if the name has no
+  namespace URI. \a localPart specifies the attribute's local name.
+
+  Returns the index of the attribute (starting with 0) or -1 if it wasn't
+  found.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+int QXmlAttributes::index( const QString& uri, const QString& localPart ) const
+{
+    uint count = uriList.count();
+    for ( uint i=0; i<count; i++ ) {
+	if ( uriList[i] == uri && localnameList[i] == localPart )
+	    return i;
+    }
+    return -1;
+}
+
+/*!
+  Returns the number of attributes in the list.
+*/
+int QXmlAttributes::length() const
+{
+    return valueList.count();
+}
+
+/*!
+  Looks up an attribute's local name by index (starting with 0).
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::localName( int index ) const
+{
+    return localnameList[index];
+}
+
+/*!
+  Looks up an attribute's XML 1.0 qualified name by index (starting with 0).
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::qName( int index ) const
+{
+    return qnameList[index];
+}
+
+/*!
+  Looks up an attribute's namespace URI by index (starting with 0).
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::uri( int index ) const
+{
+    return uriList[index];
+}
+
+/*!
+  Looks up an attribute's type by index (starting with 0).
+
+  At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( int ) const
+{
+    return "CDATA";
+}
+
+/*!
+  Looks up an attribute's type by XML 1.0 qualified name.
+
+  At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( const QString& ) const
+{
+    return "CDATA";
+}
+
+/*!
+  Looks up an attribute's type by namespace name.
+
+  The first parameter specifies the namespace URI, or the empty string if
+  the name has no namespace URI. The second parameter specifies the
+  attribute's local name.
+
+  At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( const QString&, const QString& ) const
+{
+    return "CDATA";
+}
+
+/*!
+  Looks up an attribute's value by index (starting with 0).
+*/
+QString QXmlAttributes::value( int index ) const
+{
+    return valueList[index];
+}
+
+/*!
+  Looks up an attribute's value by XML 1.0 qualified name.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::value( const QString& qName ) const
+{
+    int i = index( qName );
+    if ( i == -1 )
+	return QString::null;
+    return valueList[ i ];
+}
+
+/*!
+  Looks up an attribute's value by namespace name.
+
+  \a uri specifies the namespace URI, or the empty string if the name has no
+  namespace URI. \a localName specifies the attribute's local name.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::value( const QString& uri, const QString& localName ) const
+{
+    int i = index( uri, localName );
+    if ( i == -1 )
+	return QString::null;
+    return valueList[ i ];
+}
+
+
+/*********************************************
+ *
+ * QXmlInputSource
+ *
+ *********************************************/
+
+/*!
+  \class QXmlInputSource qxml.h
+  \brief The QXmlInputSource class is the source where XML data is read from.
+
+  \module XML
+
+  All subclasses of QXmlReader read the input from this class.
+*/
+
+/*!
+  Returns all the data this input source contains.
+*/
+const QString& QXmlInputSource::data() const
+{
+    return input;
+}
+
+/*!
+  Constructs a input source which contains no data.
+*/
+QXmlInputSource::QXmlInputSource( )
+{
+    input = "";
+}
+
+/*!
+  Constructs a input source and get the data from the text stream.
+*/
+QXmlInputSource::QXmlInputSource( QTextStream& stream )
+{
+    QByteArray rawData;
+    if ( stream.device()->isDirectAccess() ) {
+	rawData = stream.device()->readAll();
+    } else {
+	int nread = 0;
+	const int bufsize = 512;
+	while ( !stream.device()->atEnd() ) {
+	    rawData.resize( nread + bufsize );
+	    nread += stream.device()->readBlock( rawData.data()+nread, bufsize );
+	}
+	rawData.resize( nread );
+    }
+    readInput( rawData );
+}
+
+/*!
+  Constructs a input source and get the data from a file. If the file cannot be
+  read the input source is empty.
+*/
+QXmlInputSource::QXmlInputSource( QFile& file )
+{
+    if ( !file.open(IO_ReadOnly) ) {
+	input = "";
+	return;
+    }
+    QByteArray rawData = file.readAll();
+    readInput( rawData );
+    file.close();
+}
+
+/*!
+  Destructor.
+*/
+QXmlInputSource::~QXmlInputSource()
+{
+}
+
+/*!
+  Sets the data of the input source to \a dat.
+*/
+void QXmlInputSource::setData( const QString& dat )
+{
+    input = dat;
+}
+
+/*!
+  Read the XML file from the byte array; try to recoginize the encoding.
+*/
+// ### The input source should not do the encoding detection!
+void QXmlInputSource::readInput( QByteArray& rawData )
+{
+    QBuffer buf( rawData );
+    buf.open( IO_ReadOnly );
+    QTextStream *stream = new QTextStream( &buf );
+    QChar tmp;
+    // assume UTF8 or UTF16 at first
+    stream->setEncoding( QTextStream::UnicodeUTF8 );
+    input = "";
+    // read the first 5 characters
+    for ( int i=0; i<5; i++ ) {
+	*stream >> tmp;
+	input += tmp;
+    }
+    // starts the document with an XML declaration?
+    if ( input == "<?xml" ) {
+	// read the whole XML declaration
+	do {
+	    *stream >> tmp;
+	    input += tmp;
+	} while( tmp != '>' );
+	// and try to find out if there is an encoding
+	int pos = input.find( "encoding" );
+	if ( pos != -1 ) {
+	    QString encoding;
+	    do {
+		pos++;
+		if ( pos > (int)input.length() )
+		    goto finished;
+	    } while( input[pos] != '"' && input[pos] != '\'' );
+	    pos++;
+	    while( input[pos] != '"' && input[pos] != '\'' ) {
+		encoding += input[pos];
+		pos++;
+		if ( pos > (int)input.length() )
+		    goto finished;
+	    }
+	    delete stream;
+	    stream = new QTextStream( &buf );
+	    stream->setCodec( QTextCodec::codecForName( encoding ) );
+	    buf.reset();
+	    input = "";
+	}
+    }
+finished:
+    input += stream->read();
+    delete stream;
+    buf.close();
+}
+
+
+/*********************************************
+ *
+ * QXmlDefaultHandler
+ *
+ *********************************************/
+
+/*!
+  \class QXmlContentHandler qxml.h
+  \brief The QXmlContentHandler class provides an interface to report logical
+  content of XML data.
+
+  \module XML
+
+  If the application needs to be informed of basic parsing events, it
+  implements this interface and sets it with QXmlReader::setContentHandler().
+  The reader reports basic document-related events like the start and end of
+  elements and character data through this interface.
+
+  The order of events in this interface is very important, and mirrors the
+  order of information in the document itself. For example, all of an element's
+  content (character data, processing instructions, and/or subelements) will
+  appear, in order, between the startElement() event and the corresponding
+  endElement() event.
+
+  The class QXmlDefaultHandler gives a default implementation for this
+  interface; subclassing from this class is very convenient if you want only be
+  informed of some parsing events.
+
+  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+  \sa QXmlDTDHandler QXmlDeclHandler QXmlEntityResolver QXmlErrorHandler
+  QXmlLexicalHandler
+*/
+/*!
+  \fn void QXmlContentHandler::setDocumentLocator( QXmlLocator* locator )
+
+  The reader calls this function before he starts parsing the document. The
+  argument \a locator is a pointer to a QXmlLocator which allows the
+  application to get the actual position of the parsing in the document.
+
+  Do not destroy the \a locator; it is destroyed when the reader is destroyed
+  (do not use the \a locator after the reader got destroyed).
+*/
+/*!
+  \fn bool QXmlContentHandler::startDocument()
+
+  The reader calls this function when he starts parsing the document.
+  The reader will call this function only once before any other functions in
+  this class or in the QXmlDTDHandler class are called (except
+  QXmlContentHandler::setDocumentLocator()).
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  \sa endDocument()
+*/
+/*!
+  \fn bool QXmlContentHandler::endDocument()
+
+  The reader calls this function after he has finished the parsing. It
+  is only called once. It is the last function of all handler functions that is
+  called. It is called after the reader has read all input or has abandoned
+  parsing because of a fatal error.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  \sa startDocument()
+*/
+/*!
+  \fn bool QXmlContentHandler::startPrefixMapping( const QString& prefix, const QString& uri )
+
+  The reader calls this function to signal the begin of a prefix-URI
+  namespace mapping scope. This information is not necessary for normal
+  namespace processing since the reader automatically replaces prefixes for
+  element and attribute names.
+
+  Note that startPrefixMapping and endPrefixMapping calls are not guaranteed to
+  be properly nested relative to each-other: all startPrefixMapping events will
+  occur before the corresponding startElement event, and all endPrefixMapping
+  events will occur after the corresponding endElement event, but their order
+  is not otherwise guaranteed.
+
+  The argument \a prefix is the namespace prefix being declared and the
+  argument \a uri is the namespace URI the prefix is mapped to.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+  \sa endPrefixMapping()
+*/
+/*!
+  \fn bool QXmlContentHandler::endPrefixMapping( const QString& prefix )
+
+  The reader calls this function to signal the end of a prefix mapping.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+  \sa startPrefixMapping()
+*/
+/*!
+  \fn bool QXmlContentHandler::startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts )
+
+  The reader calls this function when he has parsed a start element tag.
+
+  There will be a corresponding endElement() call when the corresponding end
+  element tag was read. The startElement() and endElement() calls are always
+  nested correctly. Empty element tags (e.g. &lt;a/&gt;) are reported by
+  startElement() directly followed by a call to endElement().
+
+  The attribute list provided will contain only attributes with explicit
+  values. The attribute list will contain attributes used for namespace
+  declaration (i.e. attributes starting with xmlns) only if the
+  namespace-prefix property of the reader is TRUE.
+
+  The argument \a uri is the namespace URI, or the empty string if the element
+  has no namespace URI or if namespace processing is not being performed, \a
+  localName is the local name (without prefix), or the empty string if
+  namespace processing is not being performed, \a qName is the qualified name
+  (with prefix), or the empty string if qualified names are not available and
+  \a atts are the attributes attached to the element. If there are no
+  attributes, \a atts is an empty attributes object
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+  \sa endElement()
+*/
+/*!
+  \fn bool QXmlContentHandler::endElement( const QString& namespaceURI, const QString& localName, const QString& qName )
+
+  The reader calls this function when he has parsed an end element tag.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+  \sa startElement()
+*/
+/*!
+  \fn bool QXmlContentHandler::characters( const QString& ch )
+
+  The reader calls this function when he has parsed a chunk of character
+  data (either normal character data or character data inside a CDATA section;
+  if you have to distinguish between those two types you have to use
+  QXmlLexicalHandler::startCDATA() and QXmlLexicalHandler::endCDATA() in
+  addition).
+
+  Some readers will report whitespace in element content using the
+  ignorableWhitespace() function rather than this one (QXmlSimpleReader will
+  do it not though).
+
+  A reader is allowed to report the character data of an element in more than
+  one chunk; e.g. a reader might want to report "a &amp;lt; b" in three
+  characters() events ("a ", "<" and " b").
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn bool QXmlContentHandler::ignorableWhitespace( const QString& ch )
+
+  Some readers may use this function to report each chunk of whitespace in
+  element content (QXmlSimpleReader does not though).
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn bool QXmlContentHandler::processingInstruction( const QString& target, const QString& data )
+
+  The reader calls this function when he has parsed a processing
+  instruction.
+
+  \a target is the target name of the processing instruction and \a data is the
+  data of the processing instruction.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn bool QXmlContentHandler::skippedEntity( const QString& name )
+
+  Some readers may skip entities if they have not seen the declarations (e.g.
+  because they are in an external DTD). If they do so they will report it by
+  calling this function.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn QString QXmlContentHandler::errorString()
+
+  The reader calls this function to get an error string if any of the handler
+  functions returns FALSE to him.
+*/
+
+
+/*!
+  \class QXmlErrorHandler qxml.h
+  \brief The QXmlErrorHandler class provides an interface to report errors in
+  XML data.
+
+  \module XML
+
+  If the application is interested in reporting errors to the user or any other
+  customized error handling, you should subclass this class.
+
+  You can set the error handler with QXmlReader::setErrorHandler().
+
+  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+  \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+  QXmlLexicalHandler
+*/
+/*!
+  \fn bool QXmlErrorHandler::warning( const QXmlParseException& exception )
+
+  A reader might use this function to report a warning. Warnings are conditions
+  that are not errors or fatal errors as defined by the XML 1.0 specification.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn bool QXmlErrorHandler::error( const QXmlParseException& exception )
+
+  A reader might use this function to report a recoverable error. A recoverable
+  error corresponds to the definiton of "error" in section 1.2 of the XML 1.0
+  specification.
+
+  The reader must continue to provide normal parsing events after invoking this
+  function.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn bool QXmlErrorHandler::fatalError( const QXmlParseException& exception )
+
+  A reader must use this function to report a non-recoverable error.
+
+  If this function returns TRUE the reader might try to go on parsing and
+  reporting further errors; but no regular parsing events are reported.
+*/
+/*!
+  \fn QString QXmlErrorHandler::errorString()
+
+  The reader calls this function to get an error string if any of the handler
+  functions returns FALSE to him.
+*/
+
+
+/*!
+  \class QXmlDTDHandler qxml.h
+  \brief The QXmlDTDHandler class provides an interface to report DTD content
+  of XML data.
+
+  \module XML
+
+  If an application needs information about notations and unparsed entities,
+  then the application implements this interface and registers an instance with
+  QXmlReader::setDTDHandler().
+
+  Note that this interface includes only those DTD events that the XML
+  recommendation requires processors to report: notation and unparsed entity
+  declarations.
+
+  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+  \sa QXmlDeclHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
+  QXmlLexicalHandler
+*/
+/*!
+  \fn bool QXmlDTDHandler::notationDecl( const QString& name, const QString& publicId, const QString& systemId )
+
+  The reader calls this function when he has parsed a notation
+  declaration.
+
+  The argument \a name is the notation name, \a publicId is the notations's
+  public identifier and \a systemId is the notations's system identifier.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn bool QXmlDTDHandler::unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName )
+
+  The reader calls this function when he finds an unparsed entity declaration.
+
+  The argument \a name is the unparsed entity's name, \a publicId is the
+  entity's public identifier, \a systemId is the entity's system identifier and
+  \a notation is the name of the associated notation.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn QString QXmlDTDHandler::errorString()
+
+  The reader calls this function to get an error string if any of the handler
+  functions returns FALSE to him.
+*/
+
+
+/*!
+  \class QXmlEntityResolver qxml.h
+  \brief The QXmlEntityResolver class provides an interface to resolve extern
+  entities contained in XML data.
+
+  \module XML
+
+  If an application needs to implement customized handling for external
+  entities, it must implement this interface and register it with
+  QXmlReader::setEntityResolver().
+
+  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+  \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlErrorHandler
+  QXmlLexicalHandler
+*/
+/*!
+  \fn bool QXmlEntityResolver::resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret )
+
+  The reader will call this function before he opens any external entity,
+  except the top-level document entity. The application may request the reader
+  to resolve the entity itself (\a ret is 0) or to use an entirely different
+  input source (\a ret points to the input source).
+
+  The reader will delete the input source \a ret when he no longer needs it. So
+  you should allocate it on the heap with \c new.
+
+  The argument \a publicId is the public identifier of the external entity, \a
+  systemId is the system identifier of the external entity and \a ret is the
+  return value of this function: if it is 0 the reader should resolve the
+  entity itself, if it is non-zero it must point to an input source which the
+  reader will use instead.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn QString QXmlEntityResolver::errorString()
+
+  The reader calls this function to get an error string if any of the handler
+  functions returns FALSE to him.
+*/
+
+
+/*!
+  \class QXmlLexicalHandler qxml.h
+  \brief The QXmlLexicalHandler class provides an interface to report lexical
+  content of XML data.
+
+  \module XML
+
+  The events in the lexical handler apply to the entire document, not just to
+  the document element, and all lexical handler events appear between the
+  content handler's startDocument and endDocument events.
+
+  You can set the lexical handler with QXmlReader::setLexicalHandler().
+
+  This interface is designed after the SAX2 extension LexicalHandler. The
+  functions startEntity() and endEntity() are not included though.
+
+  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+  \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+  QXmlErrorHandler
+*/
+/*!
+  \fn bool QXmlLexicalHandler::startDTD( const QString& name, const QString& publicId, const QString& systemId )
+
+  The reader calls this function to report the start of a DTD declaration, if
+  any.
+
+  All declarations reported through QXmlDTDHandler or QXmlDeclHandler appear
+  between the startDTD() and endDTD() calls.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  \sa endDTD()
+*/
+/*!
+  \fn bool QXmlLexicalHandler::endDTD()
+
+  The reader calls this function to report the end of a DTD declaration, if
+  any.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  \sa startDTD()
+*/
+/*!
+  \fn bool QXmlLexicalHandler::startCDATA()
+
+  The reader calls this function to report the start of a CDATA section. The
+  content of the CDATA section will be reported through the regular
+  QXmlContentHandler::characters(). This function is intended only to report
+  the boundary.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  \sa endCDATA()
+*/
+/*!
+  \fn bool QXmlLexicalHandler::endCDATA()
+
+  The reader calls this function to report the end of a CDATA section.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+
+  \sa startCDATA()
+*/
+/*!
+  \fn bool QXmlLexicalHandler::comment( const QString& ch )
+
+  The reader calls this function to report an XML comment anywhere in the
+  document.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn QString QXmlLexicalHandler::errorString()
+
+  The reader calls this function to get an error string if any of the handler
+  functions returns FALSE to him.
+*/
+
+
+/*!
+  \class QXmlDeclHandler qxml.h
+  \brief The QXmlDeclHandler class provides an interface to report declaration
+  content of XML data.
+
+  \module XML
+
+  You can set the declaration handler with QXmlReader::setDeclHandler().
+
+  This interface is designed after the SAX2 extension DeclHandler.
+
+  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+  \sa QXmlDTDHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
+  QXmlLexicalHandler
+*/
+/*!
+  \fn bool QXmlDeclHandler::attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value )
+
+  The reader calls this function to report an attribute type declaration. Only
+  the effective (first) declaration for an attribute will be reported.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn bool QXmlDeclHandler::internalEntityDecl( const QString& name, const QString& value )
+
+  The reader calls this function to report an internal entity declaration. Only
+  the effective (first) declaration will be reported.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn bool QXmlDeclHandler::externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId )
+
+  The reader calls this function to report a parsed external entity
+  declaration. Only the effective (first) declaration for each entity will be
+  reported.
+
+  If this function returns FALSE the reader will stop parsing and will report
+  an error. The reader will use the function errorString() to get the error
+  message that will be used for reporting the error.
+*/
+/*!
+  \fn QString QXmlDeclHandler::errorString()
+
+  The reader calls this function to get an error string if any of the handler
+  functions returns FALSE to him.
+*/
+
+
+/*!
+  \class QXmlDefaultHandler qxml.h
+  \brief The QXmlDefaultHandler class provides a default implementation of all
+  XML handler classes.
+
+  \module XML
+
+  Very often you are only interested in parts of the things that that the
+  reader reports to you. This class simply implements a default behaviour of
+  the handler classes (most of the time: do nothing). Normally this is the
+  class you subclass for implementing your customized handler.
+
+  See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+  \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+  QXmlErrorHandler QXmlLexicalHandler
+*/
+/*!
+  \fn QXmlDefaultHandler::QXmlDefaultHandler()
+
+  Constructor.
+*/
+/*!
+  \fn QXmlDefaultHandler::~QXmlDefaultHandler()
+
+  Destructor.
+*/
+
+/*!
+  Does nothing.
+*/
+void QXmlDefaultHandler::setDocumentLocator( QXmlLocator* )
+{
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::startDocument()
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::endDocument()
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::startPrefixMapping( const QString&, const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::endPrefixMapping( const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::startElement( const QString&, const QString&,
+	const QString&, const QXmlAttributes& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::endElement( const QString&, const QString&,
+	const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::characters( const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::ignorableWhitespace( const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::processingInstruction( const QString&,
+	const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::skippedEntity( const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::warning( const QXmlParseException& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::error( const QXmlParseException& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::fatalError( const QXmlParseException& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::notationDecl( const QString&, const QString&,
+	const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::unparsedEntityDecl( const QString&, const QString&,
+	const QString&, const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Always sets \a ret to 0, so that the reader will use the system identifier
+  provided in the XML document.
+*/
+bool QXmlDefaultHandler::resolveEntity( const QString&, const QString&,
+	QXmlInputSource* ret )
+{
+    ret = 0;
+    return TRUE;
+}
+
+/*!
+  Returns the default error string.
+*/
+QString QXmlDefaultHandler::errorString()
+{
+    return QString( XMLERR_ERRORBYCONSUMER );
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::startDTD( const QString&, const QString&, const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::endDTD()
+{
+    return TRUE;
+}
+
+#if 0
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::startEntity( const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::endEntity( const QString& )
+{
+    return TRUE;
+}
+#endif
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::startCDATA()
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::endCDATA()
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::comment( const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::attributeDecl( const QString&, const QString&, const QString&, const QString&, const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::internalEntityDecl( const QString&, const QString& )
+{
+    return TRUE;
+}
+
+/*!
+  Does nothing.
+*/
+bool QXmlDefaultHandler::externalEntityDecl( const QString&, const QString&, const QString& )
+{
+    return TRUE;
+}
+
+
+/*********************************************
+ *
+ * QXmlSimpleReaderPrivate
+ *
+ *********************************************/
+
+class QXmlSimpleReaderPrivate
+{
+private:
+    // constructor
+    QXmlSimpleReaderPrivate()
+    { }
+
+
+    // used for entity declarations
+    struct ExternParameterEntity
+    {
+	ExternParameterEntity( ) {}
+	ExternParameterEntity( const QString &p, const QString &s )
+	    : publicId(p), systemId(s) {}
+	QString publicId;
+	QString systemId;
+    };
+    struct ExternEntity
+    {
+	ExternEntity( ) {}
+	ExternEntity( const QString &p, const QString &s, const QString &n )
+	    : publicId(p), systemId(s), notation(n) {}
+	QString publicId;
+	QString systemId;
+	QString notation;
+    };
+    QMap<QString,ExternParameterEntity> externParameterEntities;
+    QMap<QString,QString> parameterEntities;
+    QMap<QString,ExternEntity> externEntities;
+    QMap<QString,QString> entities;
+
+    // used for standalone declaration
+    enum Standalone { Yes, No, Unknown };
+
+    QString doctype; // only used for the doctype
+    QString xmlVersion; // only used to store the version information
+    QString encoding; // only used to store the encoding
+    Standalone standalone; // used to store the value of the standalone declaration
+
+    QString publicId; // used by parseExternalID() to store the public ID
+    QString systemId; // used by parseExternalID() to store the system ID
+    QString attDeclEName; // use by parseAttlistDecl()
+    QString attDeclAName; // use by parseAttlistDecl()
+
+    // flags for some features support
+    bool useNamespaces;
+    bool useNamespacePrefixes;
+    bool reportWhitespaceCharData;
+
+    // used to build the attribute list
+    QXmlAttributes attList;
+
+    // helper classes
+    QXmlLocator *locator;
+    QXmlNamespaceSupport namespaceSupport;
+
+    // error string
+    QString error;
+
+    // friend declarations
+    friend class QXmlSimpleReader;
+};
+
+
+/*********************************************
+ *
+ * QXmlSimpleReader
+ *
+ *********************************************/
+
+/*!
+  \class QXmlReader qxml.h
+  \brief The QXmlReader class provides an interface for XML readers (i.e.
+  parsers).
+
+  \module XML
+
+  This abstract class describes an interface for all XML readers in Qt. At the
+  moment there is only one implementation of a reader included in the XML
+  module of Qt (QXmlSimpleReader). In future releases there might be more
+  readers with different properties available (e.g. a validating parser).
+
+  The design of the XML classes follow the
+  <a href="http://www.megginson.com/SAX/">SAX2 java interface</a>.
+  It was adopted to fit into the Qt naming conventions; so it should be very
+  easy for anybody who has worked with SAX2 to get started with the Qt XML
+  classes.
+
+  All readers use the class QXmlInputSource to read the input document from.
+  Since you are normally interested in certain contents of the XML document,
+  the reader reports those contents through special handler classes
+  (QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
+  QXmlErrorHandler and QXmlLexicalHandler).
+
+  You have to subclass these classes. Since the handler classes describe only
+  interfaces you must implement all functions; there is a class
+  (QXmlDefaultHandler) to make this easier; it implements a default behaviour
+  (do nothing) for all functions.
+
+  For getting started see also the
+  <a href="xml-sax.html#quickStart">Quick start</a>.
+
+  \sa QXmlSimpleReader
+*/
+/*!
+  \fn bool QXmlReader::feature( const QString& name, bool *ok ) const
+
+  If the reader has the feature \a name, this function returns the value of the
+  feature.
+
+  If the reader has not the feature \a name, the return value may be anything.
+
+  If \a ok is not 0, then \a ok  is set to TRUE if the reader has the feature
+  \a name, otherwise \a ok is set to FALSE.
+
+  \sa setFeature() hasFeature()
+*/
+/*!
+  \fn void QXmlReader::setFeature( const QString& name, bool value )
+
+  Sets the feature \a name to \a value. If the reader has not the feature \a
+  name, this value is ignored.
+
+  \sa feature() hasFeature()
+*/
+/*!
+  \fn bool QXmlReader::hasFeature( const QString& name ) const
+
+  Returns \c TRUE if the reader has the feature \a name, otherwise FALSE.
+
+  \sa feature() setFeature()
+*/
+/*!
+  \fn void* QXmlReader::property( const QString& name, bool *ok ) const
+
+  If the reader has the property \a name, this function returns the value of
+  the property.
+
+  If the reader has not the property \a name, the return value is 0.
+
+  If \a ok is not 0, then \a ok  is set to TRUE if the reader has the property
+  \a name, otherwise \a ok is set to FALSE.
+
+  \sa setProperty() hasProperty()
+*/
+/*!
+  \fn void QXmlReader::setProperty( const QString& name, void* value )
+
+  Sets the property \a name to \a value. If the reader has not the property \a
+  name, this value is ignored.
+
+  \sa property() hasProperty()
+*/
+/*!
+  \fn bool QXmlReader::hasProperty( const QString& name ) const
+
+  Returns TRUE if the reader has the property \a name, otherwise FALSE.
+
+  \sa property() setProperty()
+*/
+/*!
+  \fn void QXmlReader::setEntityResolver( QXmlEntityResolver* handler )
+
+  Sets the entity resolver to \a handler.
+
+  \sa entityResolver()
+*/
+/*!
+  \fn QXmlEntityResolver* QXmlReader::entityResolver() const
+
+  Returns the entity resolver or 0 if none was set.
+
+  \sa setEntityResolver()
+*/
+/*!
+  \fn void QXmlReader::setDTDHandler( QXmlDTDHandler* handler )
+
+  Sets the DTD handler to \a handler.
+
+  \sa DTDHandler()
+*/
+/*!
+  \fn QXmlDTDHandler* QXmlReader::DTDHandler() const
+
+  Returns the DTD handler or 0 if none was set.
+
+  \sa setDTDHandler()
+*/
+/*!
+  \fn void QXmlReader::setContentHandler( QXmlContentHandler* handler )
+
+  Sets the content handler to \a handler.
+
+  \sa contentHandler()
+*/
+/*!
+  \fn QXmlContentHandler* QXmlReader::contentHandler() const
+
+  Returns the content handler or 0 if none was set.
+
+  \sa setContentHandler()
+*/
+/*!
+  \fn void QXmlReader::setErrorHandler( QXmlErrorHandler* handler )
+
+  Sets the error handler to \a handler.
+
+  \sa errorHandler()
+*/
+/*!
+  \fn QXmlErrorHandler* QXmlReader::errorHandler() const
+
+  Returns the error handler or 0 if none was set
+
+  \sa setErrorHandler()
+*/
+/*!
+  \fn void QXmlReader::setLexicalHandler( QXmlLexicalHandler* handler )
+
+  Sets the lexical handler to \a handler.
+
+  \sa lexicalHandler()
+*/
+/*!
+  \fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const
+
+  Returns the lexical handler or 0 if none was set.
+
+  \sa setLexicalHandler()
+*/
+/*!
+  \fn void QXmlReader::setDeclHandler( QXmlDeclHandler* handler )
+
+  Sets the declaration handler to \a handler.
+
+  \sa declHandler()
+*/
+/*!
+  \fn QXmlDeclHandler* QXmlReader::declHandler() const
+
+  Returns the declaration handler or 0 if none was set.
+
+  \sa setDeclHandler()
+*/
+/*!
+  \fn bool QXmlReader::parse( const QXmlInputSource& input )
+
+  Parses the XML document \a input. Returns TRUE if the parsing was successful,
+  otherwise FALSE.
+*/
+/*!
+  \fn bool QXmlReader::parse( const QString& systemId )
+
+  Parses the XML document at the location \a systemId. Returns TRUE if the
+  parsing was successful, otherwise FALSE.
+*/
+
+
+/*!
+  \class QXmlSimpleReader qxml.h
+  \brief The QXmlSimpleReader class provides an implementation of a simple XML
+  reader (i.e. parser).
+
+  \module XML
+
+  This XML reader is sufficient for simple parsing tasks. Here is a short list
+  of the properties of this reader:
+  <ul>
+  <li> well-formed parser
+  <li> does not parse any external entities
+  <li> can do namespace processing
+  </ul>
+
+  For getting started see also the
+  <a href="xml-sax.html#quickStart">Quick start</a>.
+*/
+
+//guaranteed not to be a characater
+const QChar QXmlSimpleReader::QEOF = QChar((ushort)0xffff);
+
+/*!
+  Constructs a simple XML reader.
+*/
+QXmlSimpleReader::QXmlSimpleReader()
+{
+    d = new QXmlSimpleReaderPrivate();
+    d->locator = new QXmlLocator( this );
+
+    entityRes  = 0;
+    dtdHnd     = 0;
+    contentHnd = 0;
+    errorHnd   = 0;
+    lexicalHnd = 0;
+    declHnd    = 0;
+
+    // default feature settings
+    d->useNamespaces = TRUE;
+    d->useNamespacePrefixes = FALSE;
+    d->reportWhitespaceCharData = TRUE;
+}
+
+/*!
+  Destroys a simple XML reader.
+*/
+QXmlSimpleReader::~QXmlSimpleReader()
+{
+    delete d->locator;
+    delete d;
+}
+
+/*!
+  Gets the state of a feature.
+
+  \sa setFeature() hasFeature()
+*/
+bool QXmlSimpleReader::feature( const QString& name, bool *ok ) const
+{
+    if ( ok != 0 )
+	*ok = TRUE;
+    if        ( name == "http://xml.org/sax/features/namespaces" ) {
+	return d->useNamespaces;
+    } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+	return d->useNamespacePrefixes;
+    } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+	return d->reportWhitespaceCharData;
+    } else {
+	qWarning( "Unknown feature " + name );
+	if ( ok != 0 )
+	    *ok = FALSE;
+    }
+    return FALSE;
+}
+
+/*!
+  Sets the state of a feature.
+
+  Supported features are:
+  <ul>
+  <li> http://xml.org/sax/features/namespaces:
+       if this feature is TRUE, namespace processing is performed
+  <li> http://xml.org/sax/features/namespace-prefixes:
+       if this feature is TRUE, the the original prefixed names and attributes
+       used for namespace declarations are reported
+  <li> http://trolltech.com/xml/features/report-whitespace-only-CharData:
+       if this feature is TRUE, CharData that consists only of whitespace (and
+       no other characters) is not reported via
+       QXmlContentHandler::characters()
+  </ul>
+
+  \sa feature() hasFeature()
+*/
+void QXmlSimpleReader::setFeature( const QString& name, bool value )
+{
+    if        ( name == "http://xml.org/sax/features/namespaces" ) {
+	d->useNamespaces = value;
+    } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+	d->useNamespacePrefixes = value;
+    } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+	d->reportWhitespaceCharData = value;
+    } else {
+	qWarning( "Unknown feature " + name );
+    }
+}
+
+/*!
+  Returns TRUE if the class has a feature named \a feature, otherwise FALSE.
+
+  \sa setFeature() feature()
+*/
+bool QXmlSimpleReader::hasFeature( const QString& name ) const
+{
+    if (    name == "http://xml.org/sax/features/namespaces" ||
+	    name == "http://xml.org/sax/features/namespace-prefixes" ||
+	    name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+	return TRUE;
+    } else {
+	return FALSE;
+    }
+}
+
+/*!
+  Returns 0 since this class does not support any properties.
+*/
+void* QXmlSimpleReader::property( const QString&, bool *ok ) const
+{
+    if ( ok != 0 )
+	*ok = FALSE;
+    return 0;
+}
+
+/*!
+  Does nothing since this class does not support any properties.
+*/
+void QXmlSimpleReader::setProperty( const QString&, void* )
+{
+}
+
+/*!
+  Returns FALSE since this class does not support any properties.
+*/
+bool QXmlSimpleReader::hasProperty( const QString& ) const
+{
+    return FALSE;
+}
+
+/*! \reimp */
+void QXmlSimpleReader::setEntityResolver( QXmlEntityResolver* handler )
+{ entityRes = handler; }
+
+/*! \reimp */
+QXmlEntityResolver* QXmlSimpleReader::entityResolver() const
+{ return entityRes; }
+
+/*! \reimp */
+void QXmlSimpleReader::setDTDHandler( QXmlDTDHandler* handler )
+{ dtdHnd = handler; }
+
+/*! \reimp */
+QXmlDTDHandler* QXmlSimpleReader::DTDHandler() const
+{ return dtdHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setContentHandler( QXmlContentHandler* handler )
+{ contentHnd = handler; }
+
+/*! \reimp */
+QXmlContentHandler* QXmlSimpleReader::contentHandler() const
+{ return contentHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setErrorHandler( QXmlErrorHandler* handler )
+{ errorHnd = handler; }
+
+/*! \reimp */
+QXmlErrorHandler* QXmlSimpleReader::errorHandler() const
+{ return errorHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setLexicalHandler( QXmlLexicalHandler* handler )
+{ lexicalHnd = handler; }
+
+/*! \reimp */
+QXmlLexicalHandler* QXmlSimpleReader::lexicalHandler() const
+{ return lexicalHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setDeclHandler( QXmlDeclHandler* handler )
+{ declHnd = handler; }
+
+/*! \reimp */
+QXmlDeclHandler* QXmlSimpleReader::declHandler() const
+{ return declHnd; }
+
+
+
+/*! \reimp */
+bool QXmlSimpleReader::parse( const QXmlInputSource& input )
+{
+    init( input );
+    // call the handler
+    if ( contentHnd ) {
+	contentHnd->setDocumentLocator( d->locator );
+	if ( !contentHnd->startDocument() ) {
+	    d->error = contentHnd->errorString();
+	    goto parseError;
+	}
+    }
+    // parse prolog
+    if ( !parseProlog() ) {
+	d->error = XMLERR_ERRORPARSINGPROLOG;
+	goto parseError;
+    }
+    // parse element
+    if ( !parseElement() ) {
+	d->error = XMLERR_ERRORPARSINGMAINELEMENT;
+	goto parseError;
+    }
+    // parse Misc*
+    while ( !atEnd() ) {
+	if ( !parseMisc() ) {
+	    d->error = XMLERR_ERRORPARSINGMISC;
+	    goto parseError;
+	}
+    }
+    // is stack empty?
+    if ( !tags.isEmpty() ) {
+	d->error = XMLERR_UNEXPECTEDEOF;
+	goto parseError;
+    }
+    // call the handler
+    if ( contentHnd ) {
+	if ( !contentHnd->endDocument() ) {
+	    d->error = contentHnd->errorString();
+	    goto parseError;
+	}
+    }
+
+    return TRUE;
+
+    // error handling
+
+parseError:
+    reportParseError();
+    tags.clear();
+    return FALSE;
+}
+
+/*!
+  Parses the prolog [22].
+*/
+bool QXmlSimpleReader::parseProlog()
+{
+    bool xmldecl_possible = TRUE;
+    bool doctype_read = FALSE;
+
+    const signed char Init             = 0;
+    const signed char EatWS            = 1; // eat white spaces
+    const signed char Lt               = 2; // '<' read
+    const signed char Em               = 3; // '!' read
+    const signed char DocType          = 4; // read doctype
+    const signed char Comment          = 5; // read comment
+    const signed char PI               = 6; // read PI
+    const signed char Done             = 7;
+
+    const signed char InpWs            = 0;
+    const signed char InpLt            = 1; // <
+    const signed char InpQm            = 2; // ?
+    const signed char InpEm            = 3; // !
+    const signed char InpD             = 4; // D
+    const signed char InpDash          = 5; // -
+    const signed char InpUnknown       = 6;
+
+    // use some kind of state machine for parsing
+    static signed char table[7][7] = {
+     /*  InpWs   InpLt  InpQm  InpEm  InpD      InpDash  InpUnknown */
+	{ EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }, // Init
+	{ -1,     Lt,    -1,    -1,    -1,       -1,       -1      }, // EatWS
+	{ -1,     -1,    PI,    Em,    Done,     -1,       Done    }, // Lt
+	{ -1,     -1,    -1,    -1,    DocType,  Comment,  -1      }, // Em
+	{ EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }, // DocType
+	{ EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }, // Comment
+	{ EatWS,  Lt,    -1,    -1,    -1,       -1,       -1      }  // PI
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// read input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '<' ) {
+	    input = InpLt;
+	} else if ( c == '?' ) {
+	    input = InpQm;
+	} else if ( c == '!' ) {
+	    input = InpEm;
+	} else if ( c == 'D' ) {
+	    input = InpD;
+	} else if ( c == '-' ) {
+	    input = InpDash;
+	} else {
+	    input = InpUnknown;
+	}
+	// get new state
+	state = table[state][input];
+
+	// in some cases do special actions depending on state
+	switch ( state ) {
+	    case EatWS:
+		// XML declaration only on first position possible
+		xmldecl_possible = FALSE;
+		// eat white spaces
+		eat_ws();
+		break;
+	    case Lt:
+		// next character
+		next();
+		break;
+	    case Em:
+		// XML declaration only on first position possible
+		xmldecl_possible = FALSE;
+		// next character
+		next();
+		break;
+	    case DocType:
+		parseOk = parseDoctype();
+		break;
+	    case Comment:
+		parseOk = parseComment();
+		break;
+	    case PI:
+		parseOk = parsePI( xmldecl_possible );
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case DocType:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGPROLOG;
+		    goto parseError;
+		}
+		if ( doctype_read ) {
+		    d->error = XMLERR_MORETHANONEDOCTYPE;
+		    goto parseError;
+		} else {
+		    doctype_read = FALSE;
+		}
+		break;
+	    case Comment:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGPROLOG;
+		    goto parseError;
+		}
+		if ( lexicalHnd ) {
+		    if ( !lexicalHnd->comment( string() ) ) {
+			d->error = lexicalHnd->errorString();
+			goto parseError;
+		    }
+		}
+		break;
+	    case PI:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGPROLOG;
+		    goto parseError;
+		}
+		// call the handler
+		if ( contentHnd ) {
+		    if ( xmldecl_possible && !d->xmlVersion.isEmpty() ) {
+			QString value( "version = '" );
+			value += d->xmlVersion;
+			value += "'";
+			if ( !d->encoding.isEmpty() ) {
+			    value += " encoding = '";
+			    value += d->encoding;
+			    value += "'";
+			}
+			if ( d->standalone == QXmlSimpleReaderPrivate::Yes ) {
+			    value += " standalone = 'yes'";
+			} else if ( d->standalone == QXmlSimpleReaderPrivate::No ) {
+			    value += " standalone = 'no'";
+			}
+			if ( !contentHnd->processingInstruction( "xml", value ) ) {
+			    d->error = contentHnd->errorString();
+			    goto parseError;
+			}
+		    } else {
+			if ( !contentHnd->processingInstruction( name(), string() ) ) {
+			    d->error = contentHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		}
+		// XML declaration only on first position possible
+		xmldecl_possible = FALSE;
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		d->error = XMLERR_ERRORPARSINGELEMENT;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse an element [39].
+
+  Precondition: the opening '<' is already read.
+*/
+bool QXmlSimpleReader::parseElement()
+{
+    static QString uri, lname, prefix;
+    static bool t;
+
+    const signed char Init             =  0;
+    const signed char ReadName         =  1;
+    const signed char Ws1              =  2;
+    const signed char STagEnd          =  3;
+    const signed char STagEnd2         =  4;
+    const signed char ETagBegin        =  5;
+    const signed char ETagBegin2       =  6;
+    const signed char Ws2              =  7;
+    const signed char EmptyTag         =  8;
+    const signed char Attribute        =  9;
+    const signed char Ws3              = 10;
+    const signed char Done             = 11;
+
+    const signed char InpWs            = 0; // whitespace
+    const signed char InpNameBe        = 1; // is_NameBeginning()
+    const signed char InpGt            = 2; // >
+    const signed char InpSlash         = 3; // /
+    const signed char InpUnknown       = 4;
+
+    // use some kind of state machine for parsing
+    static signed char table[11][5] = {
+     /*  InpWs      InpNameBe    InpGt        InpSlash     InpUnknown */
+	{ -1,        ReadName,    -1,          -1,          -1        }, // Init
+	{ Ws1,       Attribute,   STagEnd,     EmptyTag,    -1        }, // ReadName
+	{ -1,        Attribute,   STagEnd,     EmptyTag,    -1        }, // Ws1
+	{ STagEnd2,  STagEnd2,    STagEnd2,    STagEnd2,    STagEnd2  }, // STagEnd
+	{ -1,        -1,          -1,          ETagBegin,   -1        }, // STagEnd2
+	{ -1,        ETagBegin2,  -1,          -1,          -1        }, // ETagBegin
+	{ Ws2,       -1,          Done,        -1,          -1        }, // ETagBegin2
+	{ -1,        -1,          Done,        -1,          -1        }, // Ws2
+	{ -1,        -1,          Done,        -1,          -1        }, // EmptyTag
+	{ Ws3,       Attribute,   STagEnd,     EmptyTag,    -1        }, // Attribute
+	{ -1,        Attribute,   STagEnd,     EmptyTag,    -1        }  // Ws3
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// read input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( is_NameBeginning(c) ) {
+	    input = InpNameBe;
+	} else if ( c == '>' ) {
+	    input = InpGt;
+	} else if ( c == '/' ) {
+	    input = InpSlash;
+	} else {
+	    input = InpUnknown;
+	}
+	// get new state
+//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
+	state = table[state][input];
+
+	// in some cases do special actions depending on state
+	switch ( state ) {
+	    case ReadName:
+		parseOk = parseName();
+		break;
+	    case Ws1:
+	    case Ws2:
+	    case Ws3:
+		eat_ws();
+		break;
+	    case STagEnd:
+		// call the handler
+		if ( contentHnd ) {
+		    if ( d->useNamespaces ) {
+			d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
+			t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
+		    } else {
+			t = contentHnd->startElement( "", "", tags.top(), d->attList );
+		    }
+		    if ( !t ) {
+			d->error = contentHnd->errorString();
+			goto parseError;
+		    }
+		}
+		next();
+		break;
+	    case STagEnd2:
+		parseOk = parseContent();
+		break;
+	    case ETagBegin:
+		next();
+		break;
+	    case ETagBegin2:
+		// get the name of the tag
+		parseOk = parseName();
+		break;
+	    case EmptyTag:
+		if  ( tags.isEmpty() ) {
+		    d->error = XMLERR_TAGMISMATCH;
+		    goto parseError;
+		}
+		if ( !parseElementEmptyTag( t, uri, lname ) )
+		    goto parseError;
+		// next character
+		next();
+		break;
+	    case Attribute:
+		// get name and value of attribute
+		parseOk = parseAttribute();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case ReadName:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		// store it on the stack
+		tags.push( name() );
+		// empty the attributes
+		d->attList.qnameList.clear();
+		d->attList.uriList.clear();
+		d->attList.localnameList.clear();
+		d->attList.valueList.clear();
+		// namespace support?
+		if ( d->useNamespaces ) {
+		    d->namespaceSupport.pushContext();
+		}
+		break;
+	    case STagEnd2:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGCONTENT;
+		    goto parseError;
+		}
+		break;
+	    case ETagBegin2:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		if ( !parseElementETagBegin2() )
+		    goto parseError;
+		break;
+	    case Attribute:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGATTRIBUTE;
+		    goto parseError;
+		}
+		if ( !parseElementAttribute( prefix, uri, lname ) )
+		    goto parseError;
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		d->error = XMLERR_ERRORPARSINGELEMENT;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+/*!
+  Helper to break down the size of the code in the case statement.
+  Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementEmptyTag( bool &t, QString &uri, QString &lname )
+{
+    // pop the stack and call the handler
+    if ( contentHnd ) {
+	// report startElement first...
+	if ( d->useNamespaces ) {
+	    d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
+	    t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
+	} else {
+	    t = contentHnd->startElement( "", "", tags.top(), d->attList );
+	}
+	if ( !t ) {
+	    d->error = contentHnd->errorString();
+	    return FALSE;
+	}
+	// ... followed by endElement
+	// ### missing namespace support!
+	if ( !contentHnd->endElement( "","",tags.pop() ) ) {
+	    d->error = contentHnd->errorString();
+	    return FALSE;
+	}
+	// namespace support?
+	if ( d->useNamespaces ) {
+	    QStringList prefixesBefore, prefixesAfter;
+	    if ( contentHnd ) {
+		prefixesBefore = d->namespaceSupport.prefixes();
+	    }
+	    d->namespaceSupport.popContext();
+	    // call the handler for prefix mapping
+	    if ( contentHnd ) {
+		prefixesAfter = d->namespaceSupport.prefixes();
+		for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+		    if ( prefixesAfter.contains(*it) == 0 ) {
+			if ( !contentHnd->endPrefixMapping( *it ) ) {
+			    d->error = contentHnd->errorString();
+			    return FALSE;
+			}
+		    }
+		}
+	    }
+	}
+    } else {
+	tags.pop();
+    }
+    return TRUE;
+}
+/*!
+  Helper to break down the size of the code in the case statement.
+  Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementETagBegin2()
+{
+
+    // pop the stack and compare it with the name
+    if ( tags.pop() != name() ) {
+	d->error = XMLERR_TAGMISMATCH;
+	return FALSE;
+    }
+    // call the handler
+    // ### missing namespace support!
+    if ( contentHnd ) {
+	if ( !contentHnd->endElement("","",name()) ) {
+	    d->error = contentHnd->errorString();
+	    return FALSE;
+	}
+    }
+    // namespace support?
+    if ( d->useNamespaces ) {
+	QStringList prefixesBefore, prefixesAfter;
+	if ( contentHnd ) {
+	    prefixesBefore = d->namespaceSupport.prefixes();
+	}
+	d->namespaceSupport.popContext();
+	// call the handler for prefix mapping
+	if ( contentHnd ) {
+	    prefixesAfter = d->namespaceSupport.prefixes();
+	    for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+		if ( prefixesAfter.contains(*it) == 0 ) {
+		    if ( !contentHnd->endPrefixMapping( *it ) ) {
+			d->error = contentHnd->errorString();
+			return FALSE;
+		    }
+		}
+	    }
+	}
+    }
+    return TRUE;
+}
+/*!
+  Helper to break down the size of the code in the case statement.
+  Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementAttribute( QString &prefix, QString &uri, QString &lname )
+{
+    // add the attribute to the list
+    if ( d->useNamespaces ) {
+	// is it a namespace declaration?
+	d->namespaceSupport.splitName( name(), prefix, lname );
+	if ( prefix == "xmlns" ) {
+	    // namespace declaration
+	    d->namespaceSupport.setPrefix( lname, string() );
+	    if ( d->useNamespacePrefixes ) {
+		d->attList.qnameList.append( name() );
+		d->attList.uriList.append( "" );
+		d->attList.localnameList.append( "" );
+		d->attList.valueList.append( string() );
+	    }
+	    // call the handler for prefix mapping
+	    if ( contentHnd ) {
+		if ( !contentHnd->startPrefixMapping( lname, string() ) ) {
+		    d->error = contentHnd->errorString();
+		    return FALSE;
+		}
+	    }
+	} else {
+	    // no namespace delcaration
+	    d->namespaceSupport.processName( name(), TRUE, uri, lname );
+	    d->attList.qnameList.append( name() );
+	    d->attList.uriList.append( uri );
+	    d->attList.localnameList.append( lname );
+	    d->attList.valueList.append( string() );
+	}
+    } else {
+	// no namespace support
+	d->attList.qnameList.append( name() );
+	d->attList.uriList.append( "" );
+	d->attList.localnameList.append( "" );
+	d->attList.valueList.append( string() );
+    }
+    return TRUE;
+}
+
+/*!
+  Parse a content [43].
+
+  A content is only used between tags. If a end tag is found the < is already
+  read and the head stand on the '/' of the end tag '</name>'.
+*/
+bool QXmlSimpleReader::parseContent()
+{
+    bool charDataRead = FALSE;
+
+    const signed char Init             =  0;
+    const signed char ChD              =  1; // CharData
+    const signed char ChD1             =  2; // CharData help state
+    const signed char ChD2             =  3; // CharData help state
+    const signed char Ref              =  4; // Reference
+    const signed char Lt               =  5; // '<' read
+    const signed char PI               =  6; // PI
+    const signed char Elem             =  7; // Element
+    const signed char Em               =  8; // '!' read
+    const signed char Com              =  9; // Comment
+    const signed char CDS              = 10; // CDSect
+    const signed char CDS1             = 11; // read a CDSect
+    const signed char CDS2             = 12; // read a CDSect (help state)
+    const signed char CDS3             = 13; // read a CDSect (help state)
+    const signed char Done             = 14; // finished reading content
+
+    const signed char InpLt            = 0; // <
+    const signed char InpGt            = 1; // >
+    const signed char InpSlash         = 2; // /
+    const signed char InpQMark         = 3; // ?
+    const signed char InpEMark         = 4; // !
+    const signed char InpAmp           = 5; // &
+    const signed char InpDash          = 6; // -
+    const signed char InpOpenB         = 7; // [
+    const signed char InpCloseB        = 8; // ]
+    const signed char InpUnknown       = 9;
+
+    static signed char mapCLT2FSMChar[] = {
+	InpUnknown, // white space
+	InpUnknown, // %
+	InpAmp,     // &
+	InpGt,      // >
+	InpLt,      // <
+	InpSlash,   // /
+	InpQMark,   // ?
+	InpEMark,   // !
+	InpDash,    // -
+	InpCloseB,  // ]
+	InpOpenB,   // [
+	InpUnknown, // =
+	InpUnknown, // "
+	InpUnknown, // '
+	InpUnknown  // unknown
+    };
+
+    // use some kind of state machine for parsing
+    static signed char const table[14][10] = {
+     /*  InpLt  InpGt  InpSlash  InpQMark  InpEMark  InpAmp  InpDash  InpOpenB  InpCloseB  InpUnknown */
+	{ Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD1,      ChD  }, // Init
+	{ Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD1,      ChD  }, // ChD
+	{ Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD2,      ChD  }, // ChD1
+	{ Lt,    -1,    ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD2,      ChD  }, // ChD2
+	{ Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // Ref (same as Init)
+	{ -1,    -1,    Done,     PI,       Em,       -1,     -1,      -1,       -1,        Elem }, // Lt
+	{ Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // PI (same as Init)
+	{ Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // Elem (same as Init)
+	{ -1,    -1,    -1,       -1,       -1,       -1,     Com,     CDS,      -1,        -1   }, // Em
+	{ Lt,    ChD,   ChD,      ChD,      ChD,      Ref,    ChD,     ChD,      ChD,       ChD  }, // Com (same as Init)
+	{ CDS1,  CDS1,  CDS1,     CDS1,     CDS1,     CDS1,   CDS1,    CDS1,     CDS2,      CDS1 }, // CDS
+	{ CDS1,  CDS1,  CDS1,     CDS1,     CDS1,     CDS1,   CDS1,    CDS1,     CDS2,      CDS1 }, // CDS1
+	{ CDS1,  CDS1,  CDS1,     CDS1,     CDS1,     CDS1,   CDS1,    CDS1,     CDS3,      CDS1 }, // CDS2
+	{ CDS1,  Init,  CDS1,     CDS1,     CDS1,     CDS1,   CDS1,    CDS1,     CDS3,      CDS1 }  // CDS3
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input (use lookup-table instead of nested ifs for performance
+	// reasons)
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if ( c.row() ) {
+	    input = InpUnknown;
+	} else {
+	    input = mapCLT2FSMChar[ charLookupTable[ c.cell() ] ];
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Init:
+		// next character
+		next();
+		break;
+	    case ChD:
+		// on first call: clear string
+		if ( !charDataRead ) {
+		    charDataRead = TRUE;
+		    stringClear();
+		}
+		stringAddC();
+		next();
+		break;
+	    case ChD1:
+		// on first call: clear string
+		if ( !charDataRead ) {
+		    charDataRead = TRUE;
+		    stringClear();
+		}
+		stringAddC();
+		next();
+		break;
+	    case ChD2:
+		stringAddC();
+		next();
+		break;
+	    case Ref:
+		// reference may be CharData; so clear string to be safe
+		if ( !charDataRead) {
+		    charDataRead = TRUE;
+		    stringClear();
+		}
+		// parse reference
+		parseOk = parseReference( charDataRead, InContent );
+		break;
+	    case Lt:
+		// call the handler for CharData
+		if ( contentHnd ) {
+		    if ( charDataRead ) {
+			if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+			    if ( !contentHnd->characters( string() ) ) {
+				d->error = contentHnd->errorString();
+				goto parseError;
+			    }
+			}
+		    }
+		}
+		charDataRead = FALSE;
+		// next character
+		next();
+		break;
+	    case PI:
+		parseOk = parsePI();
+		break;
+	    case Elem:
+		parseOk = parseElement();
+		break;
+	    case Em:
+		// next character
+		next();
+		break;
+	    case Com:
+		parseOk = parseComment();
+		break;
+	    case CDS:
+		parseOk = parseString( "[CDATA[" );
+		break;
+	    case CDS1:
+		// read one character and add it
+		stringAddC();
+		next();
+		break;
+	    case CDS2:
+		// skip ']'
+		next();
+		break;
+	    case CDS3:
+		// skip ']'...
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Ref:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGREFERENCE;
+		    goto parseError;
+		}
+		break;
+	    case PI:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGPI;
+		    goto parseError;
+		}
+		// call the handler
+		if ( contentHnd ) {
+		    if ( !contentHnd->processingInstruction(name(),string()) ) {
+			d->error = contentHnd->errorString();
+			goto parseError;
+		    }
+		}
+		break;
+	    case Elem:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGELEMENT;
+		    goto parseError;
+		}
+		break;
+	    case Com:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGCOMMENT;
+		    goto parseError;
+		}
+		if ( lexicalHnd ) {
+		    if ( !lexicalHnd->comment( string() ) ) {
+			d->error = lexicalHnd->errorString();
+			goto parseError;
+		    }
+		}
+		break;
+	    case CDS:
+		if( !parseOk ) {
+		    d->error = XMLERR_CDSECTHEADEREXPECTED;
+		    goto parseError;
+		}
+		// empty string
+		stringClear();
+		break;
+	    case CDS2:
+		if (c != ']') {
+		    stringAddC( ']' );
+		}
+		break;
+	    case CDS3:
+		// test if this skipping was legal
+		if        ( c == '>' ) {
+		    // the end of the CDSect
+		    if ( lexicalHnd ) {
+			if ( !lexicalHnd->startCDATA() ) {
+			    d->error = lexicalHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		    if ( contentHnd ) {
+			if ( !contentHnd->characters( string() ) ) {
+			    d->error = contentHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		    if ( lexicalHnd ) {
+			if ( !lexicalHnd->endCDATA() ) {
+			    d->error = lexicalHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		} else if (c == ']') {
+		    // three or more ']'
+		    stringAddC( ']' );
+		} else {
+		    // after ']]' comes another character
+		    stringAddC( ']' );
+		    stringAddC( ']' );
+		}
+		break;
+	    case Done:
+		// call the handler for CharData
+		if ( contentHnd ) {
+		    if ( charDataRead ) {
+			if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+			    if ( !contentHnd->characters( string() ) ) {
+				d->error = contentHnd->errorString();
+				goto parseError;
+			    }
+			}
+		    }
+		}
+		// Done
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_ERRORPARSINGCONTENT;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse Misc [27].
+*/
+bool QXmlSimpleReader::parseMisc()
+{
+    const signed char Init             = 0;
+    const signed char Lt               = 1; // '<' was read
+    const signed char Comment          = 2; // read comment
+    const signed char eatWS            = 3; // eat whitespaces
+    const signed char PI               = 4; // read PI
+    const signed char Comment2         = 5; // read comment
+
+    const signed char InpWs            = 0; // S
+    const signed char InpLt            = 1; // <
+    const signed char InpQm            = 2; // ?
+    const signed char InpEm            = 3; // !
+    const signed char InpUnknown       = 4;
+
+    // use some kind of state machine for parsing
+    static signed char table[3][5] = {
+     /*  InpWs   InpLt  InpQm  InpEm     InpUnknown */
+	{ eatWS,  Lt,    -1,    -1,       -1        }, // Init
+	{ -1,     -1,    PI,    Comment,  -1        }, // Lt
+	{ -1,     -1,    -1,    -1,       Comment2  }  // Comment
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '<' ) {
+	    input = InpLt;
+	} else if ( c == '?' ) {
+	    input = InpQm;
+	} else if ( c == '!' ) {
+	    input = InpEm;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case eatWS:
+		eat_ws();
+		break;
+	    case Lt:
+		next();
+		break;
+	    case PI:
+		parseOk = parsePI();
+		break;
+	    case Comment:
+		next();
+		break;
+	    case Comment2:
+		parseOk = parseComment();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case eatWS:
+		return TRUE;
+	    case PI:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGPI;
+		    goto parseError;
+		}
+		return TRUE;
+	    case Comment2:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGCOMMENT;
+		    goto parseError;
+		}
+		if ( lexicalHnd ) {
+		    if ( !lexicalHnd->comment( string() ) ) {
+			d->error = lexicalHnd->errorString();
+			goto parseError;
+		    }
+		}
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_UNEXPECTEDCHARACTER;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a processing instruction [16].
+
+  If xmldec is TRUE, it tries to parse a PI or a XML declaration [23].
+
+  Precondition: the beginning '<' of the PI is already read and the head stand
+  on the '?' of '<?'.
+
+  If this funktion was successful, the head-position is on the first
+  character after the PI.
+*/
+bool QXmlSimpleReader::parsePI( bool xmldecl )
+{
+    const signed char Init             =  0;
+    const signed char QmI              =  1; // ? was read
+    const signed char Name             =  2; // read Name
+    const signed char XMLDecl          =  3; // read XMLDecl
+    const signed char Ws1              =  4; // eat ws after "xml" of XMLDecl
+    const signed char PI               =  5; // read PI
+    const signed char Ws2              =  6; // eat ws after Name of PI
+    const signed char Version          =  7; // read versionInfo
+    const signed char Ws3              =  8; // eat ws after versionInfo
+    const signed char EorSD            =  9; // read EDecl or SDDecl
+    const signed char Ws4              = 10; // eat ws after EDecl or SDDecl
+    const signed char SD               = 11; // read SDDecl
+    const signed char Ws5              = 12; // eat ws after SDDecl
+    const signed char ADone            = 13; // almost done
+    const signed char Char             = 14; // Char was read
+    const signed char Qm               = 15; // Qm was read
+    const signed char Done             = 16; // finished reading content
+
+    const signed char InpWs            = 0; // whitespace
+    const signed char InpNameBe        = 1; // is_nameBeginning()
+    const signed char InpGt            = 2; // >
+    const signed char InpQm            = 3; // ?
+    const signed char InpUnknown       = 4;
+
+    // use some kind of state machine for parsing
+    static signed char table[16][5] = {
+     /*  InpWs,  InpNameBe  InpGt  InpQm   InpUnknown  */
+	{ -1,     -1,        -1,    QmI,    -1     }, // Init
+	{ -1,     Name,      -1,    -1,     -1     }, // QmI
+	{ -1,     -1,        -1,    -1,     -1     }, // Name (this state is left not through input)
+	{ Ws1,    -1,        -1,    -1,     -1     }, // XMLDecl
+	{ -1,     Version,   -1,    -1,     -1     }, // Ws1
+	{ Ws2,    -1,        -1,    Qm,     -1     }, // PI
+	{ Char,   Char,      Char,  Qm,     Char   }, // Ws2
+	{ Ws3,    -1,        -1,    ADone,  -1     }, // Version
+	{ -1,     EorSD,     -1,    ADone,  -1     }, // Ws3
+	{ Ws4,    -1,        -1,    ADone,  -1     }, // EorSD
+	{ -1,     SD,        -1,    ADone,  -1     }, // Ws4
+	{ Ws5,    -1,        -1,    ADone,  -1     }, // SD
+	{ -1,     -1,        -1,    ADone,  -1     }, // Ws5
+	{ -1,     -1,        Done,  -1,     -1     }, // ADone
+	{ Char,   Char,      Char,  Qm,     Char   }, // Char
+	{ Char,   Char,      Done,  Qm,     Char   }, // Qm
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( is_NameBeginning(c) ) {
+	    input = InpNameBe;
+	} else if ( c == '>' ) {
+	    input = InpGt;
+	} else if ( c == '?' ) {
+	    input = InpQm;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case QmI:
+		next();
+		break;
+	    case Name:
+		parseOk = parseName();
+		break;
+	    case Ws1:
+	    case Ws2:
+	    case Ws3:
+	    case Ws4:
+	    case Ws5:
+		eat_ws();
+		break;
+	    case Version:
+		parseOk = parseAttribute();
+		break;
+	    case EorSD:
+		parseOk = parseAttribute();
+		break;
+	    case SD:
+		// get the SDDecl (syntax like an attribute)
+		if ( d->standalone != QXmlSimpleReaderPrivate::Unknown ) {
+		    // already parsed the standalone declaration
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		parseOk = parseAttribute();
+		break;
+	    case ADone:
+		next();
+		break;
+	    case Char:
+		stringAddC();
+		next();
+		break;
+	    case Qm:
+		// skip the '?'
+		next();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Name:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		// test what name was read and determine the next state
+		// (not very beautiful, I admit)
+		if ( name().lower() == "xml" ) {
+		    if ( xmldecl && name()=="xml" ) {
+			state = XMLDecl;
+		    } else {
+			d->error = XMLERR_INVALIDNAMEFORPI;
+			goto parseError;
+		    }
+		} else {
+		    state = PI;
+		    stringClear();
+		}
+		break;
+	    case Version:
+		// get version (syntax like an attribute)
+		if ( !parseOk ) {
+		    d->error = XMLERR_VERSIONEXPECTED;
+		    goto parseError;
+		}
+		if ( name() != "version" ) {
+		    d->error = XMLERR_VERSIONEXPECTED;
+		    goto parseError;
+		}
+		d->xmlVersion = string();
+		break;
+	    case EorSD:
+		// get the EDecl or SDDecl (syntax like an attribute)
+		if ( !parseOk ) {
+		    d->error = XMLERR_EDECLORSDDECLEXPECTED;
+		    goto parseError;
+		}
+		if        ( name() == "standalone" ) {
+		    if ( string()=="yes" ) {
+			d->standalone = QXmlSimpleReaderPrivate::Yes;
+		    } else if ( string()=="no" ) {
+			d->standalone = QXmlSimpleReaderPrivate::No;
+		    } else {
+			d->error = XMLERR_WRONGVALUEFORSDECL;
+			goto parseError;
+		    }
+		} else if ( name() == "encoding" ) {
+		    d->encoding = string();
+		} else {
+		    d->error = XMLERR_EDECLORSDDECLEXPECTED;
+		    goto parseError;
+		}
+		break;
+	    case SD:
+		if ( !parseOk ) {
+		    d->error = XMLERR_SDDECLEXPECTED;
+		    goto parseError;
+		}
+		if ( name() != "standalone" ) {
+		    d->error = XMLERR_SDDECLEXPECTED;
+		    goto parseError;
+		}
+		if ( string()=="yes" ) {
+		    d->standalone = QXmlSimpleReaderPrivate::Yes;
+		} else if ( string()=="no" ) {
+		    d->standalone = QXmlSimpleReaderPrivate::No;
+		} else {
+		    d->error = XMLERR_WRONGVALUEFORSDECL;
+		    goto parseError;
+		}
+		break;
+	    case Qm:
+		// test if the skipping was legal
+		if ( c != '>' ) {
+		    stringAddC( '?' );
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_UNEXPECTEDCHARACTER;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a document type definition (doctypedecl [28]).
+
+  Precondition: the beginning '<!' of the doctype is already read the head
+  stands on the 'D' of '<!DOCTYPE'.
+
+  If this funktion was successful, the head-position is on the first
+  character after the document type definition.
+*/
+bool QXmlSimpleReader::parseDoctype()
+{
+    // some init-stuff
+    d->systemId = "";
+    d->publicId = "";
+
+    const signed char Init             =  0;
+    const signed char Doctype          =  1; // read the doctype
+    const signed char Ws1              =  2; // eat_ws
+    const signed char Doctype2         =  3; // read the doctype, part 2
+    const signed char Ws2              =  4; // eat_ws
+    const signed char Sys              =  5; // read SYSTEM
+    const signed char Ws3              =  6; // eat_ws
+    const signed char MP               =  7; // markupdecl or PEReference
+    const signed char PER              =  8; // PERReference
+    const signed char Mup              =  9; // markupdecl
+    const signed char Ws4              = 10; // eat_ws
+    const signed char MPE              = 11; // end of markupdecl or PEReference
+    const signed char Done             = 12;
+
+    const signed char InpWs            = 0;
+    const signed char InpD             = 1; // 'D'
+    const signed char InpS             = 2; // 'S' or 'P'
+    const signed char InpOB            = 3; // [
+    const signed char InpCB            = 4; // ]
+    const signed char InpPer           = 5; // %
+    const signed char InpGt            = 6; // >
+    const signed char InpUnknown       = 7;
+
+    // use some kind of state machine for parsing
+    static signed char table[12][8] = {
+     /*  InpWs,  InpD       InpS       InpOB  InpCB  InpPer InpGt  InpUnknown */
+	{ -1,     Doctype,   -1,        -1,    -1,    -1,    -1,    -1        }, // Init
+	{ Ws1,    Doctype2,  Doctype2,  -1,    -1,    -1,    -1,    Doctype2  }, // Doctype
+	{ -1,     Doctype2,  Doctype2,  -1,    -1,    -1,    -1,    Doctype2  }, // Ws1
+	{ Ws2,    -1,        Sys,       MP,    -1,    -1,    Done,  -1        }, // Doctype2
+	{ -1,     -1,        Sys,       MP,    -1,    -1,    Done,  -1        }, // Ws2
+	{ Ws3,    -1,        -1,        MP,    -1,    -1,    Done,  -1        }, // Sys
+	{ -1,     -1,        -1,        MP,    -1,    -1,    Done,  -1        }, // Ws3
+	{ -1,     -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // MP
+	{ Ws4,    -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // PER
+	{ Ws4,    -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // Mup
+	{ -1,     -1,        -1,        -1,    MPE,   PER,   -1,    Mup       }, // Ws4
+	{ -1,     -1,        -1,        -1,    -1,    -1,    Done,  -1        }  // MPE
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == 'D' ) {
+	    input = InpD;
+	} else if ( c == 'S' ) {
+	    input = InpS;
+	} else if ( c == 'P' ) {
+	    input = InpS;
+	} else if ( c == '[' ) {
+	    input = InpOB;
+	} else if ( c == ']' ) {
+	    input = InpCB;
+	} else if ( c == '%' ) {
+	    input = InpPer;
+	} else if ( c == '>' ) {
+	    input = InpGt;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Doctype:
+		parseOk = parseString( "DOCTYPE" );
+		break;
+	    case Ws1:
+	    case Ws2:
+	    case Ws3:
+	    case Ws4:
+		eat_ws();
+		break;
+	    case Doctype2:
+		parseName();
+		break;
+	    case Sys:
+		parseOk = parseExternalID();
+		break;
+	    case MP:
+		next_eat_ws();
+		break;
+	    case PER:
+		parseOk = parsePEReference( InDTD );
+		break;
+	    case Mup:
+		parseOk = parseMarkupdecl();
+		break;
+	    case MPE:
+		next_eat_ws();
+		break;
+	    case Done:
+		if ( lexicalHnd ) {
+		    if ( !lexicalHnd->endDTD() ) {
+			d->error = lexicalHnd->errorString();
+			goto parseError;
+		    }
+		}
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Doctype:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGDOCTYPE;
+		    goto parseError;
+		}
+		if ( !is_S(c) ) {
+		    d->error = XMLERR_ERRORPARSINGDOCTYPE;
+		    goto parseError;
+		}
+		break;
+	    case Doctype2:
+		d->doctype = name();
+		if ( lexicalHnd ) {
+		    if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
+			d->error = lexicalHnd->errorString();
+			goto parseError;
+		    }
+		}
+		break;
+	    case Sys:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGDOCTYPE;
+		    goto parseError;
+		}
+		break;
+	    case PER:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGDOCTYPE;
+		    goto parseError;
+		}
+		break;
+	    case Mup:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGDOCTYPE;
+		    goto parseError;
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_ERRORPARSINGDOCTYPE;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a ExternalID [75].
+
+  If allowPublicID is TRUE parse ExternalID [75] or PublicID [83].
+*/
+bool QXmlSimpleReader::parseExternalID( bool allowPublicID )
+{
+    // some init-stuff
+    d->systemId = "";
+    d->publicId = "";
+
+    const signed char Init             =  0;
+    const signed char Sys              =  1; // parse 'SYSTEM'
+    const signed char SysWS            =  2; // parse the whitespace after 'SYSTEM'
+    const signed char SysSQ            =  3; // parse SystemLiteral with '
+    const signed char SysSQ2           =  4; // parse SystemLiteral with '
+    const signed char SysDQ            =  5; // parse SystemLiteral with "
+    const signed char SysDQ2           =  6; // parse SystemLiteral with "
+    const signed char Pub              =  7; // parse 'PUBLIC'
+    const signed char PubWS            =  8; // parse the whitespace after 'PUBLIC'
+    const signed char PubSQ            =  9; // parse PubidLiteral with '
+    const signed char PubSQ2           = 10; // parse PubidLiteral with '
+    const signed char PubDQ            = 11; // parse PubidLiteral with "
+    const signed char PubDQ2           = 12; // parse PubidLiteral with "
+    const signed char PubE             = 13; // finished parsing the PubidLiteral
+    const signed char PubWS2           = 14; // parse the whitespace after the PubidLiteral
+    const signed char PDone            = 15; // done if allowPublicID is TRUE
+    const signed char Done             = 16;
+
+    const signed char InpSQ            = 0; // '
+    const signed char InpDQ            = 1; // "
+    const signed char InpS             = 2; // S
+    const signed char InpP             = 3; // P
+    const signed char InpWs            = 4; // white space
+    const signed char InpUnknown       = 5;
+
+    // use some kind of state machine for parsing
+    static signed char table[15][6] = {
+     /*  InpSQ    InpDQ    InpS     InpP     InpWs     InpUnknown */
+	{ -1,      -1,      Sys,     Pub,     -1,       -1      }, // Init
+	{ -1,      -1,      -1,      -1,      SysWS,    -1      }, // Sys
+	{ SysSQ,   SysDQ,   -1,      -1,      -1,       -1      }, // SysWS
+	{ Done,    SysSQ2,  SysSQ2,  SysSQ2,  SysSQ2,   SysSQ2  }, // SysSQ
+	{ Done,    SysSQ2,  SysSQ2,  SysSQ2,  SysSQ2,   SysSQ2  }, // SysSQ2
+	{ SysDQ2,  Done,    SysDQ2,  SysDQ2,  SysDQ2,   SysDQ2  }, // SysDQ
+	{ SysDQ2,  Done,    SysDQ2,  SysDQ2,  SysDQ2,   SysDQ2  }, // SysDQ2
+	{ -1,      -1,      -1,      -1,      PubWS,    -1      }, // Pub
+	{ PubSQ,   PubDQ,   -1,      -1,      -1,       -1      }, // PubWS
+	{ PubE,    -1,      PubSQ2,  PubSQ2,  PubSQ2,   PubSQ2  }, // PubSQ
+	{ PubE,    -1,      PubSQ2,  PubSQ2,  PubSQ2,   PubSQ2  }, // PubSQ2
+	{ -1,      PubE,    PubDQ2,  PubDQ2,  PubDQ2,   PubDQ2  }, // PubDQ
+	{ -1,      PubE,    PubDQ2,  PubDQ2,  PubDQ2,   PubDQ2  }, // PubDQ2
+	{ PDone,   PDone,   PDone,   PDone,   PubWS2,   PDone   }, // PubE
+	{ SysSQ,   SysDQ,   PDone,   PDone,   PDone,    PDone   }  // PubWS2
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '\'' ) {
+	    input = InpSQ;
+	} else if ( c == '"' ) {
+	    input = InpDQ;
+	} else if ( c == 'S' ) {
+	    input = InpS;
+	} else if ( c == 'P' ) {
+	    input = InpP;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Sys:
+		parseOk = parseString( "SYSTEM" );
+		break;
+	    case SysWS:
+		eat_ws();
+		break;
+	    case SysSQ:
+	    case SysDQ:
+		stringClear();
+		next();
+		break;
+	    case SysSQ2:
+	    case SysDQ2:
+		stringAddC();
+		next();
+		break;
+	    case Pub:
+		parseOk = parseString( "PUBLIC" );
+		break;
+	    case PubWS:
+		eat_ws();
+		break;
+	    case PubSQ:
+	    case PubDQ:
+		stringClear();
+		next();
+		break;
+	    case PubSQ2:
+	    case PubDQ2:
+		stringAddC();
+		next();
+		break;
+	    case PubE:
+		next();
+		break;
+	    case PubWS2:
+		d->publicId = string();
+		eat_ws();
+		break;
+	    case Done:
+		d->systemId = string();
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Sys:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Pub:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case PDone:
+		if ( allowPublicID ) {
+		    d->publicId = string();
+		    return TRUE;
+		} else {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_UNEXPECTEDCHARACTER;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a markupdecl [29].
+*/
+bool QXmlSimpleReader::parseMarkupdecl()
+{
+    const signed char Init             = 0;
+    const signed char Lt               = 1; // < was read
+    const signed char Em               = 2; // ! was read
+    const signed char CE               = 3; // E was read
+    const signed char Qm               = 4; // ? was read
+    const signed char Dash             = 5; // - was read
+    const signed char CA               = 6; // A was read
+    const signed char CEL              = 7; // EL was read
+    const signed char CEN              = 8; // EN was read
+    const signed char CN               = 9; // N was read
+    const signed char Done             = 10;
+
+    const signed char InpLt            = 0; // <
+    const signed char InpQm            = 1; // ?
+    const signed char InpEm            = 2; // !
+    const signed char InpDash          = 3; // -
+    const signed char InpA             = 4; // A
+    const signed char InpE             = 5; // E
+    const signed char InpL             = 6; // L
+    const signed char InpN             = 7; // N
+    const signed char InpUnknown       = 8;
+
+    // use some kind of state machine for parsing
+    static signed char table[4][9] = {
+     /*  InpLt  InpQm  InpEm  InpDash  InpA   InpE   InpL   InpN   InpUnknown */
+	{ Lt,    -1,    -1,    -1,      -1,    -1,    -1,    -1,    -1     }, // Init
+	{ -1,    Qm,    Em,    -1,      -1,    -1,    -1,    -1,    -1     }, // Lt
+	{ -1,    -1,    -1,    Dash,    CA,    CE,    -1,    CN,    -1     }, // Em
+	{ -1,    -1,    -1,    -1,      -1,    -1,    CEL,   CEN,   -1     }  // CE
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( c == '<' ) {
+	    input = InpLt;
+	} else if ( c == '?' ) {
+	    input = InpQm;
+	} else if ( c == '!' ) {
+	    input = InpEm;
+	} else if ( c == '-' ) {
+	    input = InpDash;
+	} else if ( c == 'A' ) {
+	    input = InpA;
+	} else if ( c == 'E' ) {
+	    input = InpE;
+	} else if ( c == 'L' ) {
+	    input = InpL;
+	} else if ( c == 'N' ) {
+	    input = InpN;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Lt:
+		next();
+		break;
+	    case Em:
+		next();
+		break;
+	    case CE:
+		next();
+		break;
+	    case Qm:
+		parseOk = parsePI();
+		break;
+	    case Dash:
+		parseOk = parseComment();
+		break;
+	    case CA:
+		parseOk = parseAttlistDecl();
+		break;
+	    case CEL:
+		parseOk = parseElementDecl();
+		break;
+	    case CEN:
+		parseOk = parseEntityDecl();
+		break;
+	    case CN:
+		parseOk = parseNotationDecl();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Qm:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGPI;
+		    goto parseError;
+		}
+		return TRUE;
+	    case Dash:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGCOMMENT;
+		    goto parseError;
+		}
+		if ( lexicalHnd ) {
+		    if ( !lexicalHnd->comment( string() ) ) {
+			d->error = lexicalHnd->errorString();
+			goto parseError;
+		    }
+		}
+		return TRUE;
+	    case CA:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGATTLISTDECL;
+		    goto parseError;
+		}
+		return TRUE;
+	    case CEL:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGELEMENTDECL;
+		    goto parseError;
+		}
+		return TRUE;
+	    case CEN:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGENTITYDECL;
+		    goto parseError;
+		}
+		return TRUE;
+	    case CN:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNOTATIONDECL;
+		    goto parseError;
+		}
+		return TRUE;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_LETTEREXPECTED;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a PEReference [69]
+*/
+bool QXmlSimpleReader::parsePEReference( EntityRecognitionContext context )
+{
+    const signed char Init             = 0;
+    const signed char Next             = 1;
+    const signed char Name             = 2;
+    const signed char Done             = 3;
+
+    const signed char InpSemi          = 0; // ;
+    const signed char InpPer           = 1; // %
+    const signed char InpUnknown       = 2;
+
+    // use some kind of state machine for parsing
+    static signed char table[3][3] = {
+     /*  InpSemi  InpPer  InpUnknown */
+	{ -1,      Next,   -1    }, // Init
+	{ -1,      -1,     Name  }, // Next
+	{ Done,    -1,     -1    }  // Name
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( c == ';' ) {
+	    input = InpSemi;
+	} else if ( c == '%' ) {
+	    input = InpPer;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Next:
+		next();
+		break;
+	    case Name:
+		parseOk = parseName( TRUE );
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Name:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		if ( d->parameterEntities.find( ref() ) == d->parameterEntities.end() ) {
+		    // ### skip it???
+		    if ( contentHnd ) {
+			if ( !contentHnd->skippedEntity( QString("%") + ref() ) ) {
+			    d->error = contentHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		} else {
+		    if        ( context == InEntityValue ) {
+			// Included in literal
+			xmlRef = d->parameterEntities.find( ref() )
+			    .data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
+			    + xmlRef;
+		    } else if ( context == InDTD ) {
+			// Included as PE ### correct???
+			xmlRef = QString(" ") +
+			    d->parameterEntities.find( ref() ).data() +
+			    QString(" ") + xmlRef;
+		    }
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_LETTEREXPECTED;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a AttlistDecl [52].
+
+  Precondition: the beginning '<!' is already read and the head
+  stands on the 'A' of '<!ATTLIST'
+*/
+bool QXmlSimpleReader::parseAttlistDecl()
+{
+    const signed char Init             =  0;
+    const signed char Attlist          =  1; // parse the string "ATTLIST"
+    const signed char Ws               =  2; // whitespace read
+    const signed char Name             =  3; // parse name
+    const signed char Ws1              =  4; // whitespace read
+    const signed char Attdef           =  5; // parse the AttDef
+    const signed char Ws2              =  6; // whitespace read
+    const signed char Atttype          =  7; // parse the AttType
+    const signed char Ws3              =  8; // whitespace read
+    const signed char DDecH            =  9; // DefaultDecl with #
+    const signed char DefReq           = 10; // parse the string "REQUIRED"
+    const signed char DefImp           = 11; // parse the string "IMPLIED"
+    const signed char DefFix           = 12; // parse the string "FIXED"
+    const signed char Attval           = 13; // parse the AttValue
+    const signed char Ws4              = 14; // whitespace read
+    const signed char Done             = 15;
+
+    const signed char InpWs            = 0; // white space
+    const signed char InpGt            = 1; // >
+    const signed char InpHash          = 2; // #
+    const signed char InpA             = 3; // A
+    const signed char InpI             = 4; // I
+    const signed char InpF             = 5; // F
+    const signed char InpR             = 6; // R
+    const signed char InpUnknown       = 7;
+
+    // use some kind of state machine for parsing
+    static signed char table[15][8] = {
+     /*  InpWs    InpGt    InpHash  InpA      InpI     InpF     InpR     InpUnknown */
+	{ -1,      -1,      -1,      Attlist,  -1,      -1,      -1,      -1      }, // Init
+	{ Ws,      -1,      -1,      -1,       -1,      -1,      -1,      -1      }, // Attlist
+	{ -1,      -1,      -1,      Name,     Name,    Name,    Name,    Name    }, // Ws
+	{ Ws1,     Done,    Attdef,  Attdef,   Attdef,  Attdef,  Attdef,  Attdef  }, // Name
+	{ -1,      Done,    Attdef,  Attdef,   Attdef,  Attdef,  Attdef,  Attdef  }, // Ws1
+	{ Ws2,     -1,      -1,      -1,       -1,      -1,      -1,      -1      }, // Attdef
+	{ -1,      Atttype, Atttype, Atttype,  Atttype, Atttype, Atttype, Atttype }, // Ws2
+	{ Ws3,     -1,      -1,      -1,       -1,      -1,      -1,      -1      }, // Attype
+	{ -1,      Attval,  DDecH,   Attval,   Attval,  Attval,  Attval,  Attval  }, // Ws3
+	{ -1,      -1,      -1,      -1,       DefImp,  DefFix,  DefReq,  -1      }, // DDecH
+	{ Ws4,     Ws4,     -1,      -1,       -1,      -1,      -1,      -1      }, // DefReq
+	{ Ws4,     Ws4,     -1,      -1,       -1,      -1,      -1,      -1      }, // DefImp
+	{ Ws3,     -1,      -1,      -1,       -1,      -1,      -1,      -1      }, // DefFix
+	{ Ws4,     Ws4,     -1,      -1,       -1,      -1,      -1,      -1      }, // Attval
+	{ -1,      Done,    Attdef,  Attdef,   Attdef,  Attdef,  Attdef,  Attdef  }  // Ws4
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '>' ) {
+	    input = InpGt;
+	} else if ( c == '#' ) {
+	    input = InpHash;
+	} else if ( c == 'A' ) {
+	    input = InpA;
+	} else if ( c == 'I' ) {
+	    input = InpI;
+	} else if ( c == 'F' ) {
+	    input = InpF;
+	} else if ( c == 'R' ) {
+	    input = InpR;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Attlist:
+		parseOk = parseString( "ATTLIST" );
+		break;
+	    case Ws:
+	    case Ws1:
+	    case Ws2:
+	    case Ws3:
+		eat_ws();
+		break;
+	    case Name:
+		parseOk = parseName();
+		break;
+	    case Attdef:
+		parseOk = parseName();
+		break;
+	    case Atttype:
+		parseOk = parseAttType();
+		break;
+	    case DDecH:
+		next();
+		break;
+	    case DefReq:
+		parseOk = parseString( "REQUIRED" );
+		break;
+	    case DefImp:
+		parseOk = parseString( "IMPLIED" );
+		break;
+	    case DefFix:
+		parseOk = parseString( "FIXED" );
+		break;
+	    case Attval:
+		parseOk = parseAttValue();
+		break;
+	    case Ws4:
+		if ( declHnd ) {
+		    // TODO: not all values are computed yet...
+		    if ( !declHnd->attributeDecl( d->attDeclEName, d->attDeclAName, "", "", "" ) ) {
+			d->error = declHnd->errorString();
+			goto parseError;
+		    }
+		}
+		eat_ws();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Attlist:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Name:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		d->attDeclEName = name();
+		break;
+	    case Attdef:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		d->attDeclAName = name();
+		break;
+	    case Atttype:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGATTTYPE;
+		    goto parseError;
+		}
+		break;
+	    case DefReq:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case DefImp:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case DefFix:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Attval:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGATTVALUE;
+		    goto parseError;
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_LETTEREXPECTED;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a AttType [54]
+*/
+bool QXmlSimpleReader::parseAttType()
+{
+    const signed char Init             =  0;
+    const signed char ST               =  1; // StringType
+    const signed char TTI              =  2; // TokenizedType starting with 'I'
+    const signed char TTI2             =  3; // TokenizedType helpstate
+    const signed char TTI3             =  4; // TokenizedType helpstate
+    const signed char TTE              =  5; // TokenizedType starting with 'E'
+    const signed char TTEY             =  6; // TokenizedType starting with 'ENTITY'
+    const signed char TTEI             =  7; // TokenizedType starting with 'ENTITI'
+    const signed char N                =  8; // N read (TokenizedType or Notation)
+    const signed char TTNM             =  9; // TokenizedType starting with 'NM'
+    const signed char TTNM2            = 10; // TokenizedType helpstate
+    const signed char NO               = 11; // Notation
+    const signed char NO2              = 12; // Notation helpstate
+    const signed char NO3              = 13; // Notation helpstate
+    const signed char NOName           = 14; // Notation, read name
+    const signed char NO4              = 15; // Notation helpstate
+    const signed char EN               = 16; // Enumeration
+    const signed char ENNmt            = 17; // Enumeration, read Nmtoken
+    const signed char EN2              = 18; // Enumeration helpstate
+    const signed char ADone            = 19; // almost done (make next and accept)
+    const signed char Done             = 20;
+
+    const signed char InpWs            =  0; // whitespace
+    const signed char InpOp            =  1; // (
+    const signed char InpCp            =  2; // )
+    const signed char InpPipe          =  3; // |
+    const signed char InpC             =  4; // C
+    const signed char InpE             =  5; // E
+    const signed char InpI             =  6; // I
+    const signed char InpM             =  7; // M
+    const signed char InpN             =  8; // N
+    const signed char InpO             =  9; // O
+    const signed char InpR             = 10; // R
+    const signed char InpS             = 11; // S
+    const signed char InpY             = 12; // Y
+    const signed char InpUnknown       = 13;
+
+    // use some kind of state machine for parsing
+    static signed char table[19][14] = {
+     /*  InpWs    InpOp    InpCp    InpPipe  InpC     InpE     InpI     InpM     InpN     InpO     InpR     InpS     InpY     InpUnknown */
+	{ -1,      EN,      -1,      -1,      ST,      TTE,     TTI,     -1,      N,       -1,      -1,      -1,      -1,      -1     }, // Init
+	{ Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // ST
+	{ Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    TTI2,    Done,    Done,    Done   }, // TTI
+	{ Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    TTI3,    Done,    Done   }, // TTI2
+	{ Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // TTI3
+	{ -1,      -1,      -1,      -1,      -1,      -1,      TTEI,    -1,      -1,      -1,      -1,      -1,      TTEY,    -1     }, // TTE
+	{ Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // TTEY
+	{ Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // TTEI
+	{ -1,      -1,      -1,      -1,      -1,      -1,      -1,      TTNM,    -1,      NO,      -1,      -1,      -1,      -1     }, // N
+	{ Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    TTNM2,   Done,    Done   }, // TTNM
+	{ Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done,    Done   }, // TTNM2
+	{ NO2,     -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // NO
+	{ -1,      NO3,     -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // NO2
+	{ NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName,  NOName }, // NO3
+	{ NO4,     -1,      ADone,   NO3,     -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // NOName
+	{ -1,      -1,      ADone,   NO3,     -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // NO4
+	{ -1,      -1,      ENNmt,   -1,      ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt,   ENNmt  }, // EN
+	{ EN2,     -1,      ADone,   EN,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }, // ENNmt
+	{ -1,      -1,      ADone,   EN,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1,      -1     }  // EN2
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '(' ) {
+	    input = InpOp;
+	} else if ( c == ')' ) {
+	    input = InpCp;
+	} else if ( c == '|' ) {
+	    input = InpPipe;
+	} else if ( c == 'C' ) {
+	    input = InpC;
+	} else if ( c == 'E' ) {
+	    input = InpE;
+	} else if ( c == 'I' ) {
+	    input = InpI;
+	} else if ( c == 'M' ) {
+	    input = InpM;
+	} else if ( c == 'N' ) {
+	    input = InpN;
+	} else if ( c == 'O' ) {
+	    input = InpO;
+	} else if ( c == 'R' ) {
+	    input = InpR;
+	} else if ( c == 'S' ) {
+	    input = InpS;
+	} else if ( c == 'Y' ) {
+	    input = InpY;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case ST:
+		parseOk = parseString( "CDATA" );
+		break;
+	    case TTI:
+		parseOk = parseString( "ID" );
+		break;
+	    case TTI2:
+		parseOk = parseString( "REF" );
+		break;
+	    case TTI3:
+		next(); // S
+		break;
+	    case TTE:
+		parseOk = parseString( "ENTIT" );
+		break;
+	    case TTEY:
+		next(); // Y
+		break;
+	    case TTEI:
+		parseOk = parseString( "IES" );
+		break;
+	    case N:
+		next(); // N
+		break;
+	    case TTNM:
+		parseOk = parseString( "MTOKEN" );
+		break;
+	    case TTNM2:
+		next(); // S
+		break;
+	    case NO:
+		parseOk = parseString( "OTATION" );
+		break;
+	    case NO2:
+		eat_ws();
+		break;
+	    case NO3:
+		next_eat_ws();
+		break;
+	    case NOName:
+		parseOk = parseName();
+		break;
+	    case NO4:
+		eat_ws();
+		break;
+	    case EN:
+		next_eat_ws();
+		break;
+	    case ENNmt:
+		parseOk = parseNmtoken();
+		break;
+	    case EN2:
+		eat_ws();
+		break;
+	    case ADone:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case ST:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case TTI:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case TTI2:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case TTE:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case TTEI:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case TTNM:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case NO:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case NOName:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		break;
+	    case ENNmt:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNMTOKEN;
+		    goto parseError;
+		}
+		break;
+	    case ADone:
+		return TRUE;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_LETTEREXPECTED;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a AttValue [10]
+
+  Precondition: the head stands on the beginning " or '
+
+  If this function was successful, the head stands on the first
+  character after the closing " or ' and the value of the attribute
+  is in string().
+*/
+bool QXmlSimpleReader::parseAttValue()
+{
+    bool tmp;
+
+    const signed char Init             = 0;
+    const signed char Dq               = 1; // double quotes were read
+    const signed char DqRef            = 2; // read references in double quotes
+    const signed char DqC              = 3; // signed character read in double quotes
+    const signed char Sq               = 4; // single quotes were read
+    const signed char SqRef            = 5; // read references in single quotes
+    const signed char SqC              = 6; // signed character read in single quotes
+    const signed char Done             = 7;
+
+    const signed char InpDq            = 0; // "
+    const signed char InpSq            = 1; // '
+    const signed char InpAmp           = 2; // &
+    const signed char InpLt            = 3; // <
+    const signed char InpUnknown       = 4;
+
+    // use some kind of state machine for parsing
+    static signed char table[7][5] = {
+     /*  InpDq  InpSq  InpAmp  InpLt InpUnknown */
+	{ Dq,    Sq,    -1,     -1,   -1    }, // Init
+	{ Done,  DqC,   DqRef,  -1,   DqC   }, // Dq
+	{ Done,  DqC,   DqRef,  -1,   DqC   }, // DqRef
+	{ Done,  DqC,   DqRef,  -1,   DqC   }, // DqC
+	{ SqC,   Done,  SqRef,  -1,   SqC   }, // Sq
+	{ SqC,   Done,  SqRef,  -1,   SqC   }, // SqRef
+	{ SqC,   Done,  SqRef,  -1,   SqC   }  // SqRef
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( c == '"' ) {
+	    input = InpDq;
+	} else if ( c == '\'' ) {
+	    input = InpSq;
+	} else if ( c == '&' ) {
+	    input = InpAmp;
+	} else if ( c == '<' ) {
+	    input = InpLt;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Dq:
+	    case Sq:
+		stringClear();
+		next();
+		break;
+	    case DqRef:
+	    case SqRef:
+		parseOk = parseReference( tmp, InAttributeValue );
+		break;
+	    case DqC:
+	    case SqC:
+		stringAddC();
+		next();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case DqRef:
+	    case SqRef:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGREFERENCE;
+		    goto parseError;
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_UNEXPECTEDCHARACTER;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a elementdecl [45].
+
+  Precondition: the beginning '<!E' is already read and the head
+  stands on the 'L' of '<!ELEMENT'
+*/
+bool QXmlSimpleReader::parseElementDecl()
+{
+    const signed char Init             =  0;
+    const signed char Elem             =  1; // parse the beginning string
+    const signed char Ws1              =  2; // whitespace required
+    const signed char Nam              =  3; // parse Name
+    const signed char Ws2              =  4; // whitespace required
+    const signed char Empty            =  5; // read EMPTY
+    const signed char Any              =  6; // read ANY
+    const signed char Cont             =  7; // read contentspec (except ANY or EMPTY)
+    const signed char Mix              =  8; // read Mixed
+    const signed char Mix2             =  9; //
+    const signed char Mix3             = 10; //
+    const signed char MixN1            = 11; //
+    const signed char MixN2            = 12; //
+    const signed char MixN3            = 13; //
+    const signed char MixN4            = 14; //
+    const signed char Cp               = 15; // parse cp
+    const signed char Cp2              = 16; //
+    const signed char WsD              = 17; // eat whitespace before Done
+    const signed char Done             = 18;
+
+    const signed char InpWs            =  0;
+    const signed char InpGt            =  1; // >
+    const signed char InpPipe          =  2; // |
+    const signed char InpOp            =  3; // (
+    const signed char InpCp            =  4; // )
+    const signed char InpHash          =  5; // #
+    const signed char InpQm            =  6; // ?
+    const signed char InpAst           =  7; // *
+    const signed char InpPlus          =  8; // +
+    const signed char InpA             =  9; // A
+    const signed char InpE             = 10; // E
+    const signed char InpL             = 11; // L
+    const signed char InpUnknown       = 12;
+
+    // use some kind of state machine for parsing
+    static signed char table[18][13] = {
+     /*  InpWs   InpGt  InpPipe  InpOp  InpCp   InpHash  InpQm  InpAst  InpPlus  InpA    InpE    InpL    InpUnknown */
+	{ -1,     -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     Elem,   -1     }, // Init
+	{ Ws1,    -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Elem
+	{ -1,     -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      Nam,    Nam,    Nam,    Nam    }, // Ws1
+	{ Ws2,    -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Nam
+	{ -1,     -1,    -1,      Cont,  -1,     -1,      -1,    -1,     -1,      Any,    Empty,  -1,     -1     }, // Ws2
+	{ WsD,    Done,  -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Empty
+	{ WsD,    Done,  -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Any
+	{ -1,     -1,    -1,      Cp,    Cp,     Mix,     -1,    -1,     -1,      Cp,     Cp,     Cp,     Cp     }, // Cont
+	{ Mix2,   -1,    MixN1,   -1,    Mix3,   -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Mix
+	{ -1,     -1,    MixN1,   -1,    Mix3,   -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Mix2
+	{ WsD,    Done,  -1,      -1,    -1,     -1,      -1,    WsD,    -1,      -1,     -1,     -1,     -1     }, // Mix3
+	{ -1,     -1,    -1,      -1,    -1,     -1,      -1,    -1,     -1,      MixN2,  MixN2,  MixN2,  MixN2  }, // MixN1
+	{ MixN3,  -1,    MixN1,   -1,    MixN4,  -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // MixN2
+	{ -1,     -1,    MixN1,   -1,    MixN4,  -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // MixN3
+	{ -1,     -1,    -1,      -1,    -1,     -1,      -1,    WsD,    -1,      -1,     -1,     -1,     -1     }, // MixN4
+	{ WsD,    Done,  -1,      -1,    -1,     -1,      Cp2,   Cp2,    Cp2,     -1,     -1,     -1,     -1     }, // Cp
+	{ WsD,    Done,  -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }, // Cp2
+	{ -1,     Done,  -1,      -1,    -1,     -1,      -1,    -1,     -1,      -1,     -1,     -1,     -1     }  // WsD
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// read input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '>' ) {
+	    input = InpGt;
+	} else if ( c == '|' ) {
+	    input = InpPipe;
+	} else if ( c == '(' ) {
+	    input = InpOp;
+	} else if ( c == ')' ) {
+	    input = InpCp;
+	} else if ( c == '#' ) {
+	    input = InpHash;
+	} else if ( c == '?' ) {
+	    input = InpQm;
+	} else if ( c == '*' ) {
+	    input = InpAst;
+	} else if ( c == '+' ) {
+	    input = InpPlus;
+	} else if ( c == 'A' ) {
+	    input = InpA;
+	} else if ( c == 'E' ) {
+	    input = InpE;
+	} else if ( c == 'L' ) {
+	    input = InpL;
+	} else {
+	    input = InpUnknown;
+	}
+	// get new state
+//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
+	state = table[state][input];
+
+	// in some cases do special actions depending on state
+	switch ( state ) {
+	    case Elem:
+		parseOk = parseString( "LEMENT" );
+		break;
+	    case Ws1:
+		eat_ws();
+		break;
+	    case Nam:
+		parseOk = parseName();
+		break;
+	    case Ws2:
+		eat_ws();
+		break;
+	    case Empty:
+		parseOk = parseString( "EMPTY" );
+		break;
+	    case Any:
+		parseOk = parseString( "ANY" );
+		break;
+	    case Cont:
+		next_eat_ws();
+		break;
+	    case Mix:
+		parseOk = parseString( "#PCDATA" );
+		break;
+	    case Mix2:
+		eat_ws();
+		break;
+	    case Mix3:
+		next();
+		break;
+	    case MixN1:
+		next_eat_ws();
+		break;
+	    case MixN2:
+		parseOk = parseName();
+		break;
+	    case MixN3:
+		eat_ws();
+		break;
+	    case MixN4:
+		next();
+		break;
+	    case Cp:
+		parseOk = parseChoiceSeq();
+		break;
+	    case Cp2:
+		next();
+		break;
+	    case WsD:
+		next_eat_ws();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Elem:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Nam:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		break;
+	    case Empty:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Any:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Mix:
+		if( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case MixN2:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		break;
+	    case Cp:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGCHOICE;
+		    goto parseError;
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		d->error = XMLERR_UNEXPECTEDCHARACTER;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a NotationDecl [82].
+
+  Precondition: the beginning '<!' is already read and the head
+  stands on the 'N' of '<!NOTATION'
+*/
+bool QXmlSimpleReader::parseNotationDecl()
+{
+    const signed char Init             = 0;
+    const signed char Not              = 1; // read NOTATION
+    const signed char Ws1              = 2; // eat whitespaces
+    const signed char Nam              = 3; // read Name
+    const signed char Ws2              = 4; // eat whitespaces
+    const signed char ExtID            = 5; // parse ExternalID
+    const signed char Ws3              = 6; // eat whitespaces
+    const signed char Done             = 7;
+
+    const signed char InpWs            = 0;
+    const signed char InpGt            = 1; // >
+    const signed char InpN             = 2; // N
+    const signed char InpUnknown       = 3;
+
+    // use some kind of state machine for parsing
+    static signed char table[7][4] = {
+     /*  InpWs   InpGt  InpN    InpUnknown */
+	{ -1,     -1,    Not,    -1     }, // Init
+	{ Ws1,    -1,    -1,     -1     }, // Not
+	{ -1,     -1,    Nam,    Nam    }, // Ws1
+	{ Ws2,    Done,  -1,     -1     }, // Nam
+	{ -1,     Done,  ExtID,  ExtID  }, // Ws2
+	{ Ws3,    Done,  -1,     -1     }, // ExtID
+	{ -1,     Done,  -1,     -1     }  // Ws3
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '>' ) {
+	    input = InpGt;
+	} else if ( c == 'N' ) {
+	    input = InpN;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Not:
+		parseOk = parseString( "NOTATION" );
+		break;
+	    case Ws1:
+		eat_ws();
+		break;
+	    case Nam:
+		parseOk = parseName();
+		break;
+	    case Ws2:
+		eat_ws();
+		break;
+	    case ExtID:
+		parseOk = parseExternalID( TRUE );
+		break;
+	    case Ws3:
+		eat_ws();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Not:
+		if ( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Nam:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		break;
+	    case ExtID:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGEXTERNALID;
+		    goto parseError;
+		}
+		// call the handler
+		if ( dtdHnd ) {
+		    if ( !dtdHnd->notationDecl( name(), d->publicId, d->systemId ) ) {
+			d->error = dtdHnd->errorString();
+			goto parseError;
+		    }
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_UNEXPECTEDCHARACTER;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse choice [49] or seq [50].
+
+  Precondition: the beginning '('S? is already read and the head
+  stands on the first non-whitespace character after it.
+*/
+bool QXmlSimpleReader::parseChoiceSeq()
+{
+    const signed char Init             = 0;
+    const signed char Ws1              = 1; // eat whitespace
+    const signed char CS               = 2; // choice or set
+    const signed char Ws2              = 3; // eat whitespace
+    const signed char More             = 4; // more cp to read
+    const signed char Name             = 5; // read name
+    const signed char Done             = 6; //
+
+    const signed char InpWs            = 0; // S
+    const signed char InpOp            = 1; // (
+    const signed char InpCp            = 2; // )
+    const signed char InpQm            = 3; // ?
+    const signed char InpAst           = 4; // *
+    const signed char InpPlus          = 5; // +
+    const signed char InpPipe          = 6; // |
+    const signed char InpComm          = 7; // ,
+    const signed char InpUnknown       = 8;
+
+    // use some kind of state machine for parsing
+    static signed char table[6][9] = {
+     /*  InpWs   InpOp  InpCp  InpQm  InpAst  InpPlus  InpPipe  InpComm  InpUnknown */
+	{ -1,     Ws1,   -1,    -1,    -1,     -1,      -1,      -1,      Name  }, // Init
+	{ -1,     CS,    -1,    -1,    -1,     -1,      -1,      -1,      CS    }, // Ws1
+	{ Ws2,    -1,    Done,  Ws2,   Ws2,    Ws2,     More,    More,    -1    }, // CS
+	{ -1,     -1,    Done,  -1,    -1,     -1,      More,    More,    -1    }, // Ws2
+	{ -1,     Ws1,   -1,    -1,    -1,     -1,      -1,      -1,      Name  }, // More (same as Init)
+	{ Ws2,    -1,    Done,  Ws2,   Ws2,    Ws2,     More,    More,    -1    }  // Name (same as CS)
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '(' ) {
+	    input = InpOp;
+	} else if ( c == ')' ) {
+	    input = InpCp;
+	} else if ( c == '?' ) {
+	    input = InpQm;
+	} else if ( c == '*' ) {
+	    input = InpAst;
+	} else if ( c == '+' ) {
+	    input = InpPlus;
+	} else if ( c == '|' ) {
+	    input = InpPipe;
+	} else if ( c == ',' ) {
+	    input = InpComm;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Ws1:
+		next_eat_ws();
+		break;
+	    case CS:
+		parseOk = parseChoiceSeq();
+		break;
+	    case Ws2:
+		next_eat_ws();
+		break;
+	    case More:
+		next_eat_ws();
+		break;
+	    case Name:
+		parseOk = parseName();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case CS:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGCHOICE;
+		    goto parseError;
+		}
+		break;
+	    case Name:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_UNEXPECTEDCHARACTER;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a EntityDecl [70].
+
+  Precondition: the beginning '<!E' is already read and the head
+  stand on the 'N' of '<!ENTITY'
+*/
+bool QXmlSimpleReader::parseEntityDecl()
+{
+    const signed char Init             =  0;
+    const signed char Ent              =  1; // parse "ENTITY"
+    const signed char Ws1              =  2; // white space read
+    const signed char Name             =  3; // parse name
+    const signed char Ws2              =  4; // white space read
+    const signed char EValue           =  5; // parse entity value
+    const signed char ExtID            =  6; // parse ExternalID
+    const signed char Ws3              =  7; // white space read
+    const signed char Ndata            =  8; // parse "NDATA"
+    const signed char Ws4              =  9; // white space read
+    const signed char NNam             = 10; // parse name
+    const signed char PEDec            = 11; // parse PEDecl
+    const signed char Ws6              = 12; // white space read
+    const signed char PENam            = 13; // parse name
+    const signed char Ws7              = 14; // white space read
+    const signed char PEVal            = 15; // parse entity value
+    const signed char PEEID            = 16; // parse ExternalID
+    const signed char WsE              = 17; // white space read
+    const signed char Done             = 18;
+
+    const signed char InpWs            = 0; // white space
+    const signed char InpPer           = 1; // %
+    const signed char InpQuot          = 2; // " or '
+    const signed char InpGt            = 3; // >
+    const signed char InpN             = 4; // N
+    const signed char InpUnknown       = 5;
+
+    // use some kind of state machine for parsing
+    static signed char table[18][6] = {
+     /*  InpWs  InpPer  InpQuot  InpGt  InpN    InpUnknown */
+	{ -1,    -1,     -1,      -1,    Ent,    -1      }, // Init
+	{ Ws1,   -1,     -1,      -1,    -1,     -1      }, // Ent
+	{ -1,    PEDec,  -1,      -1,    Name,   Name    }, // Ws1
+	{ Ws2,   -1,     -1,      -1,    -1,     -1      }, // Name
+	{ -1,    -1,     EValue,  -1,    -1,     ExtID   }, // Ws2
+	{ WsE,   -1,     -1,      Done,  -1,     -1      }, // EValue
+	{ Ws3,   -1,     -1,      Done,  -1,     -1      }, // ExtID
+	{ -1,    -1,     -1,      Done,  Ndata,  -1      }, // Ws3
+	{ Ws4,   -1,     -1,      -1,    -1,     -1      }, // Ndata
+	{ -1,    -1,     -1,      -1,    NNam,   NNam    }, // Ws4
+	{ WsE,   -1,     -1,      Done,  -1,     -1      }, // NNam
+	{ Ws6,   -1,     -1,      -1,    -1,     -1      }, // PEDec
+	{ -1,    -1,     -1,      -1,    PENam,  PENam   }, // Ws6
+	{ Ws7,   -1,     -1,      -1,    -1,     -1      }, // PENam
+	{ -1,    -1,     PEVal,   -1,    -1,     PEEID   }, // Ws7
+	{ WsE,   -1,     -1,      Done,  -1,     -1      }, // PEVal
+	{ WsE,   -1,     -1,      Done,  -1,     -1      }, // PEEID
+	{ -1,    -1,     -1,      Done,  -1,     -1      }  // WsE
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_S(c) ) {
+	    input = InpWs;
+	} else if ( c == '%' ) {
+	    input = InpPer;
+	} else if ( c == '"' || c == '\'' ) {
+	    input = InpQuot;
+	} else if ( c == '>' ) {
+	    input = InpGt;
+	} else if ( c == 'N' ) {
+	    input = InpN;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Ent:
+		parseOk = parseString( "NTITY" );
+		break;
+	    case Ws1:
+		eat_ws();
+		break;
+	    case Name:
+		parseOk = parseName();
+		break;
+	    case Ws2:
+		eat_ws();
+		break;
+	    case EValue:
+		parseOk = parseEntityValue();
+		break;
+	    case ExtID:
+		parseOk = parseExternalID();
+		break;
+	    case Ws3:
+		eat_ws();
+		break;
+	    case Ndata:
+		parseOk = parseString( "NDATA" );
+		break;
+	    case Ws4:
+		eat_ws();
+		break;
+	    case NNam:
+		parseOk = parseName( TRUE );
+		break;
+	    case PEDec:
+		next();
+		break;
+	    case Ws6:
+		eat_ws();
+		break;
+	    case PENam:
+		parseOk = parseName();
+		break;
+	    case Ws7:
+		eat_ws();
+		break;
+	    case PEVal:
+		parseOk = parseEntityValue();
+		break;
+	    case PEEID:
+		parseOk = parseExternalID();
+		break;
+	    case WsE:
+		eat_ws();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Ent:
+		if ( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case Name:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		break;
+	    case EValue:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGENTITYVALUE;
+		    goto parseError;
+		}
+		if (  d->entities.find( name() ) == d->entities.end() &&
+			d->externEntities.find( name() ) == d->externEntities.end() ) {
+		    d->entities.insert( name(), string() );
+		    if ( declHnd ) {
+			if ( !declHnd->internalEntityDecl( name(), string() ) ) {
+			    d->error = declHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		}
+		break;
+	    case ExtID:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGEXTERNALID;
+		    goto parseError;
+		}
+		if (  d->entities.find( name() ) == d->entities.end() &&
+			d->externEntities.find( name() ) == d->externEntities.end() ) {
+		    d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, "" ) );
+		    if ( declHnd ) {
+			if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+			    d->error = declHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		}
+		break;
+	    case Ndata:
+		if ( !parseOk ) {
+		    d->error = XMLERR_UNEXPECTEDCHARACTER;
+		    goto parseError;
+		}
+		break;
+	    case NNam:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		if (  d->entities.find( name() ) == d->entities.end() &&
+			d->externEntities.find( name() ) == d->externEntities.end() ) {
+		    d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) );
+		    if ( declHnd ) {
+			if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+			    d->error = declHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		}
+		break;
+	    case PENam:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		break;
+	    case PEVal:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGENTITYVALUE;
+		    goto parseError;
+		}
+		if (  d->parameterEntities.find( name() ) == d->parameterEntities.end() &&
+			d->externParameterEntities.find( name() ) == d->externParameterEntities.end() ) {
+		    d->parameterEntities.insert( name(), string() );
+		    if ( declHnd ) {
+			if ( !declHnd->internalEntityDecl( QString("%")+name(), string() ) ) {
+			    d->error = declHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		}
+		break;
+	    case PEEID:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGEXTERNALID;
+		    goto parseError;
+		}
+		if (  d->parameterEntities.find( name() ) == d->parameterEntities.end() &&
+			d->externParameterEntities.find( name() ) == d->externParameterEntities.end() ) {
+		    d->externParameterEntities.insert( name(), QXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) );
+		    if ( declHnd ) {
+			if ( !declHnd->externalEntityDecl( QString("%")+name(), d->publicId, d->systemId ) ) {
+			    d->error = declHnd->errorString();
+			    goto parseError;
+			}
+		    }
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_LETTEREXPECTED;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a EntityValue [9]
+*/
+bool QXmlSimpleReader::parseEntityValue()
+{
+    bool tmp;
+
+    const signed char Init             = 0;
+    const signed char Dq               = 1; // EntityValue is double quoted
+    const signed char DqC              = 2; // signed character
+    const signed char DqPER            = 3; // PERefence
+    const signed char DqRef            = 4; // Reference
+    const signed char Sq               = 5; // EntityValue is double quoted
+    const signed char SqC              = 6; // signed character
+    const signed char SqPER            = 7; // PERefence
+    const signed char SqRef            = 8; // Reference
+    const signed char Done             = 9;
+
+    const signed char InpDq            = 0; // "
+    const signed char InpSq            = 1; // '
+    const signed char InpAmp           = 2; // &
+    const signed char InpPer           = 3; // %
+    const signed char InpUnknown       = 4;
+
+    // use some kind of state machine for parsing
+    static signed char table[9][5] = {
+     /*  InpDq  InpSq  InpAmp  InpPer  InpUnknown */
+	{ Dq,    Sq,    -1,     -1,     -1    }, // Init
+	{ Done,  DqC,   DqRef,  DqPER,  DqC   }, // Dq
+	{ Done,  DqC,   DqRef,  DqPER,  DqC   }, // DqC
+	{ Done,  DqC,   DqRef,  DqPER,  DqC   }, // DqPER
+	{ Done,  DqC,   DqRef,  DqPER,  DqC   }, // DqRef
+	{ SqC,   Done,  SqRef,  SqPER,  SqC   }, // Sq
+	{ SqC,   Done,  SqRef,  SqPER,  SqC   }, // SqC
+	{ SqC,   Done,  SqRef,  SqPER,  SqC   }, // SqPER
+	{ SqC,   Done,  SqRef,  SqPER,  SqC   }  // SqRef
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( c == '"' ) {
+	    input = InpDq;
+	} else if ( c == '\'' ) {
+	    input = InpSq;
+	} else if ( c == '&' ) {
+	    input = InpAmp;
+	} else if ( c == '%' ) {
+	    input = InpPer;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Dq:
+	    case Sq:
+		stringClear();
+		next();
+		break;
+	    case DqC:
+	    case SqC:
+		stringAddC();
+		next();
+		break;
+	    case DqPER:
+	    case SqPER:
+		parseOk = parsePEReference( InEntityValue );
+		break;
+	    case DqRef:
+	    case SqRef:
+		parseOk = parseReference( tmp, InEntityValue );
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case DqPER:
+	    case SqPER:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGDOCTYPE;
+		    goto parseError;
+		}
+		break;
+	    case DqRef:
+	    case SqRef:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGREFERENCE;
+		    goto parseError;
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_LETTEREXPECTED;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a comment [15].
+
+  Precondition: the beginning '<!' of the comment is already read and the head
+  stands on the first '-' of '<!--'.
+
+  If this funktion was successful, the head-position is on the first
+  character after the comment.
+*/
+bool QXmlSimpleReader::parseComment()
+{
+    const signed char Init             = 0;
+    const signed char Dash1            = 1; // the first dash was read
+    const signed char Dash2            = 2; // the second dash was read
+    const signed char Com              = 3; // read comment
+    const signed char Com2             = 4; // read comment (help state)
+    const signed char ComE             = 5; // finished reading comment
+    const signed char Done             = 6;
+
+    const signed char InpDash          = 0; // -
+    const signed char InpGt            = 1; // >
+    const signed char InpUnknown       = 2;
+
+    // use some kind of state machine for parsing
+    static signed char table[6][3] = {
+     /*  InpDash  InpGt  InpUnknown */
+	{ Dash1,   -1,    -1  }, // Init
+	{ Dash2,   -1,    -1  }, // Dash1
+	{ Com2,    Com,   Com }, // Dash2
+	{ Com2,    Com,   Com }, // Com
+	{ ComE,    Com,   Com }, // Com2
+	{ -1,      Done,  -1  }  // ComE
+    };
+    signed char state = Init;
+    signed char input;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( c == '-' ) {
+	    input = InpDash;
+	} else if ( c == '>' ) {
+	    input = InpGt;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Dash1:
+		next();
+		break;
+	    case Dash2:
+		next();
+		break;
+	    case Com:
+		stringAddC();
+		next();
+		break;
+	    case Com2:
+		next();
+		break;
+	    case ComE:
+		next();
+		break;
+	    case Done:
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Dash2:
+		stringClear();
+		break;
+	    case Com2:
+		// if next character is not a dash than don't skip it
+		if ( c != '-' ) {
+		    stringAddC( '-' );
+		}
+		break;
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_ERRORPARSINGCOMMENT;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a Attribute [41].
+
+  Precondition: the head stands on the first character of the name of the
+  attribute (i.e. all whitespaces are already parsed).
+
+  The head stand on the next character after the end quotes. The variable name
+  contains the name of the attribute and the variable string contains the value
+  of the attribute.
+*/
+bool QXmlSimpleReader::parseAttribute()
+{
+    const signed char Init             = 0;
+    const signed char PName            = 1; // parse name
+    const signed char Ws               = 2; // eat ws
+    const signed char Eq               = 3; // the '=' was read
+    const signed char Quotes           = 4; // " or ' were read
+
+    const signed char InpNameBe        = 0;
+    const signed char InpEq            = 1; // =
+    const signed char InpDq            = 2; // "
+    const signed char InpSq            = 3; // '
+    const signed char InpUnknown       = 4;
+
+    // use some kind of state machine for parsing
+    static signed char table[4][5] = {
+     /*  InpNameBe  InpEq  InpDq    InpSq    InpUnknown */
+	{ PName,     -1,    -1,      -1,      -1    }, // Init
+	{ -1,        Eq,    -1,      -1,      Ws    }, // PName
+	{ -1,        Eq,    -1,      -1,      -1    }, // Ws
+	{ -1,        -1,    Quotes,  Quotes,  -1    }  // Eq
+    };
+    signed char state = Init;
+    signed char input;
+    bool parseOk = TRUE;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_NameBeginning(c) ) {
+	    input = InpNameBe;
+	} else if ( c == '=' ) {
+	    input = InpEq;
+	} else if ( c == '"' ) {
+	    input = InpDq;
+	} else if ( c == '\'' ) {
+	    input = InpSq;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case PName:
+		parseOk = parseName();
+		break;
+	    case Ws:
+		eat_ws();
+		break;
+	    case Eq:
+		next_eat_ws();
+		break;
+	    case Quotes:
+		parseOk = parseAttValue();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case PName:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGNAME;
+		    goto parseError;
+		}
+		break;
+	    case Quotes:
+		if ( !parseOk ) {
+		    d->error = XMLERR_ERRORPARSINGATTVALUE;
+		    goto parseError;
+		}
+		// Done
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_UNEXPECTEDCHARACTER;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a Name [5] and store the name in name or ref (if useRef is TRUE).
+*/
+bool QXmlSimpleReader::parseName( bool useRef )
+{
+    const signed char Init             = 0;
+    const signed char Name1            = 1; // parse first signed character of the name
+    const signed char Name             = 2; // parse name
+    const signed char Done             = 3;
+
+    const signed char InpNameBe        = 0; // name beginning signed characters
+    const signed char InpNameCh        = 1; // NameChar without InpNameBe
+    const signed char InpUnknown       = 2;
+
+    // use some kind of state machine for parsing
+    static signed char table[3][3] = {
+     /*  InpNameBe  InpNameCh  InpUnknown */
+	{ Name1,     -1,        -1    }, // Init
+	{ Name,      Name,      Done  }, // Name1
+	{ Name,      Name,      Done  }  // Name
+    };
+    signed char state = Init;
+    signed char input;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( is_NameBeginning(c) ) {
+	    input = InpNameBe;
+	} else if ( is_NameChar(c) ) {
+	    input = InpNameCh;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case Name1:
+		if ( useRef ) {
+		    refClear();
+		    refAddC();
+		} else {
+		    nameClear();
+		    nameAddC();
+		}
+		next();
+		break;
+	    case Name:
+		if ( useRef ) {
+		    refAddC();
+		} else {
+		    nameAddC();
+		}
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_LETTEREXPECTED;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a Nmtoken [7] and store the name in name.
+*/
+bool QXmlSimpleReader::parseNmtoken()
+{
+    const signed char Init             = 0;
+    const signed char NameF            = 1;
+    const signed char Name             = 2;
+    const signed char Done             = 3;
+
+    const signed char InpNameCh        = 0; // NameChar without InpNameBe
+    const signed char InpUnknown       = 1;
+
+    // use some kind of state machine for parsing
+    static signed char table[3][2] = {
+     /*  InpNameCh  InpUnknown */
+	{ NameF,     -1    }, // Init
+	{ Name,      Done  }, // NameF
+	{ Name,      Done  }  // Name
+    };
+    signed char state = Init;
+    signed char input;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if ( is_NameChar(c) ) {
+	    input = InpNameCh;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case NameF:
+		nameClear();
+		nameAddC();
+		next();
+		break;
+	    case Name:
+		nameAddC();
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case Done:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_LETTEREXPECTED;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse a Reference [67].
+
+  charDataRead is set to TRUE if the reference must not be parsed. The
+  character(s) which the reference mapped to are appended to string. The
+  head stands on the first character after the reference.
+
+  charDataRead is set to FALSE if the reference must be parsed. The
+  charachter(s) which the reference mapped to are inserted at the reference
+  position. The head stands on the first character of the replacement).
+*/
+bool QXmlSimpleReader::parseReference( bool &charDataRead, EntityRecognitionContext context )
+{
+    // temporary variables
+    uint tmp;
+    bool ok;
+
+    const signed char Init             =  0;
+    const signed char SRef             =  1; // start of a reference
+    const signed char ChRef            =  2; // parse CharRef
+    const signed char ChDec            =  3; // parse CharRef decimal
+    const signed char ChHexS           =  4; // start CharRef hexadecimal
+    const signed char ChHex            =  5; // parse CharRef hexadecimal
+    const signed char Name             =  6; // parse name
+    const signed char DoneD            =  7; // done CharRef decimal
+    const signed char DoneH            =  8; // done CharRef hexadecimal
+    const signed char DoneN            =  9; // done EntityRef
+
+    const signed char InpAmp           = 0; // &
+    const signed char InpSemi          = 1; // ;
+    const signed char InpHash          = 2; // #
+    const signed char InpX             = 3; // x
+    const signed char InpNum           = 4; // 0-9
+    const signed char InpHex           = 5; // a-f A-F
+    const signed char InpUnknown       = 6;
+
+    // use some kind of state machine for parsing
+    static signed char table[8][7] = {
+     /*  InpAmp  InpSemi  InpHash  InpX     InpNum  InpHex  InpUnknown */
+	{ SRef,   -1,      -1,      -1,      -1,     -1,     -1    }, // Init
+	{ -1,     -1,      ChRef,   Name,    Name,   Name,   Name  }, // SRef
+	{ -1,     -1,      -1,      ChHexS,  ChDec,  -1,     -1    }, // ChRef
+	{ -1,     DoneD,   -1,      -1,      ChDec,  -1,     -1    }, // ChDec
+	{ -1,     -1,      -1,      -1,      ChHex,  ChHex,  -1    }, // ChHexS
+	{ -1,     DoneH,   -1,      -1,      ChHex,  ChHex,  -1    }, // ChHex
+	{ -1,     DoneN,   -1,      -1,      -1,     -1,     -1    }  // Name
+    };
+    signed char state = Init;
+    signed char input;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if        ( c.row() ) {
+	    input = InpUnknown;
+	} else if ( c.cell() == '&' ) {
+	    input = InpAmp;
+	} else if ( c.cell() == ';' ) {
+	    input = InpSemi;
+	} else if ( c.cell() == '#' ) {
+	    input = InpHash;
+	} else if ( c.cell() == 'x' ) {
+	    input = InpX;
+	} else if ( '0' <= c.cell() && c.cell() <= '9' ) {
+	    input = InpNum;
+	} else if ( 'a' <= c.cell() && c.cell() <= 'f' ) {
+	    input = InpHex;
+	} else if ( 'A' <= c.cell() && c.cell() <= 'F' ) {
+	    input = InpHex;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	state = table[state][input];
+
+	// do some actions according to state
+	switch ( state ) {
+	    case SRef:
+		refClear();
+		next();
+		break;
+	    case ChRef:
+		next();
+		break;
+	    case ChDec:
+		refAddC();
+		next();
+		break;
+	    case ChHexS:
+		next();
+		break;
+	    case ChHex:
+		refAddC();
+		next();
+		break;
+	    case Name:
+		// read the name into the ref
+		parseName( TRUE );
+		break;
+	    case DoneD:
+		tmp = ref().toUInt( &ok, 10 );
+		if ( ok ) {
+		    stringAddC( QChar(tmp) );
+		} else {
+		    d->error = XMLERR_ERRORPARSINGREFERENCE;
+		    goto parseError;
+		}
+		charDataRead = TRUE;
+		next();
+		break;
+	    case DoneH:
+		tmp = ref().toUInt( &ok, 16 );
+		if ( ok ) {
+		    stringAddC( QChar(tmp) );
+		} else {
+		    d->error = XMLERR_ERRORPARSINGREFERENCE;
+		    goto parseError;
+		}
+		charDataRead = TRUE;
+		next();
+		break;
+	    case DoneN:
+		if        ( ref() == "amp" ) {
+		    if ( context == InEntityValue ) {
+			// Bypassed
+			stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
+		    } else {
+			// Included or Included in literal
+			stringAddC( '&' );
+		    }
+		    charDataRead = TRUE;
+		} else if ( ref() == "lt" ) {
+		    if ( context == InEntityValue ) {
+			// Bypassed
+			stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
+		    } else {
+			// Included or Included in literal
+			stringAddC( '<' );
+		    }
+		    charDataRead = TRUE;
+		} else if ( ref() == "gt" ) {
+		    if ( context == InEntityValue ) {
+			// Bypassed
+			stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
+		    } else {
+			// Included or Included in literal
+			stringAddC( '>' );
+		    }
+		    charDataRead = TRUE;
+		} else if ( ref() == "apos" ) {
+		    if ( context == InEntityValue ) {
+			// Bypassed
+			stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
+		    } else {
+			// Included or Included in literal
+			stringAddC( '\'' );
+		    }
+		    charDataRead = TRUE;
+		} else if ( ref() == "quot" ) {
+		    if ( context == InEntityValue ) {
+			// Bypassed
+			stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
+		    } else {
+			// Included or Included in literal
+			stringAddC( '"' );
+		    }
+		    charDataRead = TRUE;
+		} else {
+		    QMap<QString,QString>::Iterator it;
+		    it = d->entities.find( ref() );
+		    if ( it != d->entities.end() ) {
+			// "Internal General"
+			switch ( context ) {
+			    case InContent:
+				// Included
+				xmlRef = it.data() + xmlRef;
+				charDataRead = FALSE;
+				break;
+			    case InAttributeValue:
+				// Included in literal
+				xmlRef = it.data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
+					+ xmlRef;
+				charDataRead = FALSE;
+				break;
+			    case InEntityValue:
+				{
+				    // Bypassed
+				    stringAddC( '&' );
+				    for ( int i=0; i<(int)ref().length(); i++ ) {
+					stringAddC( ref()[i] );
+				    }
+				    stringAddC( ';');
+				    charDataRead = TRUE;
+				}
+				break;
+			    case InDTD:
+				// Forbidden
+				d->error = XMLERR_INTERNALGENERALENTITYINDTD;
+				charDataRead = FALSE;
+				break;
+			}
+		    } else {
+			QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
+			itExtern = d->externEntities.find( ref() );
+			if ( itExtern != d->externEntities.end() ) {
+			    // "External Parsed General"
+			    switch ( context ) {
+				case InContent:
+				    // Included if validating
+				    if ( contentHnd ) {
+					if ( !contentHnd->skippedEntity( ref() ) ) {
+					    d->error = contentHnd->errorString();
+					    goto parseError;
+					}
+				    }
+				    charDataRead = FALSE;
+				    break;
+				case InAttributeValue:
+				    // Forbidden
+				    d->error = XMLERR_EXTERNALGENERALENTITYINAV;
+				    charDataRead = FALSE;
+				    break;
+				case InEntityValue:
+				    {
+					// Bypassed
+					stringAddC( '&' );
+					for ( int i=0; i<(int)ref().length(); i++ ) {
+					    stringAddC( ref()[i] );
+					}
+					stringAddC( ';');
+					charDataRead = TRUE;
+				    }
+				    break;
+				case InDTD:
+				    // Forbidden
+				    d->error = XMLERR_EXTERNALGENERALENTITYINDTD;
+				    charDataRead = FALSE;
+				    break;
+			    }
+			} else {
+			    // "Unparsed" ### or is the definition of unparsed entities different?
+			    if ( context == InEntityValue ) {
+				// Bypassed
+				// (this does not conform with the table 4.4 of the XML specification;
+				// on the other hand: in this case it is not really an unparsed entity)
+				stringAddC( '&' );
+				for ( int i=0; i<(int)ref().length(); i++ ) {
+				    stringAddC( ref()[i] );
+				}
+				stringAddC( ';');
+				charDataRead = TRUE;
+			    } else {
+#if 0
+				// Forbidden
+				d->error = XMLERR_UNPARSEDENTITYREFERENCE;
+				goto parseError;
+				charDataRead = FALSE;
+#else
+				// ### skip it???
+				if ( contentHnd ) {
+				    if ( !contentHnd->skippedEntity( ref() ) ) {
+					d->error = contentHnd->errorString();
+					goto parseError;
+				    }
+				}
+#endif
+			    }
+			}
+		    }
+		}
+		next();
+		break;
+	}
+	// no input is read after this
+	switch ( state ) {
+	    case DoneD:
+		return TRUE;
+	    case DoneH:
+		return TRUE;
+	    case DoneN:
+		return TRUE;
+	    case -1:
+		// Error
+		d->error = XMLERR_ERRORPARSINGREFERENCE;
+		goto parseError;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+/*!
+  Parse over a simple string.
+
+  After the string was successfully parsed, the head is on the first
+  character after the string.
+*/
+bool QXmlSimpleReader::parseString( const QString& s )
+{
+    signed char Done                   = s.length();
+
+    const signed char InpCharExpected  = 0; // the character that was expected
+    const signed char InpUnknown       = 1;
+
+    signed char state = 0; // state in this function is the position in the string s
+    signed char input;
+
+    while ( TRUE ) {
+
+	// get input
+	if ( atEnd() ) {
+	    d->error = XMLERR_UNEXPECTEDEOF;
+	    goto parseError;
+	}
+	if ( c == s[(int)state] ) {
+	    input = InpCharExpected;
+	} else {
+	    input = InpUnknown;
+	}
+
+	// set state according to input
+	if ( input == InpCharExpected ) {
+	    state++;
+	} else {
+	    // Error
+	    d->error = XMLERR_UNEXPECTEDCHARACTER;
+	    goto parseError;
+	}
+
+	// do some actions according to state
+	next();
+	// no input is read after this
+	if ( state == Done ) {
+	    return TRUE;
+	}
+
+    }
+
+    return TRUE;
+
+parseError:
+    reportParseError();
+    return FALSE;
+}
+
+
+/*
+  Init the data values.
+*/
+void QXmlSimpleReader::init( const QXmlInputSource& i )
+{
+    xml = i.data();
+    xmlLength = xml.length();
+    xmlRef = "";
+
+    d->externParameterEntities.clear();
+    d->parameterEntities.clear();
+    d->externEntities.clear();
+    d->entities.clear();
+
+    tags.clear();
+
+    d->doctype = "";
+    d->xmlVersion = "";
+    d->encoding = "";
+    d->standalone = QXmlSimpleReaderPrivate::Unknown;
+
+    lineNr = 0;
+    columnNr = -1;
+    pos = 0;
+    next();
+    d->error = XMLERR_OK;
+}
+
+void QXmlSimpleReader::reportParseError()
+{
+    if ( errorHnd )
+	errorHnd->fatalError( QXmlParseException( d->error, columnNr+1, lineNr+1 ) );
+}
+
+#endif //QT_NO_XML
diff --git a/qtools/qxml.h b/qtools/qxml.h
new file mode 100644
index 0000000..c23430c
--- /dev/null
+++ b/qtools/qxml.h
@@ -0,0 +1,645 @@
+/****************************************************************************
+** 
+**
+** Definition of QXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QXML_H
+#define QXML_H
+
+#include <qmodules.h>
+
+#if !defined(QT_MODULE_XML)
+#define QM_EXPORT
+#else
+#define QM_EXPORT Q_EXPORT
+#endif
+
+#ifndef QT_H
+#include <qtextstream.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluestack.h>
+#include <qmap.h>
+#endif // QT_H
+
+#ifndef QT_NO_XML
+
+class QXmlNamespaceSupport;
+class QXmlAttributes;
+class QXmlContentHandler;
+class QXmlDefaultHandler;
+class QXmlDTDHandler;
+class QXmlEntityResolver;
+class QXmlErrorHandler;
+class QXmlLexicalHandler;
+class QXmlDeclHandler;
+class QXmlInputSource;
+class QXmlLocator;
+class QXmlNamespaceSupport;
+class QXmlParseException;
+
+class QXmlReader;
+class QXmlSimpleReader;
+
+class QXmlSimpleReaderPrivate;
+class QXmlNamespaceSupportPrivate;
+class QXmlAttributesPrivate;
+class QXmlInputSourcePrivate;
+class QXmlParseExceptionPrivate;
+class QXmlLocatorPrivate;
+class QXmlDefaultHandlerPrivate;
+
+
+//
+// SAX Namespace Support
+//
+
+#if defined(Q_TEMPLATEDLL)
+// MOC_SKIP_BEGIN
+template class QM_EXPORT QMap<QString, QString>;
+template class QM_EXPORT QValueStack<QMap<QString, QString> >;
+template class QM_EXPORT QValueStack<QString>;
+// MOC_SKIP_END
+#endif
+
+class QM_EXPORT QXmlNamespaceSupport
+{
+public:
+    QXmlNamespaceSupport();
+    ~QXmlNamespaceSupport();
+
+    void setPrefix( const QString&, const QString& );
+
+    QString prefix( const QString& ) const;
+    QString uri( const QString& ) const;
+    void splitName( const QString&, QString&, QString& ) const;
+    void processName( const QString&, bool, QString&, QString& ) const;
+    QStringList prefixes() const;
+    QStringList prefixes( const QString& ) const;
+
+    void pushContext();
+    void popContext();
+    void reset();
+private:
+    QValueStack<QMap<QString, QString> > nsStack;
+    QMap<QString, QString> ns;
+
+    QXmlNamespaceSupportPrivate *d;
+};
+
+
+//
+// SAX Attributes
+//
+
+class QM_EXPORT QXmlAttributes
+{
+public:
+    QXmlAttributes() {}
+    virtual ~QXmlAttributes() {}
+
+    int index( const QString& qName ) const;
+    int index( const QString& uri, const QString& localPart ) const;
+    int length() const;
+    QString localName( int index ) const;
+    QString qName( int index ) const;
+    QString uri( int index ) const;
+    QString type( int index ) const;
+    QString type( const QString& qName ) const;
+    QString type( const QString& uri, const QString& localName ) const;
+    QString value( int index ) const;
+    QString value( const QString& qName ) const;
+    QString value( const QString& uri, const QString& localName ) const;
+
+private:
+    QStringList qnameList;
+    QStringList uriList;
+    QStringList localnameList;
+    QStringList valueList;
+
+    QXmlAttributesPrivate *d;
+
+    friend class QXmlSimpleReader;
+};
+
+//
+// SAX Input Source
+//
+
+class QM_EXPORT QXmlInputSource
+{
+public:
+    QXmlInputSource();
+    QXmlInputSource( QTextStream& stream );
+    QXmlInputSource( QFile& file );
+    virtual ~QXmlInputSource();
+
+    virtual const QString& data() const;
+    virtual void setData( const QString& d );
+
+private:
+    void readInput( QByteArray& rawData );
+
+    QString input;
+
+    QXmlInputSourcePrivate *d;
+};
+
+//
+// SAX Exception Classes
+//
+
+class QM_EXPORT QXmlParseException
+{
+public:
+    QXmlParseException( const QString& name="", int c=-1, int l=-1, const QString& p="", const QString& s="" )
+	: msg( name ), column( c ), line( l ), pub( p ), sys( s )
+    { }
+
+    int columnNumber() const;
+    int lineNumber() const;
+    QString publicId() const;
+    QString systemId() const;
+    QString message() const;
+
+private:
+    QString msg;
+    int column;
+    int line;
+    QString pub;
+    QString sys;
+
+    QXmlParseExceptionPrivate *d;
+};
+
+
+//
+// XML Reader
+//
+
+class QM_EXPORT QXmlReader
+{
+public:
+    virtual bool feature( const QString& name, bool *ok = 0 ) const = 0;
+    virtual void setFeature( const QString& name, bool value ) = 0;
+    virtual bool hasFeature( const QString& name ) const = 0;
+    virtual void* property( const QString& name, bool *ok = 0 ) const = 0;
+    virtual void setProperty( const QString& name, void* value ) = 0;
+    virtual bool hasProperty( const QString& name ) const = 0;
+    virtual void setEntityResolver( QXmlEntityResolver* handler ) = 0;
+    virtual QXmlEntityResolver* entityResolver() const = 0;
+    virtual void setDTDHandler( QXmlDTDHandler* handler ) = 0;
+    virtual QXmlDTDHandler* DTDHandler() const = 0;
+    virtual void setContentHandler( QXmlContentHandler* handler ) = 0;
+    virtual QXmlContentHandler* contentHandler() const = 0;
+    virtual void setErrorHandler( QXmlErrorHandler* handler ) = 0;
+    virtual QXmlErrorHandler* errorHandler() const = 0;
+    virtual void setLexicalHandler( QXmlLexicalHandler* handler ) = 0;
+    virtual QXmlLexicalHandler* lexicalHandler() const = 0;
+    virtual void setDeclHandler( QXmlDeclHandler* handler ) = 0;
+    virtual QXmlDeclHandler* declHandler() const = 0;
+    virtual bool parse( const QXmlInputSource& input ) = 0;
+};
+
+class QM_EXPORT QXmlSimpleReader : public QXmlReader
+{
+public:
+    QXmlSimpleReader();
+    virtual ~QXmlSimpleReader();
+
+    bool feature( const QString& name, bool *ok = 0 ) const;
+    void setFeature( const QString& name, bool value );
+    bool hasFeature( const QString& name ) const;
+
+    void* property( const QString& name, bool *ok = 0 ) const;
+    void setProperty( const QString& name, void* value );
+    bool hasProperty( const QString& name ) const;
+
+    void setEntityResolver( QXmlEntityResolver* handler );
+    QXmlEntityResolver* entityResolver() const;
+    void setDTDHandler( QXmlDTDHandler* handler );
+    QXmlDTDHandler* DTDHandler() const;
+    void setContentHandler( QXmlContentHandler* handler );
+    QXmlContentHandler* contentHandler() const;
+    void setErrorHandler( QXmlErrorHandler* handler );
+    QXmlErrorHandler* errorHandler() const;
+    void setLexicalHandler( QXmlLexicalHandler* handler );
+    QXmlLexicalHandler* lexicalHandler() const;
+    void setDeclHandler( QXmlDeclHandler* handler );
+    QXmlDeclHandler* declHandler() const;
+
+    bool parse( const QXmlInputSource& input );
+
+private:
+    // variables
+    QXmlContentHandler* contentHnd;
+    QXmlErrorHandler*   errorHnd;
+    QXmlDTDHandler*     dtdHnd;
+    QXmlEntityResolver* entityRes;
+    QXmlLexicalHandler* lexicalHnd;
+    QXmlDeclHandler*    declHnd;
+
+    QChar c; // the character at reading position
+    int lineNr; // number of line
+    int columnNr; // position in line
+    int pos; // position in string
+
+    int     namePos;
+    QChar   nameArray[256]; // only used for names
+    QString nameValue; // only used for names
+    int     refPos;
+    QChar   refArray[256]; // only used for references
+    QString refValue; // only used for references
+    int     stringPos;
+    QChar   stringArray[256]; // used for any other strings that are parsed
+    QString stringValue; // used for any other strings that are parsed
+
+    QString xml;
+    int xmlLength;
+    QString xmlRef; // used for parsing of entity references
+
+    QValueStack<QString> tags;
+
+    QXmlSimpleReaderPrivate* d;
+
+    static const QChar QEOF;
+
+    // inlines
+    virtual bool is_S( const QChar& );
+    virtual bool is_Letter( const QChar& );
+    virtual bool is_NameBeginning( const QChar& );
+    virtual bool is_Digit( const QChar& );
+    virtual bool is_CombiningChar( const QChar& );
+    virtual bool is_Extender( const QChar& );
+    virtual bool is_NameChar( const QChar& );
+
+    QString& string();
+    void stringClear();
+    void stringAddC();
+    void stringAddC(const QChar&);
+    QString& name();
+    void nameClear();
+    void nameAddC();
+    void nameAddC(const QChar&);
+    QString& ref();
+    void refClear();
+    void refAddC();
+    void refAddC(const QChar&);
+
+    // used by parseReference() and parsePEReference()
+    enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
+
+    // private methods
+    void eat_ws();
+    void next_eat_ws();
+
+    void next();
+    bool atEnd();
+
+    void init( const QXmlInputSource& i );
+
+    bool parseProlog();
+    bool parseElement();
+    bool parseElementEmptyTag( bool &t, QString &uri, QString &lname );
+    bool parseElementETagBegin2();
+    bool parseElementAttribute( QString &prefix, QString &uri, QString &lname );
+    bool parseMisc();
+    bool parseContent();
+
+    bool parsePI(bool xmldecl=FALSE);
+    bool parseDoctype();
+    bool parseComment();
+
+    bool parseName( bool useRef=FALSE );
+    bool parseNmtoken();
+    bool parseAttribute();
+    bool parseReference( bool &charDataRead, EntityRecognitionContext context );
+
+    bool parseExternalID( bool allowPublicID = FALSE );
+    bool parsePEReference( EntityRecognitionContext context );
+    bool parseMarkupdecl();
+    bool parseAttlistDecl();
+    bool parseAttType();
+    bool parseAttValue();
+    bool parseElementDecl();
+    bool parseNotationDecl();
+    bool parseChoiceSeq();
+    bool parseEntityDecl();
+    bool parseEntityValue();
+
+    bool parseString( const QString& s );
+
+    void reportParseError();
+
+    friend class QXmlSimpleReaderPrivate;
+    friend class QXmlLocator;
+};
+
+//
+// SAX Locator
+//
+
+class QM_EXPORT QXmlLocator
+{
+public:
+    QXmlLocator( QXmlSimpleReader* parent )
+    { reader = parent; }
+    ~QXmlLocator()
+    { }
+
+    int columnNumber();
+    int lineNumber();
+//    QString getPublicId()
+//    QString getSystemId()
+
+private:
+    QXmlSimpleReader* reader;
+
+    QXmlLocatorPrivate *d;
+};
+
+//
+// SAX handler classes
+//
+
+class QM_EXPORT QXmlContentHandler
+{
+public:
+    virtual void setDocumentLocator( QXmlLocator* locator ) = 0;
+    virtual bool startDocument() = 0;
+    virtual bool endDocument() = 0;
+    virtual bool startPrefixMapping( const QString& prefix, const QString& uri ) = 0;
+    virtual bool endPrefixMapping( const QString& prefix ) = 0;
+    virtual bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ) = 0;
+    virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ) = 0;
+    virtual bool characters( const QString& ch ) = 0;
+    virtual bool ignorableWhitespace( const QString& ch ) = 0;
+    virtual bool processingInstruction( const QString& target, const QString& data ) = 0;
+    virtual bool skippedEntity( const QString& name ) = 0;
+    virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlErrorHandler
+{
+public:
+    virtual bool warning( const QXmlParseException& exception ) = 0;
+    virtual bool error( const QXmlParseException& exception ) = 0;
+    virtual bool fatalError( const QXmlParseException& exception ) = 0;
+    virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlDTDHandler
+{
+public:
+    virtual bool notationDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+    virtual bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName ) = 0;
+    virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlEntityResolver
+{
+public:
+    virtual bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret ) = 0;
+    virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlLexicalHandler
+{
+public:
+    virtual bool startDTD( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+    virtual bool endDTD() = 0;
+//    virtual bool startEntity( const QString& name ) = 0;
+//    virtual bool endEntity( const QString& name ) = 0;
+    virtual bool startCDATA() = 0;
+    virtual bool endCDATA() = 0;
+    virtual bool comment( const QString& ch ) = 0;
+    virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlDeclHandler
+{
+public:
+    virtual bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value ) = 0;
+    virtual bool internalEntityDecl( const QString& name, const QString& value ) = 0;
+    virtual bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+    virtual QString errorString() = 0;
+};
+
+
+class QM_EXPORT QXmlDefaultHandler : public QXmlContentHandler, public QXmlErrorHandler, public QXmlDTDHandler, public QXmlEntityResolver, public QXmlLexicalHandler, public QXmlDeclHandler
+{
+public:
+    QXmlDefaultHandler() { }
+    virtual ~QXmlDefaultHandler() { }
+
+    void setDocumentLocator( QXmlLocator* locator );
+    bool startDocument();
+    bool endDocument();
+    bool startPrefixMapping( const QString& prefix, const QString& uri );
+    bool endPrefixMapping( const QString& prefix );
+    bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts );
+    bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName );
+    bool characters( const QString& ch );
+    bool ignorableWhitespace( const QString& ch );
+    bool processingInstruction( const QString& target, const QString& data );
+    bool skippedEntity( const QString& name );
+
+    bool warning( const QXmlParseException& exception );
+    bool error( const QXmlParseException& exception );
+    bool fatalError( const QXmlParseException& exception );
+
+    bool notationDecl( const QString& name, const QString& publicId, const QString& systemId );
+    bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName );
+
+    bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret );
+
+    bool startDTD( const QString& name, const QString& publicId, const QString& systemId );
+    bool endDTD();
+//    bool startEntity( const QString& name );
+//    bool endEntity( const QString& name );
+    bool startCDATA();
+    bool endCDATA();
+    bool comment( const QString& ch );
+
+    bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value );
+    bool internalEntityDecl( const QString& name, const QString& value );
+    bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId );
+
+    QString errorString();
+
+private:
+    QXmlDefaultHandlerPrivate *d;
+};
+
+
+//
+// inlines
+//
+
+inline bool QXmlSimpleReader::is_S(const QChar& ch)
+{ return ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'; }
+
+inline bool QXmlSimpleReader::is_Letter( const QChar& ch )
+{ return ch.isLetter(); }
+
+inline bool QXmlSimpleReader::is_NameBeginning( const QChar& ch )
+{ return ch=='_' || ch==':' || ch.isLetter(); }
+
+inline bool QXmlSimpleReader::is_Digit( const QChar& ch )
+{ return ch.isDigit(); }
+
+inline bool QXmlSimpleReader::is_CombiningChar( const QChar& )
+{ return FALSE; }
+
+inline bool QXmlSimpleReader::is_Extender( const QChar& )
+{ return FALSE; }
+
+inline bool QXmlSimpleReader::is_NameChar( const QChar& ch )
+{
+    return ch=='.' || ch=='-' || ch=='_' || ch==':' ||
+	is_Letter(ch) || is_Digit(ch) ||
+	is_CombiningChar(ch) || is_Extender(ch);
+}
+
+inline void QXmlSimpleReader::next()
+{
+    if ( !xmlRef.isEmpty() ) {
+	c = xmlRef[0];
+	xmlRef.remove( 0, 1 );
+    } else {
+	if ( c=='\n' || c=='\r' ) {
+	    lineNr++;
+	    columnNr = -1;
+	}
+	if ( pos >= xmlLength ) {
+	    c = QEOF;
+	} else {
+	    c = xml[pos];
+	    columnNr++;
+	    pos++;
+	}
+    }
+}
+
+inline bool QXmlSimpleReader::atEnd()
+{ return c == QEOF; }
+
+inline void QXmlSimpleReader::eat_ws()
+{ while ( !atEnd() && is_S(c) ) next(); }
+
+inline void QXmlSimpleReader::next_eat_ws()
+{ next(); eat_ws(); }
+
+
+// use buffers instead of QString::operator+= when single characters are read
+inline QString& QXmlSimpleReader::string()
+{
+    stringValue += QString( stringArray, stringPos );
+    stringPos = 0;
+    return stringValue;
+}
+inline QString& QXmlSimpleReader::name()
+{
+    nameValue += QString( nameArray, namePos );
+    namePos = 0;
+    return nameValue;
+}
+inline QString& QXmlSimpleReader::ref()
+{
+    refValue += QString( refArray, refPos );
+    refPos = 0;
+    return refValue;
+}
+
+inline void QXmlSimpleReader::stringClear()
+{ stringValue = ""; stringPos = 0; }
+inline void QXmlSimpleReader::nameClear()
+{ nameValue = ""; namePos = 0; }
+inline void QXmlSimpleReader::refClear()
+{ refValue = ""; refPos = 0; }
+
+inline void QXmlSimpleReader::stringAddC()
+{
+    if ( stringPos >= 256 ) {
+	stringValue += QString( stringArray, stringPos );
+	stringPos = 0;
+    }
+    stringArray[stringPos++] = c;
+}
+inline void QXmlSimpleReader::nameAddC()
+{
+    if ( namePos >= 256 ) {
+	nameValue += QString( nameArray, namePos );
+	namePos = 0;
+    }
+    nameArray[namePos++] = c;
+}
+inline void QXmlSimpleReader::refAddC()
+{
+    if ( refPos >= 256 ) {
+	refValue += QString( refArray, refPos );
+	refPos = 0;
+    }
+    refArray[refPos++] = c;
+}
+
+inline void QXmlSimpleReader::stringAddC(const QChar& ch)
+{
+    if ( stringPos >= 256 ) {
+	stringValue += QString( stringArray, stringPos );
+	stringPos = 0;
+    }
+    stringArray[stringPos++] = ch;
+}
+inline void QXmlSimpleReader::nameAddC(const QChar& ch)
+{
+    if ( namePos >= 256 ) {
+	nameValue += QString( nameArray, namePos );
+	namePos = 0;
+    }
+    nameArray[namePos++] = ch;
+}
+inline void QXmlSimpleReader::refAddC(const QChar& ch)
+{
+    if ( refPos >= 256 ) {
+	refValue += QString( refArray, refPos );
+	refPos = 0;
+    }
+    refArray[refPos++] = ch;
+}
+#endif //QT_NO_XML
+
+#endif
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 239ae3f..775b84f 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -604,6 +604,7 @@ ArgumentList *ClassDef::outerTemplateArguments() const
   int ti;
   ClassDef *pcd=0;
   int pi=0;
+  if (tempArgs) return tempArgs;
   // find the outer most class scope
   while ((ti=name().find("::",pi))!=-1 && 
       (pcd=getClass(name().left(ti)))==0
@@ -612,10 +613,7 @@ ArgumentList *ClassDef::outerTemplateArguments() const
   {
     return pcd->templateArguments();
   }
-  else
-  {
-    return tempArgs;
-  }
+  return 0;
 }
 
 
diff --git a/src/config.h b/src/config.h
index 176c1ad..9e5c906 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,4 +1,4 @@
-/* This file was generated by configgen on Sat Nov 25 21:38:08 2000
+/* This file was generated by configgen on Sun Dec 3 18:27:54 2000
  * from config_templ.h
  *
  * DO NOT EDIT!
@@ -98,6 +98,7 @@ struct Config
   static bool     noIndexFlag; // generate condensed index flag
   static int      enumValuesPerLine; // number of enum values that are put on one line
   static bool     ftvHelpFlag; // should a folder tree view be generated?
+  static int      treeViewWidth; // What is the width of the treeview panel?
   static bool     generateLatex; // generate Latex output
   static QCString latexOutputDir; // the directory to put the Latex files
   static bool     compactLatexFlag; // generate compact LaTeX documentation.
diff --git a/src/config.l b/src/config.l
index 6d4d834..2fcef2f 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1,4 +1,4 @@
-/* This file was generated by configgen on Sat Nov 25 21:38:08 2000
+/* This file was generated by configgen on Sun Dec 3 19:18:43 2000
  * from config_templ.l
  *
  * DO NOT EDIT!
@@ -135,6 +135,7 @@ bool     Config::htmlHelpFlag = FALSE;
 bool     Config::noIndexFlag = FALSE;
 int      Config::enumValuesPerLine = 4;
 bool     Config::ftvHelpFlag = FALSE;
+int      Config::treeViewWidth = 250;
 bool     Config::generateLatex = TRUE;
 QCString Config::latexOutputDir = "latex";
 bool     Config::compactLatexFlag = FALSE;
@@ -215,6 +216,7 @@ static int               includeDepth;
 static QCString     tabSizeString;
 static QCString     colsInAlphaIndexString;
 static QCString     enumValuesPerLineString;
+static QCString     treeViewWidthString;
 static QCString     maxDotGraphWidthString;
 static QCString     maxDotGraphHeightString;
 
@@ -413,6 +415,7 @@ static void readIncludeFile(const char *incName)
 <Start>"DISABLE_INDEX"[ \t]*"="          { BEGIN(GetBool); b=&Config::noIndexFlag; }
 <Start>"ENUM_VALUES_PER_LINE"[ \t]*"="   { BEGIN(GetString); s=&enumValuesPerLineString; s->resize(0); }
 <Start>"GENERATE_TREEVIEW"[ \t]*"="      { BEGIN(GetBool); b=&Config::ftvHelpFlag; }
+<Start>"TREEVIEW_WIDTH"[ \t]*"="         { BEGIN(GetString); s=&treeViewWidthString; s->resize(0); }
 <Start>"GENERATE_LATEX"[ \t]*"="         { BEGIN(GetBool); b=&Config::generateLatex; }
 <Start>"LATEX_OUTPUT"[ \t]*"="           { BEGIN(GetString); s=&Config::latexOutputDir; s->resize(0); }
 <Start>"COMPACT_LATEX"[ \t]*"="          { BEGIN(GetBool); b=&Config::compactLatexFlag; }
@@ -713,6 +716,7 @@ void dumpConfig()
   printf("noIndexFlag=`%d'\n",Config::noIndexFlag);
   printf("enumValuesPerLine=`%d'\n",Config::enumValuesPerLine);
   printf("ftvHelpFlag=`%d'\n",Config::ftvHelpFlag);
+  printf("treeViewWidth=`%d'\n",Config::treeViewWidth);
   printf("# configuration options related to the LaTeX output\n");
   printf("generateLatex=`%d'\n",Config::generateLatex);
   printf("latexOutputDir=`%s'\n",Config::latexOutputDir.data());
@@ -882,6 +886,7 @@ void Config::init()
   Config::noIndexFlag = FALSE;
   Config::enumValuesPerLine = 4;
   Config::ftvHelpFlag = FALSE;
+  Config::treeViewWidth = 250;
   Config::generateLatex = TRUE;
   Config::latexOutputDir = "latex";
   Config::compactLatexFlag = FALSE;
@@ -1725,6 +1730,17 @@ void writeTemplateConfig(QFile *f,bool sl)
   if (!sl)
   {
     t << "\n";
+    t << "# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \n";
+    t << "# used to set the initial width (in pixels) of the frame in which the tree \n";
+    t << "# is shown. \n";
+    t << "\n";
+  }
+  t << "TREEVIEW_WIDTH         = ";
+  writeIntValue(t,Config::treeViewWidth);
+  t << "\n";
+  if (!sl)
+  {
+    t << "\n";
   }
   t << "#---------------------------------------------------------------------------\n";
   t << "# configuration options related to the LaTeX output\n";
@@ -2356,6 +2372,23 @@ void configStrToVal()
     Config::enumValuesPerLine=cols;
   }
   
+  if (treeViewWidthString.isEmpty())
+  {
+    Config::treeViewWidth=250;
+  }
+  else
+  {
+    bool ok;
+    int width = treeViewWidthString.toInt(&ok);
+    if (!ok || width<0 || width>1500)
+    {
+      warn_cont("Warning: argument of TREEVIEW_WIDTH is not a valid number in the range [0..1500]!\n"
+	   "Using the default of 250!\n");
+      width = 250;
+    }
+    Config::treeViewWidth=width;
+  }
+
   if (maxDotGraphWidthString.isEmpty())
   {
     Config::maxDotGraphWidth=1024;
diff --git a/src/doc.l b/src/doc.l
index 274844f..82883ee 100644
--- a/src/doc.l
+++ b/src/doc.l
@@ -561,10 +561,14 @@ static void addListItemMarker(const char *marker,int dashPos,bool enumerated)
     }
     else // end sub item list
     {
-      pPrevInfo->endList();
-      listIndentStack.pop();
-      currentListIndent.pop();
-      delete pPrevInfo;
+      while (pPrevInfo && pPrevInfo->indent>indent)
+      {
+	pPrevInfo->endList();
+	listIndentStack.pop();
+	currentListIndent.pop();
+	delete pPrevInfo;
+	pPrevInfo = listIndentStack.top();
+      }
       // safe guard against wrong indenting
       if (listIndentStack.isEmpty()) 
       {
@@ -855,7 +859,7 @@ DOCPARAM  ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
 					  int dashPos = text.findRev('-');
 					  //printf("dashPos=%d char='%c'\n",dashPos,text.at(dashPos+1));
 					  bool isEnumerated = text.at(dashPos+1)=='#';
-  					  addListItemMarker(yytext,dashPos,isEnumerated);
+  					  addListItemMarker(yytext,dashPos+1,isEnumerated);
   					}
 <DocScan>\n{B}*(("//"{B}*)?)"*"*{B}*"-"("#")?{B}+ { /* found list item marker */
   					  QCString text=yytext;
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 14901c7..4e951bd 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -731,7 +731,7 @@ static void buildClassList(Entry *root)
         ClassDef *cd=new ClassDef(root->fileName,root->startLine,fullName,sec);
         cd->setDocumentation(root->doc); // copy docs to definition
         cd->setBriefDescription(root->brief);
-        //printf("new ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data());
+        //printf("new ClassDef %s tempArgList=%p specScope=%s\n",fullName.data(),root->tArgList,root->scopeSpec.data());
         cd->setTemplateArguments(root->tArgList);
         cd->setProtection(root->protection);
         cd->addSectionsToDefinition(root->anchors);
@@ -1364,7 +1364,7 @@ static MemberDef *addVariableToFile(
 
 void buildVarList(Entry *root)
 {
-  QRegExp re("([^)]*)");
+  static const QRegExp re("([^)]*)");
   int i=-1;
   if (!root->name.isEmpty() &&
       //root->type!="class" && root->type!="interface" && 
@@ -1397,9 +1397,9 @@ void buildVarList(Entry *root)
     {
       // recover from parse error caused by redundant braces
       root->type=root->name;
-      QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
+      static const QRegExp reName("[a-z_A-Z][a-z_A-Z0-9]*");
       int l;
-      i=root->args.isEmpty() ? -1 : re.match(root->args,0,&l);
+      i=root->args.isEmpty() ? -1 : reName.match(root->args,0,&l);
       root->name=root->args.mid(i,l);
       root->args=root->args.mid(i+l,root->args.find(')',i+l)-i-l);
       //printf("new: type=`%s' name=`%s' args=`%s'\n",
@@ -1408,10 +1408,19 @@ void buildVarList(Entry *root)
     else
     {
       i=root->type.find(re,0);
-      if (i!=-1) // function variable
+      if (i!=-1) // function pointer
       {
-        root->type=root->type.left(root->type.length()-1);
-        root->args.prepend(")");
+        int ai = root->type.find('[',i);
+        if (ai>i) // function pointer array
+        {
+          root->args.prepend(root->type.right(root->type.length()-ai));
+          root->type=root->type.left(ai);
+        }
+        else
+        {
+          root->type=root->type.left(root->type.length()-1);
+          root->args.prepend(")");
+        }
       }
     }
     
@@ -2047,39 +2056,48 @@ static void transferFunctionDocumentation()
         matchArguments(mdef->argumentList(),mdec->argumentList())
        ) /* match found */
     {
-      //printf("Found member %s: def in %s and dec in %s\n",
-      //    mn->memberName(),mdef->getFileDef()->name().data(),
-      //    mdec->getFileDef()->name().data());
-      
-      /* copy documentation between function definition and declaration */
-      if (mdec->briefDescription())
-      {
-        mdef->setBriefDescription(mdec->briefDescription());
-      }
-      else if (mdef->briefDescription())
-      {
-        mdec->setBriefDescription(mdef->briefDescription());
-      }
-      if (mdef->documentation())
-      {
-        mdec->setDocumentation(mdef->documentation());
-      }
-      else if (mdec->documentation())
-      {
-        mdef->setDocumentation(mdec->documentation());
-      }
-      if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
-      {
-        mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
-        mdef->setBodyDef(mdec->getFileDef());
-      }
-      else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
+      FileDef *fdef = mdef->getFileDef();
+      FileDef *fdec = mdec->getFileDef();
+
+      // check if not in different but documented files
+      if (Config::extractAllFlag || 
+          fdef==fdec || 
+          !fdef->hasDocumentation() || !mdec->hasDocumentation())
       {
-        mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
-        mdec->setBodyDef(mdef->getFileDef());
+        //printf("Found member %s: def in %s and dec in %s\n",
+        //    mn->memberName(),mdef->getFileDef()->name().data(),
+        //    mdec->getFileDef()->name().data());
+
+        /* copy documentation between function definition and declaration */
+        if (mdec->briefDescription())
+        {
+          mdef->setBriefDescription(mdec->briefDescription());
+        }
+        else if (mdef->briefDescription())
+        {
+          mdec->setBriefDescription(mdef->briefDescription());
+        }
+        if (mdef->documentation())
+        {
+          mdec->setDocumentation(mdef->documentation());
+        }
+        else if (mdec->documentation())
+        {
+          mdef->setDocumentation(mdec->documentation());
+        }
+        if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
+        {
+          mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
+          mdef->setBodyDef(mdec->getFileDef());
+        }
+        else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
+        {
+          mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
+          mdec->setBodyDef(mdef->getFileDef());
+        }
+        mdec->mergeMemberSpecifiers(mdef->getMemberSpecifiers());
+        mdef->mergeMemberSpecifiers(mdec->getMemberSpecifiers());
       }
-      mdec->mergeMemberSpecifiers(mdef->getMemberSpecifiers());
-      mdef->mergeMemberSpecifiers(mdec->getMemberSpecifiers());
     }
   }
 }
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 580749d..bb75335 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -164,6 +164,10 @@ void FileDef::writeDocumentation(OutputList &ol)
       ol.docify(ii->includeName);
       ol.enableAll();
       ol.disableAllBut(OutputGenerator::Html);
+      
+      // Here we use the include file name as it appears in the file.
+      // we could also we the name as it is used within doxygen,
+      // then we should have used fd->docName() instead of ii->includeName
       if (fd && fd->isLinkable() && fd->generateSourceFile())
       {
         ol.writeObjectLink(fd->getReference(),fd->includeName(),0,ii->includeName);
@@ -172,6 +176,7 @@ void FileDef::writeDocumentation(OutputList &ol)
       {
         ol.docify(ii->includeName);
       }
+      
       ol.enableAll();
       if (ii->local)
         ol.docify("\"");
@@ -438,7 +443,10 @@ void FileDef::writeSource(OutputList &ol)
 
   initParseCodeContext();
   ol.startCodeFragment();
-  parseCode(ol,0,fileToString(absFilePath(),TRUE),FALSE,0,this);
+  parseCode(ol,0,
+            fileToString(absFilePath(),Config::filterForSourceFlag),
+            FALSE,0,this
+           );
   ol.endCodeFragment();
   endFile(ol);
   ol.enableAll();
diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp
index 25ca875..cac212b 100644
--- a/src/ftvhelp.cpp
+++ b/src/ftvhelp.cpp
@@ -16,6 +16,7 @@
 #include "ftvhelp.h"
 #include "config.h"
 #include "message.h"
+#include "doxygen.h"
 
 
 const char treeview_data[]=
@@ -272,7 +273,7 @@ static void generateFolderTreeViewData()
   {
     QTextStream t(&f);
     t << "<html><head><title>" << Config::projectName << "</title></head>" << endl;
-    t << "<frameset cols=\"250,*\">" << endl;
+    t << "<frameset cols=\"" << Config::treeViewWidth << ",*\">" << endl;
     t << "  <frame src=\"tree.html\" name=\"treefrm\">" << endl;
     t << "  <frame src=\"main.html\" name=\"basefrm\">" << endl;
     t << "</frameset>" << endl;
@@ -360,7 +361,7 @@ void FTVHelp::initialize()
   }
   /* Write the header of the contents file */
   m_cts.setDevice(m_cf);
-  m_cts << "foldersTree = gFld(\"<b>";
+  m_cts << "foldersTree = gFld(\"\", \"<b>";
   if (Config::projectName.isEmpty())
   {
     m_cts << "Root";
@@ -409,18 +410,35 @@ int FTVHelp::decContentsDepth()
  *  \param name the name of the item.
  *  \param ref  the URL of to the item.
  */
-void FTVHelp::addContentsItem(bool isDir,const char *name,const char *ref, 
-    const char *anchor)
+void FTVHelp::addContentsItem(bool isDir,
+                              const char *ref,
+                              const char *file,
+                              const char *anchor, 
+                              const char *name
+                             )
 {
   int i; for (i=0;i<m_dc;i++) m_cts << "  ";
   QCString parent;
+  QCString tagName = ref;
+  QCString tagDir;
+  if (ref)
+  {
+    tagName += ":";
+    QCString *s = tagDestinationDict[ref];
+    if (s)
+    {
+      tagDir = *s + "/";
+      tagName += tagDir;
+    }
+  }
   if (m_dc==0) parent="foldersTree"; else parent.sprintf("aux%d",m_dc); 
   if (isDir) // directory entry
   {
-    m_cts << "aux" << m_dc+1 << " = insFld(" << parent << ", gFld(\"" << name << "\", ";
-    if (ref)      // ref optional param
+    m_cts << "aux" << m_dc+1 << " = insFld(" << parent << ", gFld(\"" 
+          << name << "\", \"" << tagName << "\", ";
+    if (file)      // file optional param
     {
-      m_cts << "\"" << ref << ".html\"))";
+      m_cts << "\"" << tagDir << file << ".html\"))";
     }
     else
     {
@@ -429,10 +447,11 @@ void FTVHelp::addContentsItem(bool isDir,const char *name,const char *ref,
   }
   else // text entry
   {
-    m_cts << "     insDoc(" << parent << ", gLnk(0, \"" << name << "\", ";
-    if (ref)      // ref optional param
+    m_cts << "     insDoc(" << parent << ", gLnk(\"" 
+          << name << "\", \"" << tagName << "\", ";
+    if (file)      // ref optional param
     {
-      m_cts << "\"" << ref << ".html";
+      m_cts << "\"" << tagDir << file << ".html";
       if (anchor) m_cts << "#" << anchor;  
       m_cts << "\"))";
     }
diff --git a/src/ftvhelp.h b/src/ftvhelp.h
index 4e58ce1..1d6ccdf 100644
--- a/src/ftvhelp.h
+++ b/src/ftvhelp.h
@@ -32,8 +32,10 @@ class FTVHelp
     /*! return the current depth of the contents tree */ 
     int  contentsDepth() { return m_dc; }
     void addContentsItem(bool isDir,
-                         const char *name, const char *ref = 0, 
-                         const char *anchor = 0);
+                         const char *ref,
+                         const char *file,
+                         const char *anchor, 
+                         const char *name);
 
   private:
     FTVHelp();
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index a962d9f..a077ab2 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -540,6 +540,7 @@ void HtmlGenerator::codify(const char *str)
                    break; 
         case '\n': t << '\n'; col=0; 
                    break;
+        case '\r': break;
         case '<':  t << "&lt;"; col++; 
                    break;
         case '>':  t << "&gt;"; col++; 
diff --git a/src/index.cpp b/src/index.cpp
index 9df60ad..09b2e71 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -144,7 +144,7 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper)
         }
         if (hasFtvHelp)
         {
-          ftvHelp->addContentsItem(hasChildren,cd->name(),cd->getOutputFileBase());
+          ftvHelp->addContentsItem(hasChildren,cd->getReference(),cd->getOutputFileBase(),0,cd->name());
         }
       }
       else
@@ -156,7 +156,7 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper)
         }
         if (hasFtvHelp)
         {
-          ftvHelp->addContentsItem(hasChildren,cd->name(),0);
+          ftvHelp->addContentsItem(hasChildren,0,0,0,cd->name());
         }
       }
       if (hasChildren)
@@ -271,7 +271,7 @@ void writeClassTree(ClassList *cl)
         }
         if (hasFtvHelp)
         {
-          ftvHelp->addContentsItem(hasChildren,cd->name(),cd->getOutputFileBase());
+          ftvHelp->addContentsItem(hasChildren,cd->getReference(),cd->getOutputFileBase(),0,cd->name());
         }
       }
       if (hasChildren)
@@ -340,7 +340,7 @@ void writeClassHierarchy(OutputList &ol)
           }
           if (hasFtvHelp)
           {
-            ftvHelp->addContentsItem(hasChildren,cd->name(),cd->getOutputFileBase());
+            ftvHelp->addContentsItem(hasChildren,cd->getReference(),cd->getOutputFileBase(),0,cd->name());
           }
         }
         else
@@ -352,7 +352,7 @@ void writeClassHierarchy(OutputList &ol)
           }
           if (hasFtvHelp)
           {
-            ftvHelp->addContentsItem(hasChildren,cd->name(),0);
+            ftvHelp->addContentsItem(hasChildren,0,0,0,cd->name());
           }
         }
         if (hasChildren) 
@@ -412,7 +412,7 @@ void writeHierarchicalIndex(OutputList &ol)
   if (Config::generateHtml && Config::ftvHelpFlag /*&& !Config::htmlHelpGroupsOnly*/)
   {
     ftvHelp = FTVHelp::getInstance();
-    ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"hierarchy"); 
+    ftvHelp->addContentsItem(TRUE,0,"hierarchy",0,ftvHelpTitle); 
   }
   if (Config::haveDotFlag && Config::gfxHierarchyFlag)
   {
@@ -459,7 +459,7 @@ void writeGraphicalClassHierarchy(OutputList &ol)
   if (Config::generateHtml && Config::ftvHelpFlag)
   {
     ftvHelp = FTVHelp::getInstance();
-    ftvHelp->addContentsItem(FALSE,ftvHelpTitle,"inherits"); 
+    ftvHelp->addContentsItem(FALSE,0,"inherits",0,ftvHelpTitle); 
   }
   ol.startTextLink("hierarchy",0);
   parseText(ol,theTranslator->trGotoTextualHierarchy());
@@ -538,7 +538,7 @@ void writeFileIndex(OutputList &ol)
   if (hasFtvHelp)
   {
     ftvHelp = FTVHelp::getInstance();
-    ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"files"); 
+    ftvHelp->addContentsItem(TRUE,0,"files",0,ftvHelpTitle); 
     ftvHelp->incContentsDepth();
   }
   //ol.newParagraph();
@@ -638,7 +638,7 @@ void writeFileIndex(OutputList &ol)
           }
           if (hasFtvHelp)
           {
-            ftvHelp->addContentsItem(FALSE,fd->name(),fd->getOutputFileBase());
+            ftvHelp->addContentsItem(FALSE,fd->getReference(),fd->getOutputFileBase(),0,fd->name());
           }
         }
         else
@@ -652,7 +652,7 @@ void writeFileIndex(OutputList &ol)
           }
           if (hasFtvHelp)
           {
-            ftvHelp->addContentsItem(FALSE,fd->name(),0);
+            ftvHelp->addContentsItem(FALSE,0,0,0,fd->name());
           }
         }
         if (src)
@@ -738,7 +738,7 @@ void writeNamespaceIndex(OutputList &ol)
   if (hasFtvHelp)
   {
     ftvHelp = FTVHelp::getInstance();
-    ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"namespaces"); 
+    ftvHelp->addContentsItem(TRUE,0,"namespaces",0,ftvHelpTitle); 
     ftvHelp->incContentsDepth();
   }
   //ol.newParagraph();
@@ -771,7 +771,7 @@ void writeNamespaceIndex(OutputList &ol)
       }
       if (hasFtvHelp)
       {
-        ftvHelp->addContentsItem(FALSE,nd->name(),nd->getOutputFileBase());
+        ftvHelp->addContentsItem(FALSE,nd->getReference(),nd->getOutputFileBase(),0,nd->name());
       }
     }
     nd=namespaceList.next();
@@ -851,7 +851,7 @@ void writeAnnotatedClassList(OutputList &ol)
       }
       if (hasFtvHelp)
       {
-        FTVHelp::getInstance()->addContentsItem(FALSE,cd->name(),cd->getOutputFileBase());
+        FTVHelp::getInstance()->addContentsItem(FALSE,cd->getReference(),cd->getOutputFileBase(),0,cd->name());
       }
     }
     cd=classList.next(); 
@@ -1060,7 +1060,7 @@ void writeAnnotatedIndex(OutputList &ol)
   if (hasFtvHelp)
   {
     ftvHelp = FTVHelp::getInstance();
-    ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"annotated"); 
+    ftvHelp->addContentsItem(TRUE,0,"annotated",0,ftvHelpTitle); 
     ftvHelp->incContentsDepth();
   }
   parseText(ol,theTranslator->trCompoundListDescription());
@@ -1536,7 +1536,7 @@ void writeExampleIndex(OutputList &ol)
   if (hasFtvHelp)
   {
     ftvHelp = FTVHelp::getInstance();
-    ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"examples"); 
+    ftvHelp->addContentsItem(TRUE,0,"examples",0,ftvHelpTitle); 
     ftvHelp->incContentsDepth();
   }
   parseText(ol,theTranslator->trExamplesDescription());
@@ -1553,13 +1553,13 @@ void writeExampleIndex(OutputList &ol)
     {
       ol.writeObjectLink(0,n,0,pi->title);
       if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pi->title,n);
-      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pi->title,n);
+      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,0,n,0,pi->title);
     }
     else
     {
       ol.writeObjectLink(0,n,0,pi->name);
       if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pi->name,n);
-      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pi->name,n);
+      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,0,n,0,pi->name);
     }
     ol.writeString("\n");
   }
@@ -1620,7 +1620,7 @@ void writePageIndex(OutputList &ol)
   if (hasFtvHelp)
   {
     ftvHelp = FTVHelp::getInstance();
-    ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"pages"); 
+    ftvHelp->addContentsItem(TRUE,0,"pages",0,ftvHelpTitle); 
     ftvHelp->incContentsDepth();
   }
   parseText(ol,theTranslator->trRelatedPagesDescription());
@@ -1651,7 +1651,7 @@ void writePageIndex(OutputList &ol)
       ol.writeEndAnnoItem(pageName);
       ol.writeString("\n");
       if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pageTitle,pageName);
-      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pageTitle,pageName);
+      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,0,pageName,0,pageTitle);
     }
   }
   ol.endIndexList();
@@ -1742,7 +1742,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd)
     }
     if(ftvHelp)
     {
-        ftvHelp->addContentsItem(hasSubGroups || hasSubPages,gd->groupTitle(),gd->getOutputFileBase()); 
+        ftvHelp->addContentsItem(hasSubGroups || hasSubPages,gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle()); 
         ftvHelp->incContentsDepth();
     }
 
@@ -1770,9 +1770,10 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd)
                                    si ? si->label.data() : 0
                                   ); 
       if(ftvHelp)  ftvHelp->addContentsItem(FALSE,
-                                   convertToHtml(pi->title),
+                                   gd->getReference(),
                                    gd->getOutputFileBase(),
-                                   si ? si->label.data() : 0
+                                   si ? si->label.data() : 0,
+                                   convertToHtml(pi->title)
                                   ); 
     }
 
@@ -1972,7 +1973,7 @@ void writeGroupIndex(OutputList &ol)
     ftvHelp = FTVHelp::getInstance();
     //if(!Config::htmlHelpGroupsOnly)
     //{
-        ftvHelp->addContentsItem(TRUE,htmlHelpTitle,"modules"); 
+        ftvHelp->addContentsItem(TRUE,0,"modules",0,htmlHelpTitle); 
         ftvHelp->incContentsDepth();
     //}
   }
@@ -2042,7 +2043,7 @@ void writeIndex(OutputList &ol)
   }
   if (Config::generateHtml && Config::ftvHelpFlag)
   {
-    FTVHelp::getInstance()->addContentsItem(FALSE,title,indexName); 
+    FTVHelp::getInstance()->addContentsItem(FALSE,0,indexName,0,title); 
   }
 
   if (!Config::noIndexFlag) writeQuickLinks(ol,TRUE);
diff --git a/src/instdox.cpp b/src/instdox.cpp
index 0ef6b6e..e891f3c 100644
--- a/src/instdox.cpp
+++ b/src/instdox.cpp
@@ -120,6 +120,7 @@ void writeInstallScript()
     t << "      $match = \".html\";\n";
     t << "      next if ( $file =~ /^\\.\\.?$/ );\n";
     t << "      ($file =~ /$match/) && (push @files, $file);\n";
+    t << "      ($file =~ \"tree.js\") && (push @files, $file);\n";
     t << "    }\n";
     t << "    closedir(D);\n";
     t << "  }\n";
@@ -145,9 +146,17 @@ void writeInstallScript()
     t << "      print STDERR \"Error: opening file $oldf for writing\\n\";\n";
     t << "      exit 1;\n";
     t << "    }\n";
-    t << "    while (<F>) {\n";
-    t << "      s/doxygen\\=\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\" (href|src)=\\\"\\2/doxygen\\=\\\"$1:$subst{$1}\\\" \\3=\\\"$subst{$1}/g;\n";
-    t << "      print G \"$_\";\n";
+    t << "    if ($oldf!=\"tree.js\") {\n";
+    t << "      while (<F>) {\n";
+    t << "        s/doxygen\\=\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\" (href|src)=\\\"\\2/doxygen\\=\\\"$1:$subst{$1}\\\" \\3=\\\"$subst{$1}/g;\n";
+    t << "        print G \"$_\";\n";
+    t << "      }\n";
+    t << "    }\n";
+    t << "    else {\n";
+    t << "      while (<F>) {\n";
+    t << "        s/\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\", \\\"\\2/\\\"$1:$subst{$1}\\\" ,\\\"$subst{$1}/g;\n";
+    t << "        print G \"$_\";\n";
+    t << "      }\n";
     t << "    }\n";
     t << "  } \n";
     t << "  else {\n";
diff --git a/src/pre.l b/src/pre.l
index 823e6e7..2c3c67b 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -93,6 +93,7 @@ static QCString           g_lastGuardName;
 static QCString           g_incName;
 static QCString           g_guardExpr;
 static int                g_curlyCount;
+static bool               g_nospaces; // add extra spaces during macro expansion
 
 static void setFileName(const char *name)
 {
@@ -494,6 +495,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
 	  if (key.length()>1 && (subst=argTable[key])) 
 	  {
 	    QCString substArg=*subst;
+	    //printf("substArg=`%s'\n",substArg.data());
 	    // only if no ## operator is before or after the argument
 	    // marker we do macro expansion.
 	    if (!hash) expandExpression(substArg,0,0);
@@ -507,7 +509,14 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
 	    }
 	    else
 	    {
-	      resExpr+=" "+substArg+" ";
+	      if (g_nospaces)
+	      {
+	        resExpr+=substArg;
+	      }
+	      else
+	      {
+	        resExpr+=" "+substArg+" ";
+	      }
 	    }
 	  }
 	}
@@ -597,7 +606,15 @@ static void expandExpression(QCString &expr,QCString *rest,int pos)
 	{
 	  // substitute the definition of the macro
 	  //printf("macro `%s'->`%s'\n",macroName.data(),def->definition.data());
-	  expMacro=" "+def->definition.stripWhiteSpace()+" ";
+	  if (g_nospaces)
+	  {
+	    expMacro=def->definition.stripWhiteSpace();
+	  }
+	  else
+	  {
+	    expMacro=" "+def->definition.stripWhiteSpace()+" ";
+	  }
+	  //expMacro=def->definition.stripWhiteSpace();
 	  replaced=TRUE;
 	  len=l;
 	  //printf("simple macro expansion=`%s'->`%s'\n",macroName.data(),expMacro.data());
@@ -1086,6 +1103,7 @@ BN	[ \t\r\n]
 					    else // g_findDefArgContext==IncludeID
 					    {
 					      readIncludeFile(result);
+					      g_nospaces=FALSE;
 					      BEGIN(Start);
 					    }
 					  }
@@ -1339,12 +1357,14 @@ BN	[ \t\r\n]
 					  BEGIN(SkipCPPBlock);
 					}
 <IncludeID>{ID}{B}*/"("			{
+  					  g_nospaces=TRUE;
 				          g_roundCount=0;
 					  g_defArgsStr=yytext;
 					  g_findDefArgContext = IncludeID;
 					  BEGIN(FindDefineArgs);
 					}
 <IncludeID>{ID}				{
+  					  g_nospaces=TRUE;
                                           readIncludeFile(expandMacro(yytext));
 					  BEGIN(Start);
   					}
@@ -1529,12 +1549,12 @@ BN	[ \t\r\n]
 					    int *n;
 					    if ((n=(*g_argDict)[yytext]))
 					    {
-					      if (!g_quoteArg) g_defText+=' ';
+					      //if (!g_quoteArg) g_defText+=' ';
 					      g_defText+='@';
 					      QCString numStr;
 					      numStr.sprintf("%d",*n);
 					      g_defText+=numStr;
-					      if (!g_quoteArg) g_defText+=' ';
+					      //if (!g_quoteArg) g_defText+=' ';
 					    }
 					    else
 					    {
@@ -1768,6 +1788,7 @@ void preprocessFile(const char *fileName,BufStr &output)
 //#endif
 
   g_curlyCount=0;
+  g_nospaces=FALSE;
   g_outputBuf=&output;
   g_includeStack.setAutoDelete(TRUE);
   g_includeStack.clear();
diff --git a/src/scanner.l b/src/scanner.l
index 3bee67e..eb5c5f6 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -693,6 +693,11 @@ TITLE     [tT][iI][tT][lL][eE]
 					  current->fileName  = yyFileName;
 					  current->startLine = yyLineNr;
 					  current->bodyLine  = yyLineNr;
+					  if (current->mtArgList) // transfer template arguments
+					  {
+					    current->tArgList = current->mtArgList;
+					    current->mtArgList = 0;
+					  }
 					  lineCount() ;
 					  BEGIN( CompoundName ) ;
 					}
@@ -749,9 +754,9 @@ TITLE     [tT][iI][tT][lL][eE]
   					  lineCount();
 					  // class template specifier already found => member template specifier
 					  // already inside class => member template specifier
-					  if (current->tArgList || (current_root->section&Entry::COMPOUND_MASK))
-					  {
-					    //printf("-------> member template\n");
+					  //if (current->tArgList /*|| (current_root->section&Entry::COMPOUND_MASK)*/)
+					  //{
+					  //  printf("-------> member template \n");
 					    if (current->mtArgList)
 					    {
 					      current->mtArgList->clear();
@@ -762,26 +767,25 @@ TITLE     [tT][iI][tT][lL][eE]
 					      current->mtArgList->setAutoDelete(TRUE);
 					    }
 					    currentArgumentList = current->mtArgList;
-					  }
-					  else // class template specifier
-					  {
-					    //printf("-------> class template\n");
-					    if (current->tArgList)
-					    {
-					      current->tArgList->clear();
-                                            }
-					    else
-					    {
-					      current->tArgList = new ArgumentList;
-					      current->tArgList->setAutoDelete(TRUE);
-					    }
-					    currentArgumentList = current->tArgList;
-					  }
+					  //}
+					  //else // class template specifier
+					  //{
+					  //  printf("-------> class template\n");
+					  //  if (current->tArgList)
+					  //  {
+					  //    current->tArgList->clear();
+                                          //  }
+					  //  else
+					  //  {
+					  //    current->tArgList = new ArgumentList;
+					  //    current->tArgList->setAutoDelete(TRUE);
+					  //  }
+					  //  currentArgumentList = current->tArgList;
+					  //}
 					  templateStr="<";
 					  fullArgString = templateStr.copy();
 					  copyArgString = &templateStr;
 					  currentArgumentContext = FindMembers;
-					  //printf("Start template list\n");
 					  BEGIN( ReadTempArgs );
   					}
 <FindMembers>"namespace"{BN}+/{ID}{BN}*"=" { // namespace alias
@@ -793,7 +797,7 @@ TITLE     [tT][iI][tT][lL][eE]
 					  BEGIN( NSAliasArg );
   					}
 <NSAliasArg>({ID}"::")*{ID}		{
-  					  printf("Inserting namespace alias %s::%s->%s\n",current_root->name.data(),aliasName.data(),yytext);
+  					  //printf("Inserting namespace alias %s::%s->%s\n",current_root->name.data(),aliasName.data(),yytext);
 					  if (current_root->name.isEmpty())
 					  {
 					    namespaceAliasDict.insert(aliasName,new QCString(yytext));
@@ -1616,6 +1620,7 @@ TITLE     [tT][iI][tT][lL][eE]
   					  lineCount();
   					  addType(current);
 					  funcPtrType=yytext;
+					  roundCount=0;
 					  //current->type += yytext;
 					  BEGIN( FuncPtr );
   					}
@@ -1638,12 +1643,12 @@ TITLE     [tT][iI][tT][lL][eE]
 					  current->type+=funcPtrType.data()+1;
   					  BEGIN(FindMembers);
   					}
-<EndFuncPtr>")"{BN}*/"("		{ // a variable function
+<EndFuncPtr>")"{BN}*/"("		{ // a function pointer
   					  lineCount();
 					  current->type+=funcPtrType+")";
 					  BEGIN(FindMembers);
   					}
-<EndFuncPtr>")"{BN}*/"["		{
+<EndFuncPtr>")"{BN}*/"["		{ // an array of variables
   					  lineCount();
 					  current->type+=funcPtrType.data();
 					  current->args += ")";
@@ -1654,6 +1659,9 @@ TITLE     [tT][iI][tT][lL][eE]
 					  roundCount=0;
 					  BEGIN( FuncFunc );
   					}
+<EndFuncPtr>"["[^\n\]]*"]"		{
+  					  funcPtrType+=yytext;
+  					}
 <EndFuncPtr>")"				{
   					  BEGIN(FindMembers);
   					}
@@ -1790,7 +1798,7 @@ TITLE     [tT][iI][tT][lL][eE]
 <ReadTempArgs>"<"			{
 					  *copyArgString+=*yytext;
 					  fullArgString+=*yytext;
-					  argSharpCount=0;
+					  argSharpCount=1;
 					  BEGIN( CopyArgSharp );
 					}
 <ReadTempArgs>">"			{
@@ -1815,16 +1823,23 @@ TITLE     [tT][iI][tT][lL][eE]
   					}
 <CopyArgSharp>"<"			{
   					  argSharpCount++;
+					  //printf("argSharpCount++=%d  copy\n",argSharpCount);
 					  *copyArgString+=*yytext;
 					  fullArgString+=*yytext;
   					}
 <CopyArgSharp>">"			{
   					  *copyArgString+=*yytext;
   					  fullArgString+=*yytext;
-					  if (argRoundCount>0)
-					    argRoundCount--;
+					  argSharpCount--;
+					  if (argSharpCount>0)
+					  {
+					    //printf("argSharpCount--=%d copy\n",argSharpCount);
+					  }
 					  else
+					  {
 					    BEGIN( ReadTempArgs );
+					    //printf("end of argSharpCount\n");
+					  }
   					}
 <CopyArgString>\\.			{
   					  *copyArgString+=yytext;
@@ -2631,6 +2646,8 @@ TITLE     [tT][iI][tT][lL][eE]
 					  BEGIN(ClassDocBrief);
   					}
 <TodoParam>\n                           |
+<TodoParam>"//"                         |
+<TodoParam>"/*"                         |
 <TodoParam>.				{
   					  if (current->todoId!=0)
 					  {
@@ -2659,6 +2676,8 @@ TITLE     [tT][iI][tT][lL][eE]
 					  BEGIN(todoStartContext);
   					}
 <TestParam>\n                           |
+<TestParam>"//"                         |
+<TestParam>"/*"                         |
 <TestParam>.				{
   					  if (current->testId!=0)
 					  {
@@ -3008,7 +3027,7 @@ TITLE     [tT][iI][tT][lL][eE]
 <ExampleDoc,PageDoc,ClassDoc>.    	 	        { current->doc += yytext; }
 <Doc,JavaDoc,LineDoc,ExampleDoc,PageDoc,ClassDoc>^{B}*"//" 
 <Doc,ExampleDoc,PageDoc,ClassDoc>"//"  			{ current->doc += yytext; }
-<LineDoc,JavaDoc>"//"					{ current->brief += yytext; }
+<LineDoc,JavaDoc,ClassDocBrief>"//"			{ current->brief += yytext; }
 <Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief>("\\\\"|"@@")"f"[$\[\]] {
 							  current->doc += &yytext[1]; 
 							}
diff --git a/src/translator_cn.h b/src/translator_cn.h
index 9343695..dfe5a78 100644
--- a/src/translator_cn.h
+++ b/src/translator_cn.h
@@ -51,6 +51,13 @@ class TranslatorChinese : public Translator
     { return "��Ա�����ĵ�"; }
     QCString trMemberDataDocumentation()
     { return "��Ա�����ĵ�"; }
+    QCString trGeneratedFrom(const char *s,bool single)
+    { 
+      QCString result=(QCString)"De documentatie voor deze"+s+
+                     " is gegenereerd op grond van de volgende file";
+      if (single) result+=":";   else result+="s:";
+      return result;
+    }
     QCString trMore()
     { return "����..."; }
     QCString trListOfAllMembers()
@@ -495,17 +502,17 @@ class TranslatorChinese : public Translator
     /*! Text for the \pre command */
     QCString trPrecondition()
     {
-      return "ǰ������";
+      return "ǰ������";
     }
     /*! Text for the \post command */
     QCString trPostcondition()
     {
-      return "Postcondition";
+      return "��������";
     }
     /*! Text for the \invariant command */
     QCString trInvariant()
     {
-      return "Invariant";
+      return "������";
     }
     /*! Text shown before a multi-line variable/enum initialization */
     QCString trInitialValue()
diff --git a/src/treeview.h b/src/treeview.h
index e74408a..213bc82 100644
--- a/src/treeview.h
+++ b/src/treeview.h
@@ -11,14 +11,17 @@
 "//       27 Jan 98 - Root folder starts open; support for USETEXTLINKS; \n"
 "//                   make the ftien4 a js file \n"
 "//       \n"
+"// DvH:  Dec 2000 -  Made some minor changes to support external \n"
+"//                   references\n"
 " \n"
 "// Definition of class Folder \n"
 "// ***************************************************************** \n"
 " \n"
-"function Folder(folderDescription, hreference) //constructor \n"
+"function Folder(folderDescription, tagName, hreference) //constructor \n"
 "{ \n"
 "  //constant data \n"
 "  this.desc = folderDescription \n"
+"  this.tagName = tagName\n"
 "  this.hreference = hreference \n"
 "  this.id = -1   \n"
 "  this.navObj = 0  \n"
@@ -186,6 +189,10 @@
 "  } \n"
 "  else \n"
 "    doc.write(this.desc) \n"
+"  if (this.tagName!=\"\")\n"
+"  {\n"
+"    doc.write(\" [external]\")\n"
+"  }\n"
 "  doc.write(\"</td>\")  \n"
 "  doc.write(\"\\n</table>\\n\") \n"
 "   \n"
@@ -209,7 +216,12 @@
 "{ \n"
 "  if (this.hreference) \n"
 "  { \n"
-"    doc.write(\"<a href='\" + this.hreference + \"' TARGET=\\\"basefrm\\\" \") \n"
+"    doc.write(\"<a \")\n"
+"    if (this.tagName)\n"
+"    {\n"
+"      doc.write(\"doxygen='\" + this.tagName + \"' \");\n"
+"    }\n"
+"    doc.write(\"href='\" + this.hreference + \"' TARGET=\\\"basefrm\\\" \") \n"
 "    if (browserVersion > 0) \n"
 "      doc.write(\"onClick='javascript:clickOnFolder(\"+this.id+\")'\") \n"
 "    doc.write(\">\") \n"
@@ -242,10 +254,11 @@
 "// Definition of class Item (a document or link inside a Folder) \n"
 "// ************************************************************* \n"
 " \n"
-"function Item(itemDescription, itemLink) // Constructor \n"
+"function Item(itemDescription, tagName, itemLink) // Constructor \n"
 "{ \n"
 "  // constant data \n"
 "  this.desc = itemDescription \n"
+"  this.tagName = tagName\n"
 "  this.link = itemLink \n"
 "  this.id = -1 //initialized in initalize() \n"
 "  this.navObj = 0 //initialized in render() \n"
@@ -319,6 +332,10 @@
 "    doc.write(\"<a href=\" + this.link + \">\" + this.desc + \"</a>\") \n"
 "  else \n"
 "    doc.write(this.desc) \n"
+"  if (this.tagName!=\"\")\n"
+"  {\n"
+"    doc.write(\" [external]\");\n"
+"  }\n"
 "  doc.write(\"\\n</table>\\n\") \n"
 "   \n"
 "  if (browserVersion == 2) \n"
@@ -422,32 +439,22 @@
 "// Auxiliary Functions for Folder-Treee backward compatibility \n"
 "// ********************************************************* \n"
 " \n"
-"function gFld(description, hreference) \n"
+"function gFld(description, tagName, hreference) \n"
 "{ \n"
-"  folder = new Folder(description, hreference) \n"
+"  folder = new Folder(description, tagName, hreference) \n"
 "  return folder \n"
 "} \n"
 " \n"
-"function gLnk(target, description, linkData) \n"
+"function gLnk(description, tagName, linkData) \n"
 "{ \n"
 "  fullLink = \"\" \n"
 " \n"
 "  if (linkData!=\"\")\n"
 "  {\n"
-"    if (target==0) \n"
-"    { \n"
-"      fullLink = \"'\"+linkData+\"' target=\\\"basefrm\\\"\" \n"
-"    } \n"
-"    else \n"
-"    { \n"
-"      if (target==1) \n"
-"        fullLink = \"'http://\"+linkData+\"' target=_blank\" \n"
-"      else \n"
-"        fullLink = \"'http://\"+linkData+\"' target=\\\"basefrm\\\"\" \n"
-"    }\n"
+"    fullLink = \"'\"+linkData+\"' target=\\\"basefrm\\\"\" \n"
 "  } \n"
 " \n"
-"  linkItem = new Item(description, fullLink)   \n"
+"  linkItem = new Item(description, tagName, fullLink)   \n"
 "  return linkItem \n"
 "} \n"
 " \n"
diff --git a/src/treeview.js b/src/treeview.js
index 8fd91b1..58ca384 100644
--- a/src/treeview.js
+++ b/src/treeview.js
@@ -11,14 +11,17 @@
 //       27 Jan 98 - Root folder starts open; support for USETEXTLINKS; 
 //                   make the ftien4 a js file 
 //       
+// DvH:  Dec 2000 -  Made some minor changes to support external 
+//                   references
  
 // Definition of class Folder 
 // ***************************************************************** 
  
-function Folder(folderDescription, hreference) //constructor 
+function Folder(folderDescription, tagName, hreference) //constructor 
 { 
   //constant data 
   this.desc = folderDescription 
+  this.tagName = tagName
   this.hreference = hreference 
   this.id = -1   
   this.navObj = 0  
@@ -186,6 +189,10 @@ function drawFolder(leftSide)
   } 
   else 
     doc.write(this.desc) 
+  if (this.tagName!="")
+  {
+    doc.write(" [external]")
+  }
   doc.write("</td>")  
   doc.write("\n</table>\n") 
    
@@ -209,7 +216,12 @@ function outputFolderLink()
 { 
   if (this.hreference) 
   { 
-    doc.write("<a href='" + this.hreference + "' TARGET=\"basefrm\" ") 
+    doc.write("<a ")
+    if (this.tagName)
+    {
+      doc.write("doxygen='" + this.tagName + "' ");
+    }
+    doc.write("href='" + this.hreference + "' TARGET=\"basefrm\" ") 
     if (browserVersion > 0) 
       doc.write("onClick='javascript:clickOnFolder("+this.id+")'") 
     doc.write(">") 
@@ -242,10 +254,11 @@ function folderSubEntries()
 // Definition of class Item (a document or link inside a Folder) 
 // ************************************************************* 
  
-function Item(itemDescription, itemLink) // Constructor 
+function Item(itemDescription, tagName, itemLink) // Constructor 
 { 
   // constant data 
   this.desc = itemDescription 
+  this.tagName = tagName
   this.link = itemLink 
   this.id = -1 //initialized in initalize() 
   this.navObj = 0 //initialized in render() 
@@ -319,6 +332,10 @@ function drawItem(leftSide)
     doc.write("<a href=" + this.link + ">" + this.desc + "</a>") 
   else 
     doc.write(this.desc) 
+  if (this.tagName!="")
+  {
+    doc.write(" [external]");
+  }
   doc.write("\n</table>\n") 
    
   if (browserVersion == 2) 
@@ -422,32 +439,22 @@ function initializeDocument()
 // Auxiliary Functions for Folder-Treee backward compatibility 
 // ********************************************************* 
  
-function gFld(description, hreference) 
+function gFld(description, tagName, hreference) 
 { 
-  folder = new Folder(description, hreference) 
+  folder = new Folder(description, tagName, hreference) 
   return folder 
 } 
  
-function gLnk(target, description, linkData) 
+function gLnk(description, tagName, linkData) 
 { 
   fullLink = "" 
  
   if (linkData!="")
   {
-    if (target==0) 
-    { 
-      fullLink = "'"+linkData+"' target=\"basefrm\"" 
-    } 
-    else 
-    { 
-      if (target==1) 
-        fullLink = "'http://"+linkData+"' target=_blank" 
-      else 
-        fullLink = "'http://"+linkData+"' target=\"basefrm\"" 
-    }
+    fullLink = "'"+linkData+"' target=\"basefrm\"" 
   } 
  
-  linkItem = new Item(description, fullLink)   
+  linkItem = new Item(description, tagName, fullLink)   
   return linkItem 
 } 
  
-- 
cgit v0.12

