From 0ee700fc0f6a02b75aa5651c23cc3339c1255ebc Mon Sep 17 00:00:00 2001
From: dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>
Date: Sun, 7 Jan 2007 21:17:16 +0000
Subject: Release-1.5.1-20070107

---
 addon/doxywizard/Makefile.in           |   2 +-
 addon/doxywizard/Makefile.win_nmake.in |   2 +-
 addon/doxywizard/doxywizard.pro.in     |   2 +-
 addon/doxywizard/expert.cpp            |   2 +-
 addon/doxywizard/expert.h              |   2 +-
 addon/doxywizard/inputbool.cpp         |   2 +-
 addon/doxywizard/inputbool.h           |   2 +-
 addon/doxywizard/inputint.cpp          |   2 +-
 addon/doxywizard/inputint.h            |   2 +-
 addon/doxywizard/inputstring.cpp       |   2 +-
 addon/doxywizard/inputstring.h         |   2 +-
 addon/doxywizard/inputstrlist.cpp      |   2 +-
 addon/doxywizard/inputstrlist.h        |   2 +-
 addon/doxywizard/qtbc.h                |   2 +-
 addon/doxywizard/version.h             |   2 +-
 doc/config.doc                         |  46 +-
 doc/translator_report.txt              |   4 -
 qtools/qgstring.cpp                    |  33 +-
 src/Makefile.in                        |   2 +-
 src/bufstr.h                           |   2 +-
 src/classdef.cpp                       |   7 +-
 src/classdef.h                         |   2 +-
 src/classlist.cpp                      |   2 +-
 src/classlist.h                        |   2 +-
 src/code.h                             |   2 +-
 src/code.l                             |  30 +-
 src/commentcnv.h                       |   2 +-
 src/commentcnv.l                       |   2 +-
 src/commentscan.l                      |   4 +-
 src/config.l                           |  46 +-
 src/constexp.h                         |   2 +-
 src/constexp.l                         |   2 +-
 src/constexp.y                         |   2 +-
 src/cppvalue.cpp                       |   2 +-
 src/cppvalue.h                         |   2 +-
 src/debug.cpp                          |   2 +-
 src/debug.h                            |   2 +-
 src/declinfo.h                         |   2 +-
 src/declinfo.l                         |   2 +-
 src/defargs.h                          |   2 +-
 src/defargs.l                          |   2 +-
 src/defgen.cpp                         |   8 +-
 src/defgen.h                           |   2 +-
 src/define.cpp                         |   2 +-
 src/define.h                           |   2 +-
 src/definition.cpp                     |  75 +--
 src/definition.h                       |  22 +-
 src/diagram.cpp                        |   2 +-
 src/diagram.h                          |   2 +-
 src/dirdef.h                           |   2 +-
 src/docparser.cpp                      |  24 +-
 src/docparser.h                        |   6 +-
 src/doctokenizer.h                     |   3 +-
 src/doctokenizer.l                     |  14 +-
 src/docvisitor.h                       |   5 +-
 src/dot.cpp                            | 854 ++++++++++++++++++++++-----------
 src/dot.h                              |  69 +--
 src/doxygen.cpp                        | 349 ++++++++------
 src/doxygen.h                          |   2 +-
 src/doxygen.pro.in                     |   2 +-
 src/doxytag.l                          |   2 +-
 src/doxytag.pro.in                     |   2 +-
 src/doxytag.t                          |   2 +-
 src/entry.cpp                          |   2 +-
 src/entry.h                            |   2 +-
 src/example.h                          |   2 +-
 src/filedef.cpp                        |  17 +-
 src/filedef.h                          |   2 +-
 src/filename.cpp                       |   2 +-
 src/filename.h                         |   2 +-
 src/formula.cpp                        |   2 +-
 src/formula.h                          |   2 +-
 src/groupdef.cpp                       |   2 +-
 src/groupdef.h                         |   2 +-
 src/htmlattrib.h                       |   2 +-
 src/htmldocvisitor.cpp                 |  18 +-
 src/htmldocvisitor.h                   |   5 +-
 src/htmlgen.cpp                        |  15 +-
 src/htmlgen.h                          |   5 +-
 src/htmlhelp.cpp                       |   2 +-
 src/htmlhelp.h                         |   2 +-
 src/image.cpp                          |   2 +-
 src/image.h                            |   2 +-
 src/index.cpp                          |   2 +-
 src/index.h                            |   2 +-
 src/instdox.cpp                        |   2 +-
 src/instdox.h                          |   2 +-
 src/language.h                         |   2 +-
 src/latexdocvisitor.cpp                |  11 +-
 src/latexdocvisitor.h                  |   2 +-
 src/latexgen.cpp                       |   5 +-
 src/latexgen.h                         |   7 +-
 src/libdoxycfg.pro.in                  |   2 +-
 src/libdoxycfg.t                       |   2 +-
 src/libdoxygen.pro.in                  |   4 +-
 src/libdoxygen.t                       |   2 +-
 src/lockingptr.h                       |   2 +-
 src/logos.cpp                          |   2 +-
 src/logos.h                            |   2 +-
 src/main.cpp                           |   2 +-
 src/mandocvisitor.cpp                  |   2 +-
 src/mandocvisitor.h                    |   2 +-
 src/mangen.cpp                         |   5 +-
 src/mangen.h                           |   5 +-
 src/marshal.cpp                        |  28 ++
 src/marshal.h                          |   3 +
 src/memberdef.cpp                      | 168 ++-----
 src/memberdef.h                        |   1 +
 src/membergroup.cpp                    |  12 +-
 src/membergroup.h                      |   2 +-
 src/memberlist.cpp                     |   2 +-
 src/memberlist.h                       |   2 +-
 src/membername.cpp                     |   2 +-
 src/membername.h                       |   2 +-
 src/message.cpp                        |   2 +-
 src/message.h                          |   2 +-
 src/namespacedef.cpp                   |   2 +-
 src/namespacedef.h                     |   2 +-
 src/objcache.cpp                       |   2 +-
 src/objcache.h                         |   2 +-
 src/outputgen.cpp                      |   2 +-
 src/outputgen.h                        |  18 +-
 src/outputlist.cpp                     |   2 +-
 src/outputlist.h                       |   7 +-
 src/pagedef.h                          |   2 +-
 src/parserintf.h                       |   2 +-
 src/pngenc.cpp                         |   2 +-
 src/pngenc.h                           |   2 +-
 src/pre.h                              |   2 +-
 src/pre.l                              |   2 +-
 src/printdocvisitor.h                  |   2 +-
 src/pycode.h                           |   2 +-
 src/pycode.l                           |  19 +-
 src/pyscanner.h                        |   2 +-
 src/pyscanner.l                        |   2 +-
 src/qtbc.h                             |   2 +-
 src/reflist.cpp                        |   2 +-
 src/reflist.h                          |   2 +-
 src/rtfdocvisitor.cpp                  |   9 +-
 src/rtfdocvisitor.h                    |   2 +-
 src/rtfgen.cpp                         |   5 +-
 src/rtfgen.h                           |   5 +-
 src/rtfstyle.cpp                       |   2 +-
 src/rtfstyle.h                         |   2 +-
 src/scanner.h                          |   2 +-
 src/scanner.l                          |  36 +-
 src/searchindex.cpp                    |   2 +-
 src/searchindex.h                      |   2 +-
 src/section.h                          |   2 +-
 src/sortdict.h                         |   2 +-
 src/store.cpp                          |  18 +
 src/store.h                            |   2 +-
 src/tagreader.cpp                      |   2 +-
 src/tagreader.h                        |   2 +-
 src/textdocvisitor.cpp                 |  79 +++
 src/textdocvisitor.h                   | 132 +++++
 src/translator_adapter.h               |  43 --
 src/translator_jp.h                    |   7 +-
 src/translator_nl.h                    |   2 +-
 src/translator_pt.h                    |   2 +-
 src/translator_ro.h                    |   2 +-
 src/translator_si.h                    |   2 +-
 src/util.cpp                           |  73 ++-
 src/util.h                             |   3 +-
 src/version.h                          |   2 +-
 src/xmldocvisitor.cpp                  |   2 +-
 src/xmldocvisitor.h                    |   2 +-
 src/xmlgen.cpp                         |  22 +-
 src/xmlgen.h                           |   2 +-
 169 files changed, 1635 insertions(+), 989 deletions(-)
 create mode 100644 src/textdocvisitor.cpp
 create mode 100644 src/textdocvisitor.h

diff --git a/addon/doxywizard/Makefile.in b/addon/doxywizard/Makefile.in
index e81c5c5..2be7628 100644
--- a/addon/doxywizard/Makefile.in
+++ b/addon/doxywizard/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 # 
diff --git a/addon/doxywizard/Makefile.win_nmake.in b/addon/doxywizard/Makefile.win_nmake.in
index 74a67a5..e48e05e 100644
--- a/addon/doxywizard/Makefile.win_nmake.in
+++ b/addon/doxywizard/Makefile.win_nmake.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 # 
diff --git a/addon/doxywizard/doxywizard.pro.in b/addon/doxywizard/doxywizard.pro.in
index ea1f3de..1562b51 100644
--- a/addon/doxywizard/doxywizard.pro.in
+++ b/addon/doxywizard/doxywizard.pro.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 #
diff --git a/addon/doxywizard/expert.cpp b/addon/doxywizard/expert.cpp
index e2552a6..10a2e04 100644
--- a/addon/doxywizard/expert.cpp
+++ b/addon/doxywizard/expert.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/expert.h b/addon/doxywizard/expert.h
index e210253..3e13b47 100644
--- a/addon/doxywizard/expert.h
+++ b/addon/doxywizard/expert.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/inputbool.cpp b/addon/doxywizard/inputbool.cpp
index ffb2e76..a2208f5 100644
--- a/addon/doxywizard/inputbool.cpp
+++ b/addon/doxywizard/inputbool.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/inputbool.h b/addon/doxywizard/inputbool.h
index b7de7ed..ed7861d 100644
--- a/addon/doxywizard/inputbool.h
+++ b/addon/doxywizard/inputbool.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/inputint.cpp b/addon/doxywizard/inputint.cpp
index e926b5e..6489f60 100644
--- a/addon/doxywizard/inputint.cpp
+++ b/addon/doxywizard/inputint.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/inputint.h b/addon/doxywizard/inputint.h
index 094f03c..50e4b61 100644
--- a/addon/doxywizard/inputint.h
+++ b/addon/doxywizard/inputint.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/inputstring.cpp b/addon/doxywizard/inputstring.cpp
index a132ff1..754e045 100644
--- a/addon/doxywizard/inputstring.cpp
+++ b/addon/doxywizard/inputstring.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/inputstring.h b/addon/doxywizard/inputstring.h
index b1b2a7a..7e7b639 100644
--- a/addon/doxywizard/inputstring.h
+++ b/addon/doxywizard/inputstring.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/inputstrlist.cpp b/addon/doxywizard/inputstrlist.cpp
index 3d26f21..2dc80ab 100644
--- a/addon/doxywizard/inputstrlist.cpp
+++ b/addon/doxywizard/inputstrlist.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/inputstrlist.h b/addon/doxywizard/inputstrlist.h
index b3c8909..7c79adb 100644
--- a/addon/doxywizard/inputstrlist.h
+++ b/addon/doxywizard/inputstrlist.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/qtbc.h b/addon/doxywizard/qtbc.h
index 029b84d..b1baec4 100644
--- a/addon/doxywizard/qtbc.h
+++ b/addon/doxywizard/qtbc.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/addon/doxywizard/version.h b/addon/doxywizard/version.h
index b86bb2e..226de7e 100644
--- a/addon/doxywizard/version.h
+++ b/addon/doxywizard/version.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/doc/config.doc b/doc/config.doc
index 2ebb6a5..be0c4a5 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -79,6 +79,7 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_directory_graph DIRECTORY_GRAPH
 \refitem cfg_disable_index DISABLE_INDEX 
 \refitem cfg_distribute_group_doc DISTRIBUTE_GROUP_DOC
+\refitem cfg_dot_graph_max_nodes DOT_GRAPH_MAX_NODES
 \refitem cfg_dot_image_format DOT_IMAGE_FORMAT
 \refitem cfg_dot_multi_targets DOT_MULTI_TARGETS
 \refitem cfg_dot_path DOT_PATH
@@ -160,9 +161,6 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_man_extension MAN_EXTENSION
 \refitem cfg_man_links MAN_LINKS
 \refitem cfg_man_output MAN_OUTPUT
-\refitem cfg_max_dot_graph_depth MAX_DOT_GRAPH_DEPTH
-\refitem cfg_max_dot_graph_height MAX_DOT_GRAPH_HEIGHT
-\refitem cfg_max_dot_graph_width MAX_DOT_GRAPH_WIDTH
 \refitem cfg_max_initializer_lines MAX_INITIALIZER_LINES
 \refitem cfg_multiline_cpp_is_brief MULTILINE_CPP_IS_BRIEF
 \refitem cfg_optimize_output_for_c OPTIMIZE_OUTPUT_FOR_C
@@ -1728,6 +1726,15 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre>
  in a graphical way. The dependency relations are determined by the \#include
  relations between the files in the directories.
 
+\anchor cfg_dot_graph_max_nodes 
+<dt>\c DOT_GRAPH_MAX_NODES <dd>
+ \addindex DOT_GRAPH_MAX_NODES
+ The \c MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+ nodes that will be shown in the graph. If the number of nodes in a graph 
+ becomes larger than this value, doxygen will truncate the graph, which is
+ visualized by representing a node as a red box. Note that doxygen will always 
+ show the root nodes and its direct children regardless of this setting. 
+
 \anchor cfg_dot_image_format
 <dt>\c DOT_IMAGE_FORMAT <dd>
  \addindex DOT_IMAGE_FORMAT
@@ -1748,39 +1755,6 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre>
  contain dot files that are included in the documentation (see the
  \\dotfile command).
 
-\anchor cfg_max_dot_graph_height 
-<dt>\c MAX_DOT_GRAPH_HEIGHT <dd>
- \addindex MAX_DOT_GRAPH_HEIGHT
- The \c MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
- (in pixels) of the graphs generated by dot. If a graph becomes larger than
- this value, doxygen will try to truncate the graph, so that it fits within
- the specified constraint. Beware that most browsers cannot cope with very
- large images.
-
-\anchor cfg_max_dot_graph_depth
-<dt>\c MAX_DOT_GRAPH_DEPTH <dd>
-\addindex MAX_DOT_GRAPH_DEPTH
-The \c MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-graphs generated by dot. A depth value of 3 means that only nodes reachable 
-from the root by following a path via at most 3 edges will be shown. Nodes that
-lay further from the root node will be omitted. Note that setting this option to 
-1 or 2 may greatly reduce the computation time needed for large code bases. Also 
-note that a graph may be further truncated if the graph's image dimensions are 
-not sufficient to fit the graph (see 
-\ref cfg_max_dot_graph_width "MAX_DOT_GRAPH_WIDTH" and 
-\ref cfg_max_dot_graph_height "MAX_DOT_GRAPH_HEIGHT"). 
-If 0 is used for the depth value (the default), the graph is 
-not depth-constraint.
-
-\anchor cfg_max_dot_graph_width 
-<dt>\c MAX_DOT_GRAPH_WIDTH <dd>
- \addindex MAX_DOT_GRAPH_WIDTH
- The \c MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
- (in pixels) of the graphs generated by dot. If a graph becomes larger than
- this value, doxygen will try to truncate the graph, so that it fits within
- the specified constraint. Beware that most browsers cannot cope with very
- large images.
-
 \anchor cfg_dot_transparent
 <dt>\c DOT_TRANSPARENT <dd>
  \addindex DOT_TRANSPARENT
diff --git a/doc/translator_report.txt b/doc/translator_report.txt
index 9df007e..65f29c6 100644
--- a/doc/translator_report.txt
+++ b/doc/translator_report.txt
@@ -58,10 +58,6 @@ must be implemented to become up-to-date:
   TranslatorSlovak                1.2.18	22 methods to implement
   TranslatorFinnish               obsolete	96 methods to implement
 
-Note: The adapter classes TranslatorAdapter_1_2_11,
-TranslatorAdapter_1_2_13, TranslatorAdapter_1_2_16,
-TranslatorAdapter_1_2_17 are not used and can be removed.
-
 ----------------------------------------------------------------------
 The following translator classes derive directly from the
 TranslatorEnglish. The class identifier has the suffix 'En' that says
diff --git a/qtools/qgstring.cpp b/qtools/qgstring.cpp
index a19d747..f43cd6b 100644
--- a/qtools/qgstring.cpp
+++ b/qtools/qgstring.cpp
@@ -13,6 +13,7 @@
  *
  */
 
+#include <stdio.h>
 #include "qgstring.h"
 
 #include <assert.h>
@@ -20,25 +21,31 @@
 #define BLOCK_SIZE 64
 #define ROUND_SIZE(x) ((x)+BLOCK_SIZE-1)&~(BLOCK_SIZE-1)
 
+#define DBG_STR(x) do { } while(0)
+
 QGString::QGString() // make null string
   : m_data(0), m_len(0), m_memSize(0) 
 {
+  DBG_STR(("%p: QGString::QGString() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
 } 
 
 QGString::QGString(uint size)
 {
-  m_memSize = ROUND_SIZE(size);
-  if (m_memSize==0)
+  if (size==0)
   {
     m_data=0;
     m_len=0;
   }
   else
   {
+    m_memSize = ROUND_SIZE(size+1);
     m_data = (char*)malloc(m_memSize);
-    m_data[0]='\0';
-    m_len=0;
+    memset(m_data,' ',size);
+    m_data[size]='\0';
+    m_len=size;
   }
+  DBG_STR(("%p: QGString::QGString(uint size=%d) %d:%s\n",
+      this,size,m_len,m_data?m_data:"<none>"));
 }
 
 QGString::QGString( const QGString &s ) 
@@ -56,6 +63,7 @@ QGString::QGString( const QGString &s )
     m_memSize = s.m_memSize;
     qstrcpy(m_data,s.m_data);
   }
+  DBG_STR(("%p: QGString::QGString(const QGString &) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
 } 
 
 QGString::QGString( const char *str )
@@ -74,12 +82,14 @@ QGString::QGString( const char *str )
     m_data = (char *)malloc(m_memSize);
     qstrcpy(m_data,str);
   }
+  DBG_STR(("%p: QGString::QGString(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
 }
 
 QGString::~QGString() 
 { 
   free(m_data); 
   m_data=0; 
+  DBG_STR(("%p: QGString::~QGString() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
 }
 
 bool QGString::resize( uint newlen )
@@ -89,6 +99,7 @@ bool QGString::resize( uint newlen )
   {
     if (m_data) { free(m_data); m_data=0; }
     m_memSize=0;
+    DBG_STR(("%p: 1.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
     return TRUE;
   }
   m_memSize = ROUND_SIZE(newlen+1);
@@ -101,9 +112,14 @@ bool QGString::resize( uint newlen )
   {
     m_data = (char *)realloc(m_data,m_memSize);
   }
-  if (m_data==0) return FALSE;
+  if (m_data==0) 
+  {
+    DBG_STR(("%p: 2.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
+    return FALSE;
+  }
   m_data[newlen-1]='\0';
   m_len = qstrlen(m_data);
+  DBG_STR(("%p: 3.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
   return TRUE;
 }
 
@@ -123,6 +139,8 @@ QGString &QGString::operator=( const QGString &s )
     m_data    = (char*)malloc(m_memSize);
     qstrcpy(m_data,s.m_data);
   }
+  DBG_STR(("%p: QGString::operator=(const QGString &%p) %d:%s\n",
+      this,&s,m_len,m_data?m_data:"<none>"));
   return *this;
 }
 
@@ -143,6 +161,7 @@ QGString &QGString::operator=( const char *str )
     m_data    = (char*)malloc(m_memSize);
     qstrcpy(m_data,str);
   }
+  DBG_STR(("%p: QGString::operator=(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
   return *this;
 }
 
@@ -160,6 +179,8 @@ QGString &QGString::operator+=( const QGString &s )
     m_data = newData;
     memcpy( m_data + len1, s, len2 + 1 );
   }
+  m_len = len1+len2;
+  DBG_STR(("%p: QGString::operator+=(const QGString &) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
   return *this;
 }
 
@@ -178,6 +199,7 @@ QGString &QGString::operator+=( const char *str )
     memcpy( m_data + len1, str, len2 + 1 );
   }
   m_len+=len2;
+  DBG_STR(("%p: QGString::operator+=(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
   return *this;
 }
 
@@ -195,6 +217,7 @@ QGString &QGString::operator+=( char c )
     m_data[len+1] = '\0';
   }
   m_len++;
+  DBG_STR(("%p: QGString::operator+=(char s) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
   return *this;
 }
 
diff --git a/src/Makefile.in b/src/Makefile.in
index 86298ce..e9decc4 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,6 +1,6 @@
 
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 # 
diff --git a/src/bufstr.h b/src/bufstr.h
index 995211a..3fcdd1d 100644
--- a/src/bufstr.h
+++ b/src/bufstr.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/classdef.cpp b/src/classdef.cpp
index ed4a603..6d00ea5 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -563,7 +563,6 @@ void ClassDef::internalInsertMember(MemberDef *md,
                 {
                   MemberList *ml = createMemberList(MemberList::constructors);
                   ml->append(md);
-                  md->setSectionList(this,ml);
                 }
                 else
                 {
@@ -1260,7 +1259,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
   if (Config_getBool("HAVE_DOT") && Config_getBool("CLASS_GRAPH"))
     // write class diagram using dot
   {
-    DotClassGraph inheritanceGraph(this,DotNode::Inheritance,Config_getInt("MAX_DOT_GRAPH_DEPTH"));
+    DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
     if (!inheritanceGraph.isTrivial())
     {
       ol.pushGeneratorState();
@@ -1295,7 +1294,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
 
   if (Config_getBool("HAVE_DOT") && Config_getBool("COLLABORATION_GRAPH"))
   {
-    DotClassGraph usageImplGraph(this,DotNode::Collaboration,Config_getInt("MAX_DOT_GRAPH_DEPTH"));
+    DotClassGraph usageImplGraph(this,DotNode::Collaboration);
     if (!usageImplGraph.isTrivial())
     {
       ol.pushGeneratorState();
diff --git a/src/classdef.h b/src/classdef.h
index 7152d84..5d745bf 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/classlist.cpp b/src/classlist.cpp
index aac8f95..67507d6 100644
--- a/src/classlist.cpp
+++ b/src/classlist.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/classlist.h b/src/classlist.h
index 3621e3b..0b74b03 100644
--- a/src/classlist.h
+++ b/src/classlist.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/code.h b/src/code.h
index 26d8f7e..15dcdee 100644
--- a/src/code.h
+++ b/src/code.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/code.l b/src/code.l
index fa7b056..6a6224d 100644
--- a/src/code.l
+++ b/src/code.l
@@ -552,7 +552,8 @@ static void codifyLines(char *text)
  */
 static void writeMultiLineCodeLink(CodeOutputInterface &ol,
                   const char *ref,const char *file,
-                  const char *anchor,const char *text)
+                  const char *anchor,const char *text,
+		  const char *tooltip)
 {
   bool done=FALSE;
   char *p=(char *)text;
@@ -566,7 +567,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol,
       g_yyLineNr++;
       *(p-1)='\0';
       //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
-      ol.writeCodeLink(ref,file,anchor,sp);
+      ol.writeCodeLink(ref,file,anchor,sp,tooltip);
       endCodeLine();
       if (g_yyLineNr<g_inputLines) 
       {
@@ -576,7 +577,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol,
     else
     {
       //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
-      ol.writeCodeLink(ref,file,anchor,sp);
+      ol.writeCodeLink(ref,file,anchor,sp,tooltip);
       done=TRUE;
     }
   }
@@ -834,7 +835,8 @@ static bool getLinkInScope(const QCString &c,  // scope
       writeMultiLineCodeLink(ol,md->getReference(),
 	                        md->getOutputFileBase(),
 	                        md->anchor(),
-				text ? text : memberText);
+				text ? text : memberText,
+				md->briefDescriptionAsTooltip());
       addToSearchIndex(text ? text : memberText);
       return TRUE;
     } 
@@ -942,7 +944,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
     }
     ol.linkableSymbol(g_yyLineNr,cd->name(),cd,
                       g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
-    writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,clName);
+    writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,clName,cd->briefDescriptionAsTooltip());
     addToSearchIndex(className);
     if (md)
     {
@@ -985,7 +987,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
 	{
           ol.linkableSymbol(g_yyLineNr,md->name(),md,
 	                    g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
-	  writeMultiLineCodeLink(ol,md->getReference(),md->getOutputFileBase(),md->anchor(),clName);
+	  writeMultiLineCodeLink(ol,md->getReference(),md->getOutputFileBase(),md->anchor(),clName,md->briefDescriptionAsTooltip());
           addToSearchIndex(clName);
 	  if (g_currentMemberDef)
 	  {
@@ -1057,7 +1059,7 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,ClassDef *mcd,const
         ol.linkableSymbol(g_yyLineNr,xmd->name(),xmd,
                           g_currentMemberDef ? g_currentMemberDef : g_currentDefinition);
 	writeMultiLineCodeLink(ol,xmd->getReference(),
-	    xmd->getOutputFileBase(),xmd->anchor(),memName);
+	    xmd->getOutputFileBase(),xmd->anchor(),memName,xmd->briefDescriptionAsTooltip());
         addToSearchIndex(memName);
 	return TRUE;
       }
@@ -1352,7 +1354,8 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx)
 		                     ctx->method->getReference(),
 	                             ctx->method->getOutputFileBase(),
 	                             ctx->method->anchor(),
-				     pName->data());
+				     pName->data(),
+				     ctx->method->briefDescriptionAsTooltip());
 	      if (g_currentMemberDef)
 	      {
 	        addDocCrossReference(g_currentMemberDef,ctx->method);
@@ -1439,7 +1442,8 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx)
 		    ctx->objectVar->getReference(),
 		    ctx->objectVar->getOutputFileBase(),
 		    ctx->objectVar->anchor(),
-		    pObject->data());
+		    pObject->data(),
+		    ctx->objectVar->briefDescriptionAsTooltip());
 	      if (g_currentMemberDef)
 	      {
 	        addDocCrossReference(g_currentMemberDef,ctx->objectVar);
@@ -1457,7 +1461,8 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx)
 		    cd->getReference(),
 		    cd->getOutputFileBase(),
 		    0,
-		    pObject->data());
+		    pObject->data(),
+		    cd->briefDescriptionAsTooltip());
 	    }
 	    else // object still needs to be resolved
 	    {
@@ -1472,7 +1477,8 @@ static void writeObjCMethodCall(ObjCCallCtx *ctx)
 		    cd->getReference(),
 		    cd->getOutputFileBase(),
 		    0,
-		    pObject->data());
+		    pObject->data(),
+		    cd->briefDescriptionAsTooltip());
 	      }
 	      else
 	      {
@@ -1822,7 +1828,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
 					  if (found)
 					  {
 					    //printf("      include file %s found=%d\n",fd->absFilePath().data(),found);
-					    g_code->writeCodeLink(fd->getReference(),fd->getOutputFileBase(),0,yytext);
+					    g_code->writeCodeLink(fd->getReference(),fd->getOutputFileBase(),0,yytext,fd->briefDescriptionAsTooltip());
 					  }
 					  else
 					  {
diff --git a/src/commentcnv.h b/src/commentcnv.h
index 5924135..7ccbc4f 100644
--- a/src/commentcnv.h
+++ b/src/commentcnv.h
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/commentcnv.l b/src/commentcnv.l
index b988c67..c26334e 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/commentscan.l b/src/commentscan.l
index 82178d4..ddd62a5 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -605,7 +605,6 @@ static inline void setOutput(OutputContext ctx)
 		    newXRefItemKey==xrefItemKey);              // with the same key if \xrefitem
   //printf("refKind=%d newXRefKind=%d xrefAppendToPrev=%d xrefAppendFlag=%d\n",
   //   	  xrefKind,newXRefKind,xrefAppendToPrev,xrefAppendFlag);
-  xrefItemKey = newXRefItemKey;
 
   //printf("setOutput(inContext=%d ctx=%d)\n",inContext,ctx);
   if (inContext==OutputXRef) // end of XRef section => add the item 
@@ -655,6 +654,7 @@ static inline void setOutput(OutputContext ctx)
 	break;
     }
   }
+  xrefItemKey = newXRefItemKey;
 
   int oldContext = inContext;
   inContext = ctx;
@@ -1319,7 +1319,7 @@ MAILADR   [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]
                                           xrefKind = XRef_Item;
 					  BEGIN( Comment );
   					}
-<XRefItemParam2>{LC}			{ // line continuation
+<XRefItemParam2,XRefItemParam3>{LC}	{ // line continuation
                                           yyLineNr++; 
 					  addOutput('\n');
   					}
diff --git a/src/config.l b/src/config.l
index 1c1dae7..19d3c1e 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -1145,7 +1145,7 @@ void Config::check()
 
 #undef PUTENV
 #undef SEP
-#if defined(_WIN32) && (__BORLANDC__ < 0x0550)
+#if defined(_WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ < 0x0550))
 #define PUTENV _putenv
 #define SEP ";"
 #else 
@@ -1167,11 +1167,13 @@ void Config::check()
     PUTENV(buf);
   }
 
+#if 0
   int &depth = Config_getInt("MAX_DOT_GRAPH_DEPTH");
   if (depth==0)
   {
     depth=1000;
   }
+#endif
   
   if (Config_getBool("OPTIMIZE_OUTPUT_JAVA") && Config_getBool("INLINE_INFO"))
   {
@@ -2751,38 +2753,18 @@ void Config::create()
   cl->setWidgetType(ConfigList::Dir);
   cl->addDependency("HAVE_DOT");
   ci = addInt(
-                    "MAX_DOT_GRAPH_WIDTH",
-                    "The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width \n"
-                    "(in pixels) of the graphs generated by dot. If a graph becomes larger than \n"
-                    "this value, doxygen will try to truncate the graph, so that it fits within \n"
-                    "the specified constraint. Beware that most browsers cannot cope with very \n"
-                    "large images. \n",
-                    100,30000, 1024
-                );
-  ci->addDependency("HAVE_DOT");
-  ci = addInt(
-                    "MAX_DOT_GRAPH_HEIGHT",
-                    "The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height \n"
-                    "(in pixels) of the graphs generated by dot. If a graph becomes larger than \n"
-                    "this value, doxygen will try to truncate the graph, so that it fits within \n"
-                    "the specified constraint. Beware that most browsers cannot cope with very \n"
-                    "large images. \n",
-                    100,30000,1024
-                );
-  ci = addInt(
-                    "MAX_DOT_GRAPH_DEPTH",
-                    "The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the \n"
-                    "graphs generated by dot. A depth value of 3 means that only nodes reachable \n"
-                    "from the root by following a path via at most 3 edges will be shown. Nodes \n"
-		    "that lay further from the root node will be omitted. Note that setting this \n"
-		    "option to 1 or 2 may greatly reduce the computation time needed for large \n"
-		    "code bases. Also note that a graph may be further truncated if the graph's \n"
-		    "image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH \n"
-		    "and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), \n"
-		    "the graph is not depth-constrained. \n",
-                    0,1000,0
+                    "DOT_GRAPH_MAX_NODES",
+                    "The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of \n"
+                    "nodes that will be shown in the graph. If the number of nodes in a graph \n"
+                    "becomes larger than this value, doxygen will truncate the graph, which is \n"
+                    "visualized by representing a node as a red box. Note that doxygen will always \n"
+                    "show the root nodes and its direct children regardless of this setting. \n",
+                    0,10000, 50
                 );
   ci->addDependency("HAVE_DOT");
+  addObsolete("MAX_DOT_GRAPH_WIDTH");
+  addObsolete("MAX_DOT_GRAPH_HEIGHT");
+  addObsolete("MAX_DOT_GRAPH_DEPTH");
   cb = addBool(
                     "DOT_TRANSPARENT",
 		    "Set the DOT_TRANSPARENT tag to YES to generate images with a transparent \n"
diff --git a/src/constexp.h b/src/constexp.h
index 67a7446..1a6c37b 100644
--- a/src/constexp.h
+++ b/src/constexp.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/constexp.l b/src/constexp.l
index 9b1409f..3a09242 100644
--- a/src/constexp.l
+++ b/src/constexp.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/constexp.y b/src/constexp.y
index 68b1ee9..81282dc 100644
--- a/src/constexp.y
+++ b/src/constexp.y
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp
index 4a59661..f1df666 100644
--- a/src/cppvalue.cpp
+++ b/src/cppvalue.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/cppvalue.h b/src/cppvalue.h
index 17ca81a..0a8d638 100644
--- a/src/cppvalue.h
+++ b/src/cppvalue.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/debug.cpp b/src/debug.cpp
index 7e8f9a2..258980e 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/debug.h b/src/debug.h
index 179e309..777b8fe 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/declinfo.h b/src/declinfo.h
index 4e83840..28c8add 100644
--- a/src/declinfo.h
+++ b/src/declinfo.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/declinfo.l b/src/declinfo.l
index f580edf..c269700 100644
--- a/src/declinfo.l
+++ b/src/declinfo.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/defargs.h b/src/defargs.h
index 87c5990..aeb8175 100644
--- a/src/defargs.h
+++ b/src/defargs.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/defargs.l b/src/defargs.l
index ec24ba0..e5a2de4 100644
--- a/src/defargs.l
+++ b/src/defargs.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/defgen.cpp b/src/defgen.cpp
index 529b913..8211151 100644
--- a/src/defgen.cpp
+++ b/src/defgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -457,16 +457,14 @@ void generateDEFForClass(ClassDef *cd,QTextStream &t)
   t << "  cp-documentation = <<_EnD_oF_dEf_TeXt_" << endl
     << cd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
 
-  DotClassGraph inheritanceGraph(cd,DotNode::Inheritance,
-                                 Config_getInt("MAX_DOT_GRAPH_DEPTH"));
+  DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
   if (!inheritanceGraph.isTrivial())
   {
     t << "  cp-inheritancegraph = <<_EnD_oF_dEf_TeXt_" << endl;
     inheritanceGraph.writeDEF(t);
     t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
   }
-  DotClassGraph collaborationGraph(cd,DotNode::Collaboration,
-                                 Config_getInt("MAX_DOT_GRAPH_DEPTH"));
+  DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
   if (!collaborationGraph.isTrivial())
   {
     t << "  cp-collaborationgraph = <<_EnD_oF_dEf_TeXt_" << endl;
diff --git a/src/defgen.h b/src/defgen.h
index 1bb562f..0e03064 100644
--- a/src/defgen.h
+++ b/src/defgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/define.cpp b/src/define.cpp
index fbce9b9..12846b9 100644
--- a/src/define.cpp
+++ b/src/define.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/define.h b/src/define.h
index 9779ca5..fc32bfe 100644
--- a/src/define.h
+++ b/src/define.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/definition.cpp b/src/definition.cpp
index 528a8d1..ce8d1c4 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -51,8 +51,7 @@ class DefinitionImpl
     DefinitionImpl();
    ~DefinitionImpl();
     void init(const char *df,int dl,
-         const char *n,const char *b,
-         const char *d);
+         const char *n);
 
     SectionDict *sectionDict;  // dictionary of all sections, not accessible
 
@@ -61,9 +60,9 @@ class DefinitionImpl
     QList<ListItemInfo> *xrefListItems; 
     GroupList *partOfGroups;            
 
-    DocInfo  *details; // not exported
-    DocInfo  *brief;   // not exported
-    BodyInfo *body;    // not exported
+    DocInfo   *details; // not exported
+    BriefInfo *brief;   // not exported
+    BodyInfo  *body;    // not exported
 
     QCString localName;      // local (unqualified) name of the definition
                                // in the future m_name should become m_localName
@@ -101,8 +100,7 @@ DefinitionImpl::~DefinitionImpl()
 }
 
 void DefinitionImpl::init(const char *df,int dl,
-                          const char *n,const char *b,
-                          const char *d)
+                          const char *n)
 {
   defFileName = df;
   int lastDot = defFileName.findRev('.');
@@ -123,25 +121,8 @@ void DefinitionImpl::init(const char *df,int dl,
   }
   //printf("m_localName=%s\n",m_localName.data());
 
-  if (b)
-  {
-    brief = new DocInfo;
-    brief->doc = b;
-  }
-  else
-  {
-    brief = 0;
-  }
-
-  if (d)
-  {
-    details = new DocInfo;
-    details->doc = d;
-  }
-  else
-  {
-    details = 0;
-  }
+  brief = 0;
+  details = 0;
   body = 0;
   sourceRefByDict=0;
   sourceRefsDict=0;
@@ -238,9 +219,11 @@ Definition::Definition(const char *df,int dl,
 {
   m_name = name;
   m_impl = new DefinitionImpl;
-  m_impl->init(df,dl,name,b,d);
+  m_impl->init(df,dl,name);
   m_isSymbol = isSymbol;
   if (isSymbol) addToMap(name,this);
+  _setBriefDescription(b,df,dl);
+  _setDocumentation(d,df,dl,TRUE);
 }
 
 Definition::~Definition()
@@ -307,10 +290,9 @@ void Definition::writeDocAnchorsToTagFile()
   }
 }
 
-void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) 
+void Definition::_setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) 
 { 
   if (d==0) return;
-  makeResident();
   //printf("Definition::setDocumentation(%s,%s,%d,%d)\n",d,docFile,docLine,stripWhiteSpace);
   QCString doc = d;
   if (stripWhiteSpace)
@@ -331,21 +313,26 @@ void Definition::setDocumentation(const char *d,const char *docFile,int docLine,
   m_impl->details->line = docLine;
 }
 
+void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
+{
+  if (d==0) return;
+  makeResident();
+  _setDocumentation(d,docFile,docLine,stripWhiteSpace);
+}
+
 #define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase)
 
-void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine) 
-{ 
+void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine)
+{
   if (b==0) return;
   static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE");
   static bool needsDot = outputLanguage!="Japanese" && 
                          outputLanguage!="Chinese" &&
                          outputLanguage!="Korean";
-  makeResident();
-
   //fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine);
   if (m_impl->brief==0)
   {
-    m_impl->brief = new DocInfo;
+    m_impl->brief = new BriefInfo;
   }
   m_impl->brief->doc=QCString(b).stripWhiteSpace();
   int bl=m_impl->brief->doc.length(); 
@@ -361,6 +348,14 @@ void Definition::setBriefDescription(const char *b,const char *briefFile,int bri
   }
   m_impl->brief->file = briefFile;
   m_impl->brief->line = briefLine;
+  m_impl->brief->tooltip = parseCommentAsText(m_impl->brief->doc,briefFile,briefLine);
+}
+
+void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine) 
+{ 
+  if (b==0) return;
+  makeResident();
+  _setBriefDescription(b,briefFile,briefLine);
 }
 
 /*! Reads a fragment of code from file \a fileName starting at 
@@ -1040,6 +1035,12 @@ QCString Definition::briefDescription() const
   return m_impl->brief ? m_impl->brief->doc : QCString(""); 
 }
 
+QCString Definition::briefDescriptionAsTooltip() const
+{
+  makeResident();
+  return m_impl->brief ? m_impl->brief->tooltip : QCString(""); 
+}
+
 int Definition::briefLine() const 
 { 
   makeResident();
@@ -1180,7 +1181,7 @@ void Definition::flushToDisk() const
   marshalItemInfoList (Doxygen::symbolStorage,m_impl->xrefListItems);
   marshalGroupList    (Doxygen::symbolStorage,m_impl->partOfGroups);
   marshalDocInfo      (Doxygen::symbolStorage,m_impl->details);
-  marshalDocInfo      (Doxygen::symbolStorage,m_impl->brief);
+  marshalBriefInfo    (Doxygen::symbolStorage,m_impl->brief);
   marshalBodyInfo     (Doxygen::symbolStorage,m_impl->body);
   marshalQCString     (Doxygen::symbolStorage,m_impl->localName);
   marshalQCString     (Doxygen::symbolStorage,m_impl->qualifiedName);
@@ -1209,7 +1210,7 @@ void Definition::loadFromDisk() const
   m_impl->xrefListItems   = unmarshalItemInfoList (Doxygen::symbolStorage);
   m_impl->partOfGroups    = unmarshalGroupList    (Doxygen::symbolStorage);
   m_impl->details         = unmarshalDocInfo      (Doxygen::symbolStorage);
-  m_impl->brief           = unmarshalDocInfo      (Doxygen::symbolStorage);
+  m_impl->brief           = unmarshalBriefInfo    (Doxygen::symbolStorage);
   m_impl->body            = unmarshalBodyInfo     (Doxygen::symbolStorage);
   m_impl->localName       = unmarshalQCString     (Doxygen::symbolStorage);
   m_impl->qualifiedName   = unmarshalQCString     (Doxygen::symbolStorage);
diff --git a/src/definition.h b/src/definition.h
index f13a8b8..d3723a1 100644
--- a/src/definition.h
+++ b/src/definition.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -37,12 +37,14 @@ struct SectionInfo;
 class Definition;
 class DefinitionImpl;
 
+#if 0
 struct ReachableDefinition
 {
   ReachableDefinition(Definition *d,int dist) : def(d), distance(dist) {}
   Definition *def;
   int distance;
 };
+#endif
 
 struct DocInfo
 {
@@ -51,6 +53,14 @@ struct DocInfo
     QCString file;
 };
 
+struct BriefInfo
+{
+    QCString doc;  
+    QCString tooltip;  
+    int      line;
+    QCString file;
+};
+
 struct BodyInfo
 {
     int      startLine;   // line number of the start of the definition
@@ -135,9 +145,14 @@ class Definition : public DefinitionIntf, public LockableObj
      */
     QCString docFile() const;
 
-    /*! Returns the brief description of this definition */
+    /*! Returns the brief description of this definition. This can include commands. */
     QCString briefDescription() const;
 
+    /*! Returns a plain text version of the brief description suitable for use
+     *  as a tool tip. 
+     */
+    QCString briefDescriptionAsTooltip() const;
+
     /*! Returns the line number at which the brief description was found. */
     int briefLine() const;
 
@@ -182,6 +197,7 @@ class Definition : public DefinitionIntf, public LockableObj
     /*! Returns TRUE iff the name may appear in the output */
     virtual bool isVisible() const;
 
+    /*! Returns TRUE iff this item is supposed to be hidden from the output. */
     bool isHidden() const;
 
     /*! If this definition was imported via a tag file, this function
@@ -293,6 +309,8 @@ class Definition : public DefinitionIntf, public LockableObj
     int  _getXRefListId(const char *listName) const;
     void _writeSourceRefList(OutputList &ol,const char *scopeName,
                        const QCString &text,MemberSDict *members,bool);
+    void _setBriefDescription(const char *b,const char *briefFile,int briefLine);
+    void _setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace);
     DefinitionImpl *m_impl; // internal structure holding all private data
     QCString m_name;
     bool m_isSymbol;
diff --git a/src/diagram.cpp b/src/diagram.cpp
index 15d2971..d169617 100644
--- a/src/diagram.cpp
+++ b/src/diagram.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/diagram.h b/src/diagram.h
index ad8caac..bf95ef7 100644
--- a/src/diagram.h
+++ b/src/diagram.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/dirdef.h b/src/dirdef.h
index 21aaa5f..d8d7cf1 100644
--- a/src/dirdef.h
+++ b/src/dirdef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/docparser.cpp b/src/docparser.cpp
index a2a7ef0..dc87b57 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -902,7 +902,8 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children)
           DocLinkedWord(parent,name,
             member->getReference(),
             member->getOutputFileBase(),
-            member->anchor()
+            member->anchor(),
+            member->briefDescriptionAsTooltip()
                        )
                      );
     }
@@ -920,7 +921,8 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children)
           DocLinkedWord(parent,name,
                         compound->getReference(),
                         compound->getOutputFileBase(),
-                        ""
+                        "",
+                        compound->briefDescriptionAsTooltip()
                        )
                      );
     }
@@ -932,7 +934,8 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children)
           DocLinkedWord(parent,g_token->name,
                          compound->getReference(),
                          compound->getSourceFileBase(),
-                         ""
+                         "",
+                         compound->briefDescriptionAsTooltip()
                        )
                      );
     }
@@ -957,7 +960,9 @@ static void handleLinkedWord(DocNode *parent,QList<DocNode> &children)
         DocLinkedWord(parent,name,
           cd->getReference(),
           cd->getOutputFileBase(),
-          ""));
+          "",
+          cd->briefDescriptionAsTooltip()
+          ));
   }
   else // normal non-linkable word
   {
@@ -1448,9 +1453,10 @@ DocWord::DocWord(DocNode *parent,const QString &word) :
 
 DocLinkedWord::DocLinkedWord(DocNode *parent,const QString &word,
                   const QString &ref,const QString &file,
-                  const QString &anchor) : 
+                  const QString &anchor,const QString &tooltip) : 
       m_parent(parent), m_word(word), m_ref(ref), 
-      m_file(file), m_relPath(g_relPath), m_anchor(anchor) 
+      m_file(file), m_relPath(g_relPath), m_anchor(anchor),
+      m_tooltip(tooltip)
 {
   //printf("new word %s url=%s\n",word.data(),g_searchUrl.data());
   if (!g_searchUrl.isEmpty())
@@ -2835,6 +2841,7 @@ int DocHtmlRow::parse()
     {
       warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: expected <td> or <th> tag but "
           "found <%s> instead!",g_token->name.data());
+      doctokenizerYYpushBackHtmlTag(g_token->name);
       goto endrow;
     }
   }
@@ -3161,6 +3168,7 @@ int DocHtmlDescList::parse()
     {
       warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: expected <dt> tag but "
           "found <%s> instead!",g_token->name.data());
+      doctokenizerYYpushBackHtmlTag(g_token->name);
       goto enddesclist;
     }
   }
@@ -3294,6 +3302,7 @@ int DocHtmlList::parse()
     {
       warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: expected <li> tag but "
           "found <%s> instead!",g_token->name.data());
+      doctokenizerYYpushBackHtmlTag(g_token->name);
       goto endlist;
     }
   }
@@ -3354,6 +3363,7 @@ int DocHtmlList::parseXml()
     {
       warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: expected <item> tag but "
           "found <%s> instead!",g_token->name.data());
+      doctokenizerYYpushBackHtmlTag(g_token->name);
       goto endlist;
     }
   }
diff --git a/src/docparser.h b/src/docparser.h
index 89c85fe..4ce3a11 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -206,7 +206,7 @@ class DocLinkedWord : public DocNode
   public:
     DocLinkedWord(DocNode *parent,const QString &word,
                   const QString &ref,const QString &file,
-                  const QString &anchor);
+                  const QString &anchor,const QString &tooltip);
     QString word() const       { return m_word; }
     Kind kind() const          { return Kind_LinkedWord; }
     DocNode *parent() const    { return m_parent; }
@@ -214,6 +214,7 @@ class DocLinkedWord : public DocNode
     QString relPath() const    { return m_relPath; }
     QString ref() const        { return m_ref; }
     QString anchor() const     { return m_anchor; }
+    QString tooltip() const    { return m_tooltip; }
     void accept(DocVisitor *v) { v->visit(this); }
 
   private:
@@ -223,6 +224,7 @@ class DocLinkedWord : public DocNode
     QString  m_file;
     QString  m_relPath;
     QString  m_anchor;
+    QString  m_tooltip;
 };
 
 /*! @brief Node representing an URL (or email address) */
diff --git a/src/doctokenizer.h b/src/doctokenizer.h
index f283fc7..3602b95 100644
--- a/src/doctokenizer.h
+++ b/src/doctokenizer.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -143,5 +143,6 @@ void doctokenizerYYsetStateInternalRef();
 void doctokenizerYYsetStateText();
 void doctokenizerYYsetStateSkipTitle();
 void doctokenizerYYsetInsidePre(bool b);
+void doctokenizerYYpushBackHtmlTag(const char *tag);
 
 #endif
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 374b4e4..b285322 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -1060,6 +1060,18 @@ void doctokenizerYYsetInsidePre(bool b)
   g_insidePre = b;
 }
 
+void doctokenizerYYpushBackHtmlTag(const char *tag)
+{
+  QCString tagName = tag;
+  int i,l = tagName.length();
+  unput('>');
+  for (i=l-1;i>=0;i--)
+  {
+    unput(tag[i]);
+  }
+  unput('<');
+}
+
 #if !defined(YY_FLEX_SUBMINOR_VERSION) 
 extern "C" { // some bogus code to keep the compiler happy
     void doctokenizerYYdummy() { yy_flex_realloc(0,0); }
diff --git a/src/docvisitor.h b/src/docvisitor.h
index 1bfd660..c0a5e4d 100644
--- a/src/docvisitor.h
+++ b/src/docvisitor.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -25,7 +25,8 @@ const int DocVisitor_Latex = 1;
 const int DocVisitor_XML   = 2;
 const int DocVisitor_RTF   = 3;
 const int DocVisitor_Man   = 4;
-const int DocVisitor_Other = 5;
+const int DocVisitor_Text  = 5;
+const int DocVisitor_Other = 6;
 
 // forward declarations
 class DocWord;
diff --git a/src/dot.cpp b/src/dot.cpp
index 37268ee..188b15f 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -34,6 +34,7 @@
 #include <qtextstream.h>
 #include <md5.h>
 
+#define MAP_CMD "cmap"
 
 //--------------------------------------------------------------------
 
@@ -84,6 +85,7 @@ static void writeGraphFooter(QTextStream &t)
   t << "}" << endl;
 }
 
+#if 0
 /*! converts the rectangles in a server site image map into a client 
  *  site image map.
  *  \param t the stream to which the result is written.
@@ -198,6 +200,105 @@ static bool convertMapFile(QTextStream &t,const char *mapName,
   
   return TRUE;
 }
+#endif
+
+/*! converts the rectangles in a client site image map into a stream
+ *  \param t the stream to which the result is written.
+ *  \param mapName the name of the map file.
+ *  \param relPath the relative path to the root of the output directory
+ *                 (used in case CREATE_SUBDIRS is enabled).
+ *  \param urlOnly if FALSE the url field in the map contains an external 
+ *                 references followed by a $ and then the URL.  
+ *  \returns TRUE if succesful.
+ */
+static bool convertMapFile(QTextStream &t,const char *mapName,
+                           const QCString relPath, bool urlOnly=FALSE)
+{
+  QFile f(mapName);
+  if (!f.open(IO_ReadOnly)) 
+  {
+    err("Error opening map file %s for inclusion in the docs!\n",mapName);
+    return FALSE;
+  }
+  const int maxLineLen=10240;
+  while (!f.atEnd()) // foreach line
+  {
+    QCString buf(maxLineLen);
+    int numBytes = f.readLine(buf.data(),maxLineLen);
+    buf[numBytes-1]='\0';
+
+    // search for href="...", store ... part in link
+    int indexS = buf.find("href=\""), indexE;
+    if (indexS!=-1 && (indexE=buf.find('"',indexS+6))!=-1)
+    {
+      QCString link = buf.mid(indexS+6,indexE-indexS-6);
+      QCString result;
+      QCString *dest;
+      if (urlOnly) // for user defined dot graphs
+      {
+        if (link.left(5)=="\\ref ") // \ref url
+        {
+          result="href=\"";
+          // fake ref node to resolve the url
+          DocRef *df = new DocRef( (DocNode*) 0, link.mid(5) );
+          if (!df->ref().isEmpty())
+          {
+            if ((dest=Doxygen::tagDestinationDict[df->ref()])) 
+              result += *dest + "/";
+          }
+          else if (!relPath.isEmpty())
+          {
+            result += relPath;
+          }
+          if (!df->file().isEmpty())  
+            result += df->file().data() + Doxygen::htmlFileExtension;
+          if (!df->anchor().isEmpty()) 
+            result += "#" + df->anchor();
+          delete df;
+          result += "\"";
+        }
+        else
+        {
+          result = "href=\"" + link + "\"";
+        }
+      }
+      else // ref$url (external ref via tag file), or $url (local ref)
+      {
+        int marker = link.find('$');
+        if (marker!=-1)
+        {
+          QCString ref = link.left(marker);
+          QCString url = link.mid(marker+1);
+          if (!ref.isEmpty())
+          {
+            result = "doxygen=\"" + ref + ":";
+            if ((dest=Doxygen::tagDestinationDict[ref])) result += *dest + "/";
+            result += "\" ";
+          }
+          result+= "href=\"";
+          if (!ref.isEmpty())
+          {
+            if ((dest=Doxygen::tagDestinationDict[ref])) result += *dest + "/";
+          }
+          else if (!relPath.isEmpty())
+          {
+            result += relPath;
+          }
+          result+= url + "\"";
+        }
+        else // should not happen, but handle properly anyway
+        {
+          result = "href=\"" + link + "\"";
+        }
+      }
+      QCString leftPart = buf.left(indexS);
+      QCString rightPart = buf.mid(indexE+1);
+      buf = leftPart + result + rightPart;
+    }
+    t << buf;
+  }
+  return TRUE;
+}
 
 static QArray<int> s_newNumber;
 static int s_max_newNumber=0;
@@ -241,6 +342,7 @@ static void resetReNumbering()
   s_newNumber.resize(s_max_newNumber);
 }
 
+#if 0
 static bool readBoundingBoxDot(const char *fileName,int *width,int *height)
 {
   QFile f(fileName);
@@ -263,6 +365,7 @@ static bool readBoundingBoxDot(const char *fileName,int *width,int *height)
   }
   return FALSE;
 }
+#endif
 
 static bool readBoundingBoxEPS(const char *fileName,int *width,int *height)
 {
@@ -360,6 +463,7 @@ static bool checkAndUpdateMd5Signature(const QCString &baseName,const QCString &
     // read checksum
     QCString md5stored(33);
     int bytesRead=f.readBlock(md5stored.data(),32);
+    md5stored[32]='\0';
     // compare checksum
     if (bytesRead==32 && md5==md5stored)
     {
@@ -405,17 +509,20 @@ void DotRunner::addJob(const char *format,const char *output)
 
 bool DotRunner::run()
 {
+  int exitCode=0;
+  static QCString dotExe = Config_getString("DOT_PATH")+"dot";
+  QCString dotArgs;
   QListIterator<QCString> li(m_jobs);
   QCString *s;
   if (Config_getBool("DOT_MULTI_TARGETS"))
   {
-    QCString dotArgs="\""+m_file+"\"";
+    dotArgs="\""+m_file+"\"";
     for (li.toFirst();(s=li.current());++li)
     {
       dotArgs+=' ';
       dotArgs+=*s;
     }
-    if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs,FALSE)!=0)
+    if ((exitCode=iSystem(dotExe,dotArgs,FALSE))!=0)
     {
       goto error;
     }
@@ -424,8 +531,8 @@ bool DotRunner::run()
   {
     for (li.toFirst();(s=li.current());++li)
     {
-      QCString dotArgs="\""+m_file+"\" "+*s;
-      if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs,FALSE)!=0)
+      dotArgs="\""+m_file+"\" "+*s;
+      if ((exitCode=iSystem(dotExe,dotArgs,FALSE))!=0)
       {
         goto error;
       }
@@ -433,7 +540,8 @@ bool DotRunner::run()
   }
   return TRUE;
 error:
-  err("Problems running dot. Check your installation!\n");
+  err("Problems running dot: exit code=%d, command='%s', arguments='%s'\n",
+      exitCode,dotExe.data(),dotArgs.data());
   return FALSE;
 }
 
@@ -452,18 +560,24 @@ static void deleteNodes(DotNode *node,SDict<DotNode> *skipNodes=0)
   deletedNodes.clear(); // actually remove the nodes.
 }
 
-DotNode::DotNode(int n,const char *lab,const char *url,int distance,
+DotNode::DotNode(int n,const char *lab,const char *tip, const char *url,
                  bool isRoot,ClassDef *cd)
-  : m_number(n), m_label(lab), m_url(url), m_isRoot(isRoot), m_classDef(cd)
+  : m_subgraphId(-1)
+  , m_number(n)
+  , m_label(lab)
+  , m_tooltip(tip)
+  , m_url(url)
+  , m_parents(0)
+  , m_children(0)
+  , m_edgeInfo(0)
+  , m_deleted(FALSE)
+  , m_written(FALSE)
+  , m_hasDoc(FALSE)
+  , m_isRoot(isRoot)
+  , m_classDef(cd)
+  , m_visible(FALSE)
+  , m_truncated(Unknown)
 {
-  m_children   = 0; 
-  m_edgeInfo   = 0;
-  m_parents    = 0;
-  m_subgraphId =-1;
-  m_deleted    = FALSE;
-  m_written    = FALSE;
-  m_hasDoc     = FALSE;
-  m_distance   = distance;
 }
 
 DotNode::~DotNode()
@@ -473,11 +587,6 @@ DotNode::~DotNode()
   delete m_edgeInfo;
 }
 
-void DotNode::setDistance(int distance)
-{
-  if (distance<m_distance) m_distance=distance;
-}
-
 void DotNode::addChild(DotNode *n,
                        int edgeColor,
                        int edgeStyle,
@@ -663,7 +772,7 @@ void DotNode::writeBox(QTextStream &t,
     }
     t << "}";
   }
-  else // old look
+  else // standard look
   {
     t << convertLabel(m_label);
   }
@@ -695,6 +804,10 @@ void DotNode::writeBox(QTextStream &t,
           << m_url.right(m_url.length()-anchorPos) << "\"";
       }
     }
+    if (!m_tooltip.isEmpty())
+    {
+      t << ",tooltip=\"" << m_tooltip << "\"";
+    }
   }
   t << "];" << endl; 
 }
@@ -741,27 +854,16 @@ void DotNode::write(QTextStream &t,
                     GraphOutputFormat format,
                     bool topDown,
                     bool toChildren,
-                    int distance,
                     bool backArrows,
                     bool reNumber
                    )
 {
   //printf("DotNode::write(%d) name=%s this=%p written=%d\n",distance,m_label.data(),this,m_written);
   if (m_written) return; // node already written to the output
-  if (m_distance>distance) return;
-  QList<DotNode> *nl = toChildren ? m_children : m_parents; 
-  bool hasNonReachableChildren=FALSE;
-  if (m_distance==distance && nl)
-  {
-    QListIterator<DotNode> dnli(*nl);
-    DotNode *cn;
-    for (dnli.toFirst();(cn=dnli.current());++dnli)
-    {
-      if (cn->m_distance>distance) hasNonReachableChildren=TRUE;
-    }
-  }
-  writeBox(t,gt,format,hasNonReachableChildren,reNumber);
+  if (!m_visible) return; // node is not visible
+  writeBox(t,gt,format,m_truncated==Truncated,reNumber);
   m_written=TRUE;
+  QList<DotNode> *nl = toChildren ? m_children : m_parents; 
   if (nl)
   {
     if (toChildren)
@@ -771,12 +873,12 @@ void DotNode::write(QTextStream &t,
       DotNode *cn;
       for (dnli1.toFirst();(cn=dnli1.current());++dnli1,++dnli2)
       {
-        if (cn->m_distance<=distance) 
+        if (cn->isVisible())
         {
           //printf("write arrow %s%s%s\n",label().data(),backArrows?"<-":"->",cn->label().data());
           writeArrow(t,gt,format,cn,dnli2.current(),topDown,backArrows,reNumber);
         }
-        cn->write(t,gt,format,topDown,toChildren,distance,backArrows,reNumber);
+        cn->write(t,gt,format,topDown,toChildren,backArrows,reNumber);
       }
     }
     else // render parents
@@ -785,7 +887,7 @@ void DotNode::write(QTextStream &t,
       DotNode *pn;
       for (dnli.toFirst();(pn=dnli.current());++dnli)
       {
-        if (pn->m_distance<=distance) 
+        if (pn->isVisible())
         {
           //printf("write arrow %s%s%s\n",label().data(),backArrows?"<-":"->",pn->label().data());
           writeArrow(t,
@@ -798,7 +900,7 @@ void DotNode::write(QTextStream &t,
               reNumber
               );
         }
-        pn->write(t,gt,format,TRUE,FALSE,distance,backArrows,reNumber);
+        pn->write(t,gt,format,TRUE,FALSE,backArrows,reNumber);
       }
     }
   }
@@ -978,6 +1080,7 @@ void DotNode::colorConnectedNodes(int curColor)
       if (cn->m_subgraphId==-1) // uncolored child node
       {
         cn->m_subgraphId=curColor;
+        cn->markAsVisible();
         cn->colorConnectedNodes(curColor);
         //printf("coloring node %s (%p): %d\n",cn->m_label.data(),cn,cn->m_subgraphId);
       }
@@ -993,6 +1096,7 @@ void DotNode::colorConnectedNodes(int curColor)
       if (pn->m_subgraphId==-1) // uncolored parent node
       {
         pn->m_subgraphId=curColor;
+        pn->markAsVisible();
         pn->colorConnectedNodes(curColor);
         //printf("coloring node %s (%p): %d\n",pn->m_label.data(),pn,pn->m_subgraphId);
       }
@@ -1074,8 +1178,10 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
     DotNode *node;
 
     // compute md5 checksum of the graph were are about to generate
-    QString buf;
-    QTextStream md5stream(&buf,IO_WriteOnly);
+    QString theGraph;
+    QTextStream md5stream(&theGraph,IO_WriteOnly);
+    writeGraphHeader(md5stream);
+    md5stream << "  rankdir=LR;" << endl;
     for (dnli2.toFirst();(node=dnli2.current());++dnli2)
     {
       if (node->m_subgraphId==n->m_subgraphId) 
@@ -1087,13 +1193,14 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
     {
       if (node->m_subgraphId==n->m_subgraphId) 
       {
-        node->write(md5stream,DotNode::Hierarchy,BITMAP,FALSE,TRUE,1000,TRUE,TRUE);
+        node->write(md5stream,DotNode::Hierarchy,BITMAP,FALSE,TRUE,TRUE,TRUE);
       }
     }
+    writeGraphFooter(md5stream);
     resetReNumbering();
     uchar md5_sig[16];
     QCString sigStr(33);
-    MD5Buffer((const unsigned char *)buf.ascii(),buf.length(),md5_sig);
+    MD5Buffer((const unsigned char *)theGraph.ascii(),theGraph.length(),md5_sig);
     MD5SigToString(md5_sig,sigStr.data(),33);
     if (checkAndUpdateMd5Signature(baseName,sigStr) || 
         !QFileInfo(mapName).exists())
@@ -1103,29 +1210,13 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
       QFile f(dotName);
       if (!f.open(IO_WriteOnly)) return;
       QTextStream t(&f);
-      writeGraphHeader(t);
-      t << "  rankdir=LR;" << endl;
-      for (dnli2.toFirst();(node=dnli2.current());++dnli2)
-      {
-        if (node->m_subgraphId==n->m_subgraphId) 
-        {
-          node->clearWriteFlag();
-        }
-      }
-      for (dnli2.toFirst();(node=dnli2.current());++dnli2)
-      {
-        if (node->m_subgraphId==n->m_subgraphId) 
-        {
-          node->write(t,DotNode::Hierarchy,BITMAP,FALSE,TRUE,1000,TRUE,TRUE);
-        }
-      }
-      writeGraphFooter(t);
+      t << theGraph;
       f.close();
       resetReNumbering();
 
       DotRunner dotRun(dotName);
       dotRun.addJob(imgExt,imgName);
-      dotRun.addJob("imap",mapName);
+      dotRun.addJob(MAP_CMD,mapName);
       if (!dotRun.run())
       {
         out << "</table>" << endl;
@@ -1190,8 +1281,10 @@ void DotGfxHierarchyTable::addHierarchy(DotNode *n,ClassDef *cd,bool hideSuper)
           {
             tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase();
           }
+          QCString tooltip = bClass->briefDescriptionAsTooltip();
           bn = new DotNode(m_curNodeNumber++,
               bClass->displayName(),
+              tooltip,
               tmp_url.data()
               );
           n->addChild(bn,bcd->prot);
@@ -1234,8 +1327,10 @@ void DotGfxHierarchyTable::addClassList(ClassSDict *cl)
         tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
       }
       //printf("Inserting root class %s\n",cd->name().data());
+      QCString tooltip = cd->briefDescriptionAsTooltip();
       DotNode *n = new DotNode(m_curNodeNumber++,
           cd->displayName(),
+          tooltip,
           tmp_url.data());
 
       //m_usedNodes->clear();
@@ -1281,6 +1376,7 @@ DotGfxHierarchyTable::DotGfxHierarchyTable()
         //printf("Starting at node %s (%p): %d\n",n->m_label.data(),n,curColor);
         done=FALSE; // still uncolored nodes
         n->m_subgraphId=curColor;
+        n->markAsVisible();
         n->colorConnectedNodes(curColor);
         curColor++;
         const DotNode *dn=n->findDocNode();
@@ -1325,7 +1421,7 @@ DotGfxHierarchyTable::~DotGfxHierarchyTable()
 int DotClassGraph::m_curNodeNumber = 0;
 
 void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
-    const char *label,int distance,const char *usedName,const char *templSpec,bool base)
+    const char *label,const char *usedName,const char *templSpec,bool base)
 {
   if (Config_getBool("HIDE_UNDOC_CLASSES") && !cd->isLinkable()) return;
 
@@ -1358,7 +1454,6 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
       bn->addChild(n,prot,edgeStyle,label);
       n->addParent(bn);
     }
-    bn->setDistance(distance);
     //printf(" add exiting node %s of %s\n",bn->m_label.data(),n->m_label.data());
   }
   else // new class
@@ -1370,14 +1465,14 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
     {
       tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
     }
+    QCString tooltip = cd->briefDescriptionAsTooltip();
     bn = new DotNode(m_curNodeNumber++,
         displayName,
+        tooltip,
         tmp_url.data(),
-        distance,
         FALSE,        // rootNode
         cd
        );
-    if (distance>m_maxDistance) m_maxDistance=distance;
     if (base)
     {
       n->addChild(bn,prot,edgeStyle,label);
@@ -1392,13 +1487,85 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
     //printf(" add new child node `%s' to %s hidden=%d url=%s\n",
     //    className.data(),n->m_label.data(),cd->isHidden(),tmp_url.data());
     
-    // we use <=, i.s.o < to cause one more level than intended which is used to 
-    // detect truncated nodes
-    if (distance<=m_recDepth) buildGraph(cd,bn,distance+1,base);
+    buildGraph(cd,bn,base);
+  }
+}
+
+void DotClassGraph::determineTruncatedNodes(QList<DotNode> &queue,bool includeParents)
+{
+  while (queue.count()>0)
+  {
+    DotNode *n = queue.take(0);
+    if (n->isVisible() && n->isTruncated()==DotNode::Unknown)
+    {
+      bool truncated = FALSE;
+      if (n->m_children)
+      {
+        QListIterator<DotNode> li(*n->m_children);
+        DotNode *dn;
+        for (li.toFirst();(dn=li.current());++li)
+        {
+          if (!dn->isVisible()) 
+            truncated = TRUE;
+          else 
+            queue.append(dn);
+        }
+      }
+      if (n->m_parents && includeParents)
+      {
+        QListIterator<DotNode> li(*n->m_parents);
+        DotNode *dn;
+        for (li.toFirst();(dn=li.current());++li)
+        {
+          if (!dn->isVisible()) 
+            truncated = TRUE;
+          else 
+            queue.append(dn);
+        }
+      }
+      n->markAsTruncated(truncated);
+    }
   }
 }
 
-void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
+void DotClassGraph::determineVisibleNodes(QList<DotNode> &queue,
+                                          int &maxNodes,bool includeParents)
+{
+  while (queue.count()>0 && maxNodes>0)
+  {
+    DotNode *n = queue.take(0);
+    //printf("*** Processing node %p queue=%d maxNodes=%d m_children=%p m_parents=%p\n",
+    //    n,queue.count(),maxNodes,n->m_children,n->m_parents);
+    if (!n->isVisible()) // not yet processed
+    {
+      //printf("    Marked as visible!\n");
+      n->markAsVisible();
+      maxNodes--;
+      // add direct children
+      if (n->m_children)
+      {
+        QListIterator<DotNode> li(*n->m_children);
+        DotNode *dn;
+        for (li.toFirst();(dn=li.current());++li)
+        {
+          queue.append(dn);
+        }
+      }
+      // add direct parents
+      if (n->m_parents && includeParents)
+      {
+        QListIterator<DotNode> li(*n->m_parents);
+        DotNode *dn;
+        for (li.toFirst();(dn=li.current());++li)
+        {
+          queue.append(dn);
+        }
+      }
+    }
+  }
+}
+
+void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,bool base)
 {
   //printf("DocClassGraph::buildGraph(%s,distance=%d,base=%d)\n",
   //    cd->name().data(),distance,base);
@@ -1415,7 +1582,7 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
       {
         //printf("-------- inheritance relation %s->%s templ=`%s'\n",
         //            cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());
-        addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName,
+        addClass(bcd->classDef,n,bcd->prot,0,bcd->usedName,
             bcd->templSpecifiers,base); 
       }
     }
@@ -1434,15 +1601,6 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
       UsesClassDef *ucd;
       for (;(ucd=ucdi.current());++ucdi)
       {
-        //if (base)
-        //{
-        //  printf("%s uses %s\n",cd->name().data(),ucd->classDef->name().data());
-        //}
-        //else
-        //{
-        //  printf("%s is used by %s\n",cd->name().data(),ucd->classDef->name().data());
-        //}
-        //printf("drawing\n");
         QCString label;
         QDictIterator<void> dvi(*ucd->accessors);
         const char *s;
@@ -1459,7 +1617,7 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
             label+=QCString("\n")+s;
           }
         }
-        addClass(ucd->classDef,n,EdgeInfo::Purple,label,distance,0,
+        addClass(ucd->classDef,n,EdgeInfo::Purple,label,0,
             ucd->templSpecifiers,base);
       }
     }
@@ -1480,7 +1638,7 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
         {
           if (templInstance==cd)
           {
-            addClass(templMaster,n,EdgeInfo::Orange,cli.currentKey(),distance,0,
+            addClass(templMaster,n,EdgeInfo::Orange,cli.currentKey(),0,
                 0,TRUE);
           }
         }
@@ -1495,7 +1653,7 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
         ClassDef *templInstance;
         for (;(templInstance=cli.current());++cli)
         {
-          addClass(templInstance,n,EdgeInfo::Orange,cli.currentKey(),distance,0,
+          addClass(templInstance,n,EdgeInfo::Orange,cli.currentKey(),0,
               0,FALSE);
         }
       }
@@ -1503,42 +1661,48 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
   }
 }
 
-DotClassGraph::DotClassGraph(ClassDef *cd,DotNode::GraphType t,int maxRecursionDepth)
+DotClassGraph::DotClassGraph(ClassDef *cd,DotNode::GraphType t)
 {
   //printf("--------------- DotClassGraph::DotClassGraph `%s'\n",cd->displayName().data());
   m_graphType = t;
-  m_maxDistance = 0;
-  m_recDepth = maxRecursionDepth;
   QCString tmp_url="";
   if (cd->isLinkable() && !cd->isHidden()) 
   {
     tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
   }
   QCString className = cd->displayName();
-  //if (cd->templateArguments())
-  //{
-  //  className+=tempArgListToString(cd->templateArguments());
-  //}
+  QCString tooltip = cd->briefDescriptionAsTooltip();
   m_startNode = new DotNode(m_curNodeNumber++,
                             className,
+                            tooltip,
                             tmp_url.data(),
-                            0,                         // distance
                             TRUE,                      // is a root node
                             cd
                            );
   m_usedNodes = new QDict<DotNode>(1009);
   m_usedNodes->insert(className,m_startNode);
 
-  //ClassSDict::Iterator cli(Doxygen::classSDict);
-  //ClassDef *icd;
-  //for (cli.toFirst();(icd=cli.current());++cli) icd->initTemplateMapping();
-
   //printf("Root node %s\n",cd->name().data());
-  if (m_recDepth>0) 
-  {
-    buildGraph(cd,m_startNode,1,TRUE);
-    if (t==DotNode::Inheritance) buildGraph(cd,m_startNode,1,FALSE);
-  }
+  //if (m_recDepth>0) 
+  //{
+    buildGraph(cd,m_startNode,TRUE);
+    if (t==DotNode::Inheritance) buildGraph(cd,m_startNode,FALSE);
+  //}
+
+  int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+  int directChildNodes = 1;
+  if (m_startNode->m_children!=0) 
+    directChildNodes+=m_startNode->m_children->count();
+  if (t==DotNode::Inheritance && m_startNode->m_parents!=0)
+    directChildNodes+=m_startNode->m_parents->count();
+  if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+  QList<DotNode> openNodeQueue;
+  openNodeQueue.append(m_startNode);
+  determineVisibleNodes(openNodeQueue,maxNodes,t==DotNode::Inheritance);
+  openNodeQueue.clear();
+  openNodeQueue.append(m_startNode);
+  determineTruncatedNodes(openNodeQueue,t==DotNode::Inheritance);
+
   m_diskName = cd->getFileBase().copy();
 }
 
@@ -1556,6 +1720,7 @@ DotClassGraph::~DotClassGraph()
   delete m_usedNodes;
 }
 
+#if 0
 void writeDotGraph(DotNode *root,
                    DotNode::GraphType gt,
                    GraphOutputFormat format,
@@ -1607,6 +1772,7 @@ void writeDotGraph(DotNode *root,
     f.close();
   }
 }
+#endif
 
 /*! Computes a 16 byte md5 checksum for a given dot graph.
  *  The md5 checksum is returned as a 32 character ASCII string.
@@ -1616,8 +1782,8 @@ QCString computeMd5Signature(DotNode *root,
                    GraphOutputFormat format,
                    bool lrRank,
                    bool renderParents,
-                   int distance,
-                   bool backArrows
+                   bool backArrows,
+                   QCString &graphStr
                   )
 {
   bool reNumber=TRUE;
@@ -1625,33 +1791,42 @@ QCString computeMd5Signature(DotNode *root,
   //printf("computeMd5Signature\n");
   QString buf;
   QTextStream md5stream(&buf,IO_WriteOnly);
+  writeGraphHeader(md5stream);
   if (lrRank)
   {
     md5stream << "rankdir=LR;" << endl;
   }
   root->clearWriteFlag();
-  root->write(md5stream,gt,format,gt!=DotNode::CallGraph,TRUE,distance,backArrows,reNumber);
+  root->write(md5stream,gt,format,gt!=DotNode::CallGraph,TRUE,backArrows,reNumber);
   if (renderParents && root->m_parents) 
   {
     QListIterator<DotNode>  dnli(*root->m_parents);
     DotNode *pn;
     for (dnli.toFirst();(pn=dnli.current());++dnli)
     {
-      if (pn->m_distance<=distance) 
+      if (pn->isVisible()) 
       {
-        root->writeArrow(md5stream,
-            gt,
-            format,
-            pn,
-            pn->m_edgeInfo->at(pn->m_children->findRef(root)),
-            FALSE,
-            backArrows,
-            reNumber
+        root->writeArrow(md5stream,                              // stream
+            gt,                                                  // graph type
+            format,                                              // output format
+            pn,                                                  // child node
+            pn->m_edgeInfo->at(pn->m_children->findRef(root)),   // edge info
+            FALSE,                                               // topDown?
+            backArrows,                                          // point back?
+            reNumber                                             // renumber nodes
             );
       }
-      pn->write(md5stream,gt,format,TRUE,FALSE,distance,backArrows,reNumber);
+      pn->write(md5stream,      // stream
+                gt,             // graph type
+                format,         // output format
+                TRUE,           // topDown?
+                FALSE,          // toChildren?
+                backArrows,     // backward pointing arrows?
+                reNumber        // renumber nodes?
+               );
     }
   }
+  writeGraphFooter(md5stream);
   uchar md5_sig[16];
   QCString sigStr(33);
   MD5Buffer((const unsigned char *)buf.ascii(),buf.length(),md5_sig);
@@ -1660,10 +1835,40 @@ QCString computeMd5Signature(DotNode *root,
   {
     resetReNumbering();
   }
+  graphStr=buf.ascii();
   //printf("md5: %s | file: %s\n",sigStr,baseName.data());
   return sigStr;
 }
 
+static bool updateDotGraph(DotNode *root,
+                           DotNode::GraphType gt,
+                           //QDir &thisDir,
+                           const QCString &baseName,
+                           GraphOutputFormat format,
+                           bool lrRank,
+                           bool renderParents,
+                           bool backArrows
+                          )
+{
+  QCString theGraph;
+  // TODO: write graph to theGraph, then compute md5 checksum
+  QCString md5 = computeMd5Signature(
+                   root,gt,format,lrRank,renderParents,backArrows,theGraph);
+  if (checkAndUpdateMd5Signature(baseName,md5)) // graph needs to be regenerated
+  {
+    QFile f;
+    f.setName(baseName+".dot");
+    if (f.open(IO_WriteOnly))
+    {
+      QTextStream t(&f);
+      t << theGraph;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+#if 0
 static bool findMaximalDotGraph(DotNode *root,
                                 int maxDist,
                                 const QCString &baseName,
@@ -1750,6 +1955,7 @@ static bool findMaximalDotGraph(DotNode *root,
   }
   return TRUE;
 }
+#endif
 
 QCString DotClassGraph::diskName() const
 {
@@ -1810,28 +2016,17 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
   baseName = convertNameToFile(diskName());
 
   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
-  QCString md5 = computeMd5Signature(m_startNode,        // root
-                                     m_graphType,        // gt
-                                     format,             // format
-                                     !isTBRank,          // lrRank
-                                     m_graphType==DotNode::Inheritance, // renderParent
-                                     QMIN(m_recDepth,m_maxDistance),    // maxDist
-                                     TRUE                               // backArrows
-                                    );
-  if (checkAndUpdateMd5Signature(baseName,md5) ||
-      !QFileInfo(baseName+".map").exists()
-     )
+
+  if (updateDotGraph(m_startNode,
+                 m_graphType,
+                 baseName,
+                 format,
+                 !isTBRank,
+                 m_graphType==DotNode::Inheritance,
+                 TRUE
+                )
+      )
   {
-    findMaximalDotGraph(m_startNode,                       // root
-                        QMIN(m_recDepth,m_maxDistance),    // maxDist
-                        baseName,                          // baseName
-                        thisDir,                           // thisDir
-                        m_graphType,                       // gt
-                        format,                            // format
-                        !isTBRank,                         // lrRank
-                        m_graphType==DotNode::Inheritance, // renderParents
-                        TRUE                               // backArrows
-                       );
     if (format==BITMAP) // run dot to create a bitmap image
     {
       QCString dotArgs(maxCmdLine);
@@ -1839,7 +2034,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
 
       DotRunner dotRun(baseName+".dot");
       dotRun.addJob(imgExt,imgName);
-      if (generateImageMap) dotRun.addJob("imap",baseName+".map");
+      if (generateImageMap) dotRun.addJob(MAP_CMD,baseName+".map");
       if (!dotRun.run())
       {
         QDir::setCurrent(oldDir);
@@ -1875,7 +2070,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
     if (Config_getBool("DOT_CLEANUP")) thisDir.remove(baseName+".dot");
   }
 
-  if (format==BITMAP && generateImageMap) // run dot to create a image map
+  if (format==BITMAP && generateImageMap) // produce HTML to include the image
   {
     QCString mapLabel = convertNameToFile(m_startNode->m_label+"_"+mapName);
     out << "<p><center><img src=\"" << relPath << baseName << "." 
@@ -1905,7 +2100,7 @@ QCString DotClassGraph::writeGraph(QTextStream &out,
     }
     //thisDir.remove(baseName+".map");
   }
-  else if (format==EPS) // run dot to create a .eps image
+  else if (format==EPS) // produce tex to include the .eps image
   {
       int width,height;
       if (!readBoundingBoxEPS(baseName+".eps",&width,&height))
@@ -1954,7 +2149,7 @@ void DotClassGraph::writeDEF(QTextStream &t)
 
 int DotInclDepGraph::m_curNodeNumber = 0;
 
-void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance)
+void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd)
 {
   QList<IncludeInfo> *includeFiles = 
      m_inverse ? fd->includedByFileList() : fd->includeFileList();
@@ -1987,49 +2182,107 @@ void DotInclDepGraph::buildGraph(DotNode *n,FileDef *fd,int distance)
         {
           n->addChild(bn,0,0,0);
           bn->addParent(n);
-          bn->setDistance(distance);
         }
         else
         {
           QCString tmp_url;
           if (bfd) tmp_url=doc || src ? bfd->getReference()+"$"+url : QCString();
+          QCString tooltip = fd->briefDescriptionAsTooltip();
           bn = new DotNode(
               m_curNodeNumber++,
               ii->includeName,
+              tooltip,
               tmp_url,
-              distance
+              0 //distance
               );
-          if (distance>m_maxDistance) m_maxDistance=distance;
           n->addChild(bn,0,0,0);
           bn->addParent(n);
           m_usedNodes->insert(in,bn);
 
-          // we use <=, i.s.o < to cause one more level than intended which is used to 
-          // detect truncated nodes
-          if (bfd && distance<=m_recDepth) buildGraph(bn,bfd,distance+1);
+          if (bfd) buildGraph(bn,bfd);
+        }
+      }
+    }
+  }
+}
+
+void DotInclDepGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes)
+{
+  while (queue.count()>0 && maxNodes>0)
+  {
+    DotNode *n = queue.take(0);
+    if (!n->isVisible()) // not yet processed
+    {
+      n->markAsVisible();
+      maxNodes--;
+      // add direct children
+      if (n->m_children)
+      {
+        QListIterator<DotNode> li(*n->m_children);
+        DotNode *dn;
+        for (li.toFirst();(dn=li.current());++li)
+        {
+          queue.append(dn);
+        }
+      }
+    }
+  }
+}
+
+void DotInclDepGraph::determineTruncatedNodes(QList<DotNode> &queue)
+{
+  while (queue.count()>0)
+  {
+    DotNode *n = queue.take(0);
+    if (n->isVisible() && n->isTruncated()==DotNode::Unknown)
+    {
+      bool truncated = FALSE;
+      if (n->m_children)
+      {
+        QListIterator<DotNode> li(*n->m_children);
+        DotNode *dn;
+        for (li.toFirst();(dn=li.current());++li)
+        {
+          if (!dn->isVisible()) 
+            truncated = TRUE;
+          else 
+            queue.append(dn);
         }
       }
+      n->markAsTruncated(truncated);
     }
   }
 }
 
-DotInclDepGraph::DotInclDepGraph(FileDef *fd,int maxRecursionDepth,bool inverse)
+
+DotInclDepGraph::DotInclDepGraph(FileDef *fd,bool inverse)
 {
   m_maxDistance = 0;
-  m_recDepth = maxRecursionDepth;
   m_inverse = inverse;
   ASSERT(fd!=0);
   m_diskName  = fd->getFileBase().copy();
   QCString tmp_url=fd->getReference()+"$"+fd->getFileBase();
   m_startNode = new DotNode(m_curNodeNumber++,
                             fd->docName(),
+                            "",
                             tmp_url.data(),
-                            0,       // distance
                             TRUE     // root node
                            );
   m_usedNodes = new QDict<DotNode>(1009);
   m_usedNodes->insert(fd->absFilePath(),m_startNode);
-  buildGraph(m_startNode,fd,1);
+  buildGraph(m_startNode,fd);
+
+  int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+  int directChildNodes = 1;
+  if (m_startNode->m_children!=0) 
+    directChildNodes+=m_startNode->m_children->count();
+  if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+  QList<DotNode> openNodeQueue;
+  openNodeQueue.append(m_startNode);
+  determineVisibleNodes(openNodeQueue,maxNodes);
+  openNodeQueue.clear();
+  openNodeQueue.append(m_startNode);
+  determineTruncatedNodes(openNodeQueue);
 }
 
 DotInclDepGraph::~DotInclDepGraph()
@@ -2072,28 +2325,16 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
   if (m_inverse) mapName+="dep";
   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
 
-  QCString md5 = computeMd5Signature(m_startNode,         // root
-                                     DotNode::CallGraph,  // gt
-                                     format,              // format
-                                     TRUE,                // lrRank
-                                     FALSE,               // renderParents
-                                     QMIN(m_recDepth,m_maxDistance), // maxDist
-                                     FALSE                // backArrows
-                                    );
-  if (checkAndUpdateMd5Signature(baseName,md5) ||
-      !QFileInfo(baseName+".map").exists()
-     )
+  if (updateDotGraph(m_startNode,
+                 DotNode::CallGraph,
+                 baseName,
+                 format,
+                 TRUE,         // lrRank
+                 FALSE,        // renderParents
+                 m_inverse     // backArrows
+                )
+      )
   {
-    findMaximalDotGraph(m_startNode,                      // root
-                        QMIN(m_recDepth,m_maxDistance),   // maxDist
-                        baseName,                         // baseName
-                        thisDir,                          // thisDir
-                        DotNode::CallGraph,               // gt
-                        format,                           // format
-                        TRUE,                             // lrRank
-                        FALSE,                            // renderParents
-                        m_inverse                         // backArrows
-                       );
     if (format==BITMAP)
     {
       // run dot to create a bitmap image
@@ -2101,7 +2342,7 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out,
       QCString imgName=baseName+"."+imgExt;
       DotRunner dotRun(baseName+".dot");
       dotRun.addJob(imgExt,imgName);
-      if (generateImageMap) dotRun.addJob("imap",baseName+".map");
+      if (generateImageMap) dotRun.addJob(MAP_CMD,baseName+".map");
       if (!dotRun.run())
       {
         QDir::setCurrent(oldDir);
@@ -2197,10 +2438,110 @@ void DotInclDepGraph::writeXML(QTextStream &t)
 
 int DotCallGraph::m_curNodeNumber = 0;
 
-DotCallGraph::DotCallGraph(MemberDef *md,int maxRecursionDepth,bool inverse)
+void DotCallGraph::buildGraph(DotNode *n,MemberDef *md)
+{
+  LockingPtr<MemberSDict> refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers();
+  if (!refs.isNull())
+  {
+    MemberSDict::Iterator mri(*refs);
+    MemberDef *rmd;
+    for (;(rmd=mri.current());++mri)
+    {
+      if (rmd->isFunction())
+      {
+        QCString uniqueId;
+        uniqueId=rmd->getReference()+"$"+
+                 rmd->getOutputFileBase()+"#"+rmd->anchor();
+        DotNode *bn  = m_usedNodes->find(uniqueId);
+        if (bn) // file is already a node in the graph
+        {
+          n->addChild(bn,0,0,0);
+          bn->addParent(n);
+        }
+        else
+        {
+          QCString name;
+          if (Config_getBool("HIDE_SCOPE_NAMES"))
+          {
+            name  = rmd->getOuterScope()==m_scope ? 
+                    rmd->name() : rmd->qualifiedName();
+          }
+          else
+          {
+            name = rmd->qualifiedName();
+          }
+          QCString tooltip = rmd->briefDescriptionAsTooltip();
+          bn = new DotNode(
+              m_curNodeNumber++,
+              linkToText(name,FALSE),
+              tooltip,
+              uniqueId,
+              0 //distance
+              );
+          n->addChild(bn,0,0,0);
+          bn->addParent(n);
+          m_usedNodes->insert(uniqueId,bn);
+
+          buildGraph(bn,rmd);
+        }
+      }
+    }
+  }
+}
+
+void DotCallGraph::determineVisibleNodes(QList<DotNode> &queue, int &maxNodes)
+{
+  while (queue.count()>0 && maxNodes>0)
+  {
+    DotNode *n = queue.take(0);
+    if (!n->isVisible()) // not yet processed
+    {
+      n->markAsVisible();
+      maxNodes--;
+      // add direct children
+      if (n->m_children)
+      {
+        QListIterator<DotNode> li(*n->m_children);
+        DotNode *dn;
+        for (li.toFirst();(dn=li.current());++li)
+        {
+          queue.append(dn);
+        }
+      }
+    }
+  }
+}
+
+void DotCallGraph::determineTruncatedNodes(QList<DotNode> &queue)
+{
+  while (queue.count()>0)
+  {
+    DotNode *n = queue.take(0);
+    if (n->isVisible() && n->isTruncated()==DotNode::Unknown)
+    {
+      bool truncated = FALSE;
+      if (n->m_children)
+      {
+        QListIterator<DotNode> li(*n->m_children);
+        DotNode *dn;
+        for (li.toFirst();(dn=li.current());++li)
+        {
+          if (!dn->isVisible()) 
+            truncated = TRUE;
+          else 
+            queue.append(dn);
+        }
+      }
+      n->markAsTruncated(truncated);
+    }
+  }
+}
+
+
+
+DotCallGraph::DotCallGraph(MemberDef *md,bool inverse)
 {
   m_maxDistance = 0;
-  m_recDepth = maxRecursionDepth;
   m_inverse = inverse;
   m_diskName = md->getOutputFileBase()+"_"+md->anchor();
   m_scope    = md->getOuterScope();
@@ -2218,13 +2559,25 @@ DotCallGraph::DotCallGraph(MemberDef *md,int maxRecursionDepth,bool inverse)
   }
   m_startNode = new DotNode(m_curNodeNumber++,
                             linkToText(name,FALSE),
+                            "",
                             uniqueId.data(),
-                            0,       // distance
                             TRUE     // root node
                            );
   m_usedNodes = new QDict<DotNode>(1009);
   m_usedNodes->insert(uniqueId,m_startNode);
-  buildGraph(m_startNode,md,1);
+  buildGraph(m_startNode,md);
+
+  int maxNodes = Config_getInt("DOT_GRAPH_MAX_NODES");
+  int directChildNodes = 1;
+  if (m_startNode->m_children!=0) 
+    directChildNodes+=m_startNode->m_children->count();
+  if (directChildNodes>maxNodes) maxNodes=directChildNodes;
+  QList<DotNode> openNodeQueue;
+  openNodeQueue.append(m_startNode);
+  determineVisibleNodes(openNodeQueue,maxNodes);
+  openNodeQueue.clear();
+  openNodeQueue.append(m_startNode);
+  determineTruncatedNodes(openNodeQueue);
 }
 
 DotCallGraph::~DotCallGraph()
@@ -2251,28 +2604,16 @@ QCString DotCallGraph::writeGraph(QTextStream &out, GraphOutputFormat format,
   QCString mapName=baseName;
   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
 
-  QCString md5 = computeMd5Signature(m_startNode,         // root
-                                     DotNode::CallGraph,  // gt
-                                     format,              // format
-                                     TRUE,                // lrRank
-                                     FALSE,               // renderParents
-                                     QMIN(m_recDepth,m_maxDistance), // maxDist
-                                     FALSE                // backArrows
-                                    );
-  if (checkAndUpdateMd5Signature(baseName,md5) ||
-      !QFileInfo(baseName+".map").exists()
-     )
+  if (updateDotGraph(m_startNode,
+                 DotNode::CallGraph,
+                 baseName,
+                 format,
+                 TRUE,         // lrRank
+                 FALSE,        // renderParents
+                 m_inverse     // backArrows
+                )
+      )
   {
-    findMaximalDotGraph(m_startNode,                      // root
-                        QMIN(m_recDepth,m_maxDistance),   // maxDist
-                        baseName,                         // baseName
-                        thisDir,                          // thisDir
-                        DotNode::CallGraph,               // gt
-                        format,                           // format
-                        TRUE,                             // lrRank
-                        FALSE,                            // renderParents
-                        m_inverse                         // backArrows
-                       );
     if (format==BITMAP)
     {
       // run dot to create a bitmap image
@@ -2280,7 +2621,7 @@ QCString DotCallGraph::writeGraph(QTextStream &out, GraphOutputFormat format,
       QCString imgName=baseName+"."+imgExt;
       DotRunner dotRun(baseName+".dot");
       dotRun.addJob(imgExt,imgName);
-      if (generateImageMap) dotRun.addJob("imap",baseName+".map");
+      if (generateImageMap) dotRun.addJob(MAP_CMD,baseName+".map");
       if (!dotRun.run())
       {
         QDir::setCurrent(oldDir);
@@ -2357,59 +2698,6 @@ QCString DotCallGraph::writeGraph(QTextStream &out, GraphOutputFormat format,
   return baseName;
 }
 
-void DotCallGraph::buildGraph(DotNode *n,MemberDef *md,int distance)
-{
-  LockingPtr<MemberSDict> refs = m_inverse ? md->getReferencedByMembers() : md->getReferencesMembers();
-  if (!refs.isNull())
-  {
-    MemberSDict::Iterator mri(*refs);
-    MemberDef *rmd;
-    for (;(rmd=mri.current());++mri)
-    {
-      if (rmd->isFunction())
-      {
-        QCString uniqueId;
-        uniqueId=rmd->getReference()+"$"+
-                 rmd->getOutputFileBase()+"#"+rmd->anchor();
-        DotNode *bn  = m_usedNodes->find(uniqueId);
-        if (bn) // file is already a node in the graph
-        {
-          n->addChild(bn,0,0,0);
-          bn->addParent(n);
-          bn->setDistance(distance);
-        }
-        else
-        {
-          QCString name;
-          if (Config_getBool("HIDE_SCOPE_NAMES"))
-          {
-            name  = rmd->getOuterScope()==m_scope ? 
-                    rmd->name() : rmd->qualifiedName();
-          }
-          else
-          {
-            name = rmd->qualifiedName();
-          }
-          bn = new DotNode(
-              m_curNodeNumber++,
-              linkToText(name,FALSE),
-              uniqueId,
-              distance
-              );
-          if (distance>m_maxDistance) m_maxDistance=distance;
-          n->addChild(bn,0,0,0);
-          bn->addParent(n);
-          m_usedNodes->insert(uniqueId,bn);
-
-          // we use <=, i.s.o < to cause one more level than intended which is used to 
-          // detect truncated nodes
-          if (distance<=m_recDepth) buildGraph(bn,rmd,distance+1);
-        }
-      }
-    }
-  }
-}
-
 bool DotCallGraph::isTrivial() const
 {
   return m_startNode->m_children==0;
@@ -2464,7 +2752,7 @@ QCString DotDirDeps::writeGraph(QTextStream &out,
       QCString imgName=baseName+"."+imgExt;
       DotRunner dotRun(baseName+".dot");
       dotRun.addJob(imgExt,imgName);
-      if (generateImageMap) dotRun.addJob("imap",baseName+".map");
+      if (generateImageMap) dotRun.addJob(MAP_CMD,baseName+".map");
       if (!dotRun.run())
       {
         QDir::setCurrent(oldDir);
@@ -2609,6 +2897,12 @@ void generateGraphLegend(const char *path)
   QDir::setCurrent(oldDir);
 }
   
+#undef PUTENV
+#if defined(_WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ < 0x0550))
+#define PUTENV _putenv
+#else 
+#define PUTENV putenv
+#endif
 
 void writeDotGraphFromFile(const char *inFile,const char *outDir,
                            const char *outFile,GraphOutputFormat format)
@@ -2627,15 +2921,19 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir,
   QDir::setCurrent(outDir);
   //printf("Going to dir %s\n",QDir::currentDirPath().data());
 
-  //{ // copy input file to output dir.
-  //  QFile inf(inFile,IO_ReadOnly);
-  //  QFileInfo infinfo(inf);
-  //  uint s = infinfo.size();
-  //  QByteArray a(s);
-  //  inf.readBlock(a.data(),s);
-  //  QFile outf(outDir,IO_WriteOnly);
-  //  outf.writeBlock(a.data(),s);
-  //}
+  QCString env = getenv("DOTFONTPATH");
+  if (env==".") // this path was set by doxygen, so dot can find the FreeSans.ttf font, 
+                // for user defined graphs we use the default search path built into dot, 
+                // unless the user has set the DOTFONTPATH as well. 
+  {
+    // temporarily remove the DOTFONTPATH environment variable
+    // so dot will use the built-in search path.
+#ifdef _WIN32
+    SetEnvironmentVariable("DOTFONTPATH", 0)
+#else
+    unsetenv("DOTFONTPATH");
+#endif
+  }
   
   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
   QCString imgName = (QCString)outFile+"."+imgExt;
@@ -2648,7 +2946,7 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir,
   if (!dotRun.run())
   {
     QDir::setCurrent(oldDir);
-    return;
+    goto error;
   }
   // Added by Nils Strom
   if ( (format==EPS) && (Config_getBool("USE_PDFLATEX")) )
@@ -2664,6 +2962,17 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir,
 
   if (format==BITMAP) checkDotResult(imgName);
 
+  if (env==".")
+  {
+    // restore the DOTFONTPATH variable again
+#ifdef _WIN32
+    SetEnvironmentVariable("DOTFONTPATH", env)
+#else
+    setenv("DOTFONTPATH",env,1);
+#endif
+  }
+
+error:
   QDir::setCurrent(oldDir);
 }
 
@@ -2687,7 +2996,7 @@ QString getDotImageMapFromFile(const QString& inFile, const QString& outDir,
   //printf("Going to dir %s\n",QDir::currentDirPath().data());
 
   DotRunner dotRun(inFile);
-  dotRun.addJob("imap",outFile);
+  dotRun.addJob(MAP_CMD,outFile);
   if (!dotRun.run())
   {
     QDir::setCurrent(oldDir);
@@ -2712,13 +3021,14 @@ DotGroupCollaboration::DotGroupCollaboration(GroupDef* gd)
     m_curNodeId = 0;
     QCString tmp_url = gd->getReference()+"$"+gd->getOutputFileBase();
     m_usedNodes = new QDict<DotNode>(1009);
-    m_rootNode = new DotNode(m_curNodeId++, gd->groupTitle(), tmp_url, 0, TRUE );
+    m_rootNode = new DotNode(m_curNodeId++, gd->groupTitle(), "", tmp_url, TRUE );
+    m_rootNode->markAsVisible();
     m_usedNodes->insert(gd->name(), m_rootNode );
     m_edges.setAutoDelete(TRUE);
 
     m_diskName = gd->getOutputFileBase();
 
-    buildGraph( gd, 0 );
+    buildGraph( gd );
 }
 
 DotGroupCollaboration::~DotGroupCollaboration()
@@ -2726,7 +3036,7 @@ DotGroupCollaboration::~DotGroupCollaboration()
   delete m_usedNodes;
 }
 
-void DotGroupCollaboration::buildGraph(GroupDef* gd,int)
+void DotGroupCollaboration::buildGraph(GroupDef* gd)
 {
   QCString tmp_url;
   //===========================
@@ -2744,7 +3054,9 @@ void DotGroupCollaboration::buildGraph(GroupDef* gd,int)
       if ( !nnode )
       { // add node
         tmp_url = d->getReference()+"$"+d->getOutputFileBase();
-        nnode = new DotNode(m_curNodeId++, d->groupTitle(), tmp_url );
+        QCString tooltip = d->briefDescriptionAsTooltip();
+        nnode = new DotNode(m_curNodeId++, d->groupTitle(), tooltip, tmp_url );
+        nnode->markAsVisible();
         m_usedNodes->insert(d->name(), nnode );
       }
       tmp_url = "";
@@ -2763,7 +3075,9 @@ void DotGroupCollaboration::buildGraph(GroupDef* gd,int)
       if ( !nnode )
       { // add node
         tmp_url = def->getReference()+"$"+def->getOutputFileBase();
-        nnode = new DotNode(m_curNodeId++, def->groupTitle(), tmp_url );
+        QCString tooltip = def->briefDescriptionAsTooltip();
+        nnode = new DotNode(m_curNodeId++, def->groupTitle(), tooltip, tmp_url );
+        nnode->markAsVisible();
         m_usedNodes->insert(def->name(), nnode );
       }
       tmp_url = "";
@@ -2899,7 +3213,9 @@ void DotGroupCollaboration::addCollaborationMember(
       if ( nnode==0 )
       { // add node
         tmp_str = d->getReference()+"$"+d->getOutputFileBase();
-        nnode = new DotNode(m_curNodeId++, d->groupTitle(), tmp_str );
+        QCString tooltip = d->briefDescriptionAsTooltip();
+        nnode = new DotNode(m_curNodeId++, d->groupTitle(), tooltip, tmp_str );
+        nnode->markAsVisible();
         m_usedNodes->insert(d->name(), nnode );
       }
       tmp_str = def->qualifiedName();
@@ -2941,7 +3257,7 @@ QCString DotGroupCollaboration::writeGraph( QTextStream &t, GraphOutputFormat fo
     // write other nodes.
     for (dni.toFirst();(pn=dni.current());++dni)
     {
-      pn->write(tdot,DotNode::Inheritance,format,TRUE,FALSE,1,FALSE,FALSE);
+      pn->write(tdot,DotNode::Inheritance,format,TRUE,FALSE,FALSE,FALSE);
     }
 
     // write edges
@@ -2965,7 +3281,7 @@ QCString DotGroupCollaboration::writeGraph( QTextStream &t, GraphOutputFormat fo
 
     DotRunner dotRun(baseName+".dot");
     dotRun.addJob(imgExt,imgName);
-    if (writeImageMap) dotRun.addJob("imap",mapName);
+    if (writeImageMap) dotRun.addJob(MAP_CMD,mapName);
     if (!dotRun.run())
     {
       QDir::setCurrent(oldDir);
diff --git a/src/dot.h b/src/dot.h
index ec002b2..5ca8724 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -37,6 +37,7 @@ class DotGroupCollaboration;
 
 enum GraphOutputFormat { BITMAP , EPS };
 
+/** @brief Attributes of an edge of a dot graph */
 struct EdgeInfo
 {
   enum Colors { Blue=0, Green=1, Red=2, Purple=3, Grey=4, Orange=5 };
@@ -50,11 +51,14 @@ struct EdgeInfo
   int m_labColor;
 };
 
+/** @brief A node in a dot graph */
 class DotNode
 {
   public:
     enum GraphType { Dependency, Inheritance, Collaboration, Hierarchy, CallGraph };
-    DotNode(int n,const char *lab,const char *url,int distance = 0,bool rootNode=FALSE,ClassDef *cd=0);
+    enum TruncState { Unknown, Truncated, Untruncated };
+    DotNode(int n,const char *lab,const char *tip,const char *url,
+            bool rootNode=FALSE,ClassDef *cd=0);
    ~DotNode();
     void addChild(DotNode *n,
                   int edgeColor=EdgeInfo::Purple,
@@ -63,20 +67,21 @@ class DotNode
                   const char *edgeURL=0,
                   int edgeLabCol=-1
                  );
-    void setDistance(int distance);
     void addParent(DotNode *n);
     void deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes=0);
     void removeChild(DotNode *n);
     void removeParent(DotNode *n);
     int findParent( DotNode *n );
     void write(QTextStream &t,GraphType gt,GraphOutputFormat f,
-               bool topDown,bool toChildren,int maxDistance,bool backArrows,bool reNumber);
+               bool topDown,bool toChildren,bool backArrows,bool reNumber);
     int  m_subgraphId;
     void clearWriteFlag();
     void writeXML(QTextStream &t,bool isClassGraph);
     void writeDEF(QTextStream &t);
     QCString label() const { return m_label; }
     int  number() const { return m_number; }
+    bool isVisible() const { return m_visible; }
+    TruncState isTruncated() const { return m_truncated; }
 
   private:
     void colorConnectedNodes(int curColor);
@@ -85,8 +90,11 @@ class DotNode
     void writeArrow(QTextStream &t,GraphType gt,GraphOutputFormat f,DotNode *cn,
                     EdgeInfo *ei,bool topDown, bool pointBack=TRUE, bool reNumber=FALSE);
     const DotNode   *findDocNode() const; // only works for acyclic graphs!
+    void markAsVisible(bool b=TRUE) { m_visible=b; }
+    void markAsTruncated(bool b=TRUE) { m_truncated=b ? Truncated : Untruncated; }
     int              m_number;
     QCString         m_label;     //!< label text
+    QCString         m_tooltip;   //!< node's tooltip
     QCString         m_url;       //!< url of the node (format: remote$local)
     QList<DotNode>  *m_parents;   //!< list of parent nodes (incoming arrows)
     QList<DotNode>  *m_children;  //!< list of child nodes (outgoing arrows)
@@ -94,9 +102,10 @@ class DotNode
     bool             m_deleted;   //!< used to mark a node as deleted
     bool             m_written;   //!< used to mark a node as written
     bool             m_hasDoc;    //!< used to mark a node as documented
-    int              m_distance;  //!< distance to the root node
     bool             m_isRoot;    //!< indicates if this is a root node
     ClassDef *       m_classDef;  //!< class representing this node (can be 0)
+    bool             m_visible;   //!< is the node visible in the output
+    TruncState       m_truncated; //!< does the node have non-visible children/parents
 
     friend class DotGfxHierarchyTable;
     friend class DotClassGraph;
@@ -105,27 +114,23 @@ class DotNode
     friend class DotCallGraph;
     friend class DotGroupCollaboration;
 
-    friend void writeDotGraph(
-                      DotNode *root, GraphType gt,
-                      GraphOutputFormat f, const QCString &baseName,
-                      bool lrRank, bool renderParents,
-                      int distance, bool backArrows, bool reNumber
-                     );
     friend QCString computeMd5Signature(
                       DotNode *root, GraphType gt,
                       GraphOutputFormat f, 
                       bool lrRank, bool renderParents,
-                      int distance, bool backArrows
+                      bool backArrows,
+                      QCString &graphStr
                      );
 };
-inline
-int DotNode::findParent( DotNode *n )
+
+inline int DotNode::findParent( DotNode *n )
 {
     if( !m_parents )
         return -1;
     return m_parents->find(n);
 }
 
+/** @brief Represents a graphical class hierarchy */
 class DotGfxHierarchyTable
 {
   public:
@@ -143,11 +148,11 @@ class DotGfxHierarchyTable
     DotNodeList    *m_rootSubgraphs;
 };
 
+/** @brief Representation of a class inheritance or dependency graph */
 class DotClassGraph
 {
   public:
-    //enum GraphType { Interface, Implementation, Inheritance };
-    DotClassGraph(ClassDef *cd,DotNode::GraphType t,int maxRecusionDepth);
+    DotClassGraph(ClassDef *cd,DotNode::GraphType t);
    ~DotClassGraph();
     bool isTrivial() const;
     QCString writeGraph(QTextStream &t,GraphOutputFormat f,const char *path,
@@ -158,23 +163,25 @@ class DotClassGraph
     QCString diskName() const;
 
   private:
-    void buildGraph(ClassDef *cd,DotNode *n,int level,bool base);
+    void buildGraph(ClassDef *cd,DotNode *n,bool base);
+    void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes,bool includeParents);
+    void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents);
     void addClass(ClassDef *cd,DotNode *n,int prot,const char *label,
-                  int level,const char *usedName,const char *templSpec,
+                  const char *usedName,const char *templSpec,
                   bool base);
+
     DotNode        *   m_startNode;
     QDict<DotNode> *   m_usedNodes;
     static int         m_curNodeNumber;
     DotNode::GraphType m_graphType;
-    int                m_recDepth;
     QCString           m_diskName;
-    int                m_maxDistance;
 };
 
+/** @brief Representation of an include dependency graph */
 class DotInclDepGraph
 {
   public:
-    DotInclDepGraph(FileDef *fd,int maxRecusionDepth,bool inverse);
+    DotInclDepGraph(FileDef *fd,bool inverse);
    ~DotInclDepGraph();
     QCString writeGraph(QTextStream &t, GraphOutputFormat f,const char *path,
                     const char *relPath,
@@ -184,25 +191,30 @@ class DotInclDepGraph
     void writeXML(QTextStream &t);
 
   private:
-    void buildGraph(DotNode *n,FileDef *fd,int distance);
+    void buildGraph(DotNode *n,FileDef *fd);
+    void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes);
+    void determineTruncatedNodes(QList<DotNode> &queue);
+
     DotNode        *m_startNode;
     QDict<DotNode> *m_usedNodes;
     static int      m_curNodeNumber;
     QCString        m_diskName;
     int             m_maxDistance;
     bool            m_inverse;
-    int             m_recDepth;
 };
 
+/** @brief Representation of an call graph */
 class DotCallGraph
 {
   public:
-    DotCallGraph(MemberDef *md,int maxRecursionDepth, bool inverse);
+    DotCallGraph(MemberDef *md,bool inverse);
    ~DotCallGraph();
     QCString writeGraph(QTextStream &t, GraphOutputFormat f,
                         const char *path,const char *relPath,bool writeImageMap=TRUE);
-    void buildGraph(DotNode *n,MemberDef *md,int distance);
+    void buildGraph(DotNode *n,MemberDef *md);
     bool isTrivial() const;
+    void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes);
+    void determineTruncatedNodes(QList<DotNode> &queue);
     
   private:
     DotNode        *m_startNode;
@@ -215,6 +227,7 @@ class DotCallGraph
     Definition *    m_scope;
 };
 
+/** @brief Representation of an directory dependency graph */
 class DotDirDeps
 {
   public:
@@ -230,6 +243,7 @@ class DotDirDeps
     DirDef *m_dir;
 };
 
+/** @brief Representation of a group collaboration graph */
 class DotGroupCollaboration
 {
   public :
@@ -271,7 +285,7 @@ class DotGroupCollaboration
     QCString writeGraph(QTextStream &t, GraphOutputFormat format,
                     const char *path,const char *relPath,
                     bool writeImageMap=TRUE);
-    void buildGraph(GroupDef* gd,int distance);
+    void buildGraph(GroupDef* gd);
     bool isTrivial() const;
   private :
     void addCollaborationMember( Definition* def, QCString& url, EdgeType eType );
@@ -308,8 +322,9 @@ class DotRunner
 };
 
 
-
+/** Generated a graphs legend page */
 void generateGraphLegend(const char *path);
+
 void writeDotGraphFromFile(const char *inFile,const char *outDir,
                            const char *outFile,GraphOutputFormat format);
 QString getDotImageMapFromFile(const QString& inFile, const QString& outDir,
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 15e56dc..68d7055 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -1897,7 +1897,7 @@ static MemberDef *addVariableToClass(
   }
   Debug::print(Debug::Variables,0,
       "  class variable:\n"
-      "    `%s' `%s'::`%s' `%s' prot=`%d ann=%d init=%s\n",
+      "    `%s' `%s'::`%s' `%s' prot=`%d ann=%d init=`%s'\n",
       root->type.data(),
       qualScope.data(), 
       name.data(),
@@ -2476,7 +2476,6 @@ static void buildVarList(EntryNav *rootNav)
     else
       mtype=MemberDef::Variable;
 
-
     if (!root->relates.isEmpty()) // related variable
     {
       isRelated=TRUE;
@@ -2563,7 +2562,10 @@ nextMember:
     EntryNav *e;
     for (;(e=eli.current());++eli)
     {
-      if (e->section()!=Entry::ENUM_SEC) buildVarList(e);
+      if (e->section()!=Entry::ENUM_SEC) 
+      {
+        buildVarList(e);
+      }
     }
   }
 }
@@ -4669,8 +4671,13 @@ static void addMemberDocs(EntryNav *rootNav,
     }
   }
 
+  //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
+  //    md->initializer().data(),md->initializer().isEmpty(),
+  //    root->initializer.data(),root->initializer.isEmpty()
+  //   );
   if (md->initializer().isEmpty() && !root->initializer.isEmpty())
   {
+    //printf("setInitializer\n");
     md->setInitializer(root->initializer);
     md->setMaxInitLines(root->initLines);
   }
@@ -6369,60 +6376,80 @@ static void addEnumValuesToEnums(EntryNav *rootNav)
             EntryNav *e;
             for (;(e=eli.current());++eli)
             {
-              //printf("e->name=%s isRelated=%d\n",e->name().data(),isRelated);
-              MemberName *fmn=0;
-              MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd;
-              if (!e->name().isEmpty() && (fmn=(*emnsd)[e->name()])) 
-                // get list of members with the same name as the field
+              SrcLangExt sle;
+              if (rootNav->fileDef() &&
+                  ( (sle=getLanguageFromFileName(rootNav->fileDef()->name()))==SrcLangExt_CSharp
+                  || sle==SrcLangExt_Java
+                  )
+                 )
+              {
+                // For C# enum value are only inside the enum scope, so we
+                // must create them here
+                e->loadEntry(g_storage);
+                MemberDef *fmd = addVariableToFile(e,MemberDef::EnumValue,
+                                 md->getOuterScope() ? md->getOuterScope()->name() : "",
+                                 e->name(),TRUE,0); 
+                md->insertEnumField(fmd);
+                fmd->setEnumScope(md);
+                e->releaseEntry();
+              }
+              else
               {
-                MemberNameIterator fmni(*fmn);
-                MemberDef *fmd;
-                for (fmni.toFirst(); (fmd=fmni.current()) ; ++fmni) 
+                //printf("e->name=%s isRelated=%d\n",e->name().data(),isRelated);
+                MemberName *fmn=0;
+                MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd;
+                if (!e->name().isEmpty() && (fmn=(*emnsd)[e->name()])) 
+                  // get list of members with the same name as the field
                 {
-                  if (fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
+                  MemberNameIterator fmni(*fmn);
+                  MemberDef *fmd;
+                  for (fmni.toFirst(); (fmd=fmni.current()) ; ++fmni) 
                   {
-                    //printf("found enum value with same name %s in scope %s\n",
-                    //    fmd->name().data(),fmd->getOuterScope()->name().data());
-                    if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
+                    if (fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
                     {
-                      NamespaceDef *fnd=fmd->getNamespaceDef();
-                      if (fnd==nd) // enum value is inside a namespace
+                      //printf("found enum value with same name %s in scope %s\n",
+                      //    fmd->name().data(),fmd->getOuterScope()->name().data());
+                      if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
                       {
-                        md->insertEnumField(fmd);
-                        fmd->setEnumScope(md);
+                        NamespaceDef *fnd=fmd->getNamespaceDef();
+                        if (fnd==nd) // enum value is inside a namespace
+                        {
+                          md->insertEnumField(fmd);
+                          fmd->setEnumScope(md);
+                        }
                       }
-                    }
-                    else if (isGlobal)
-                    {
-                      FileDef *ffd=fmd->getFileDef();
-                      if (ffd==fd) // enum value has file scope
+                      else if (isGlobal)
                       {
-                        md->insertEnumField(fmd);
-                        fmd->setEnumScope(md);
+                        FileDef *ffd=fmd->getFileDef();
+                        if (ffd==fd) // enum value has file scope
+                        {
+                          md->insertEnumField(fmd);
+                          fmd->setEnumScope(md);
+                        }
                       }
-                    }
-                    else if (isRelated && cd) // reparent enum value to
-                      // match the enum's scope
-                    {
-                      md->insertEnumField(fmd);   // add field def to list
-                      fmd->setEnumScope(md);      // cross ref with enum name
-                      fmd->setEnumClassScope(cd); // cross ref with enum name
-                      fmd->setOuterScope(cd);
-                      fmd->makeRelated();
-                      cd->insertMember(fmd);
-                    }
-                    else
-                    {
-                      ClassDef *fcd=fmd->getClassDef();
-                      if (fcd==cd) // enum value is inside a class
+                      else if (isRelated && cd) // reparent enum value to
+                                                // match the enum's scope
+                      {
+                        md->insertEnumField(fmd);   // add field def to list
+                        fmd->setEnumScope(md);      // cross ref with enum name
+                        fmd->setEnumClassScope(cd); // cross ref with enum name
+                        fmd->setOuterScope(cd);
+                        fmd->makeRelated();
+                        cd->insertMember(fmd);
+                      }
+                      else
                       {
-                        //printf("Inserting enum field %s in enum scope %s\n",
-                        //    fmd->name().data(),md->name().data());
-                        md->insertEnumField(fmd); // add field def to list
-                        fmd->setEnumScope(md);    // cross ref with enum name
+                        ClassDef *fcd=fmd->getClassDef();
+                        if (fcd==cd) // enum value is inside a class
+                        {
+                          //printf("Inserting enum field %s in enum scope %s\n",
+                          //    fmd->name().data(),md->name().data());
+                          md->insertEnumField(fmd); // add field def to list
+                          fmd->setEnumScope(md);    // cross ref with enum name
+                        }
                       }
-                    }
-                  } 
+                    } 
+                  }
                 }
               }
             }
@@ -6994,6 +7021,7 @@ static void inheritDocumentation()
           md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
           md->setDocsForDefinition(bmd->isDocsForDefinition());
           md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
+          md->copyArgumentNames(bmd);
           md->setInbodyDocumentation(bmd->inbodyDocumentation(),bmd->inbodyFile(),bmd->inbodyLine());
         }
       }
@@ -7697,6 +7725,25 @@ static void buildExampleList(EntryNav *rootNav)
 }
 
 //----------------------------------------------------------------------------
+// prints the Entry tree (for debugging)
+
+void printNavTree(EntryNav *rootNav,int indent)
+{
+  QCString indentStr;
+  indentStr.fill(' ',indent);
+  msg("%s%s (sec=0x%x)\n",
+      indentStr.isEmpty()?"":indentStr.data(),
+      rootNav->name().isEmpty()?"<empty>":rootNav->name().data(),
+      rootNav->section());
+  if (rootNav->children()) 
+  {
+    EntryNavListIterator eli(*rootNav->children());
+    for (;eli.current();++eli) printNavTree(eli.current(),indent+2);
+  }
+}
+
+
+//----------------------------------------------------------------------------
 // generate the example documentation 
 
 static void generateExampleDocs()
@@ -8065,7 +8112,6 @@ static bool patternMatch(QFileInfo *fi,QStrList *patList)
       int i=pattern.find('=');
       if (i!=-1) pattern=pattern.left(i); // strip of the extension specific filter name
 
-      //printf("Matching `%s' against pattern `%s'\n",fi->fileName().data(),pattern);
 #if defined(_WIN32) // windows
       QRegExp re(pattern,FALSE,TRUE); // case insensitive match 
 #else                // unix
@@ -8074,6 +8120,8 @@ static bool patternMatch(QFileInfo *fi,QStrList *patList)
       found = found || re.match(fi->fileName())!=-1 || 
                        re.match(fi->filePath())!=-1 ||
                        re.match(fi->absFilePath())!=-1;
+      //printf("Matching `%s' against pattern `%s' found=%d\n",
+      //    fi->fileName().data(),pattern.data(),found);
       pattern=patList->next();
     }
   }
@@ -8255,7 +8303,7 @@ static int readDir(QFileInfo *fi,
   QDir dir((const char *)fi->absFilePath());
   dir.setFilter( QDir::Files | QDir::Dirs | QDir::Hidden );
   int totalSize=0;
-  msg("Search for files in directory %s\n", fi->absFilePath().data());
+  msg("Searching for files in directory %s\n", fi->absFilePath().data());
   //printf("killDict=%p count=%d\n",killDict,killDict->count());
   
   const QFileInfoList *list = dir.entryInfoList();
@@ -8312,6 +8360,7 @@ static int readDir(QFileInfo *fi,
       else if (recursive &&
           (!Config_getBool("EXCLUDE_SYMLINKS") || !cfi->isSymLink()) &&
           cfi->isDir() && cfi->fileName()!="." && 
+          !patternMatch(cfi,exclPatList) &&
           cfi->fileName()!="..")
       {
         cfi->setFile(cfi->absFilePath());
@@ -9137,8 +9186,109 @@ void parseInput()
   bool alwaysRecursive = Config_getBool("RECURSIVE");
 
   /**************************************************************************
+   *            Check/create output directorties                            *
+   **************************************************************************/
+
+  QCString &htmlOutput = Config_getString("HTML_OUTPUT");
+  bool &generateHtml = Config_getBool("GENERATE_HTML");
+  if (htmlOutput.isEmpty() && generateHtml)
+  {
+    htmlOutput=outputDirectory+"/html";
+  }
+  else if (htmlOutput && htmlOutput[0]!='/' && htmlOutput[1]!=':')
+  {
+    htmlOutput.prepend(outputDirectory+'/');
+  }
+  QDir htmlDir(htmlOutput);
+  if (generateHtml && !htmlDir.exists() && !htmlDir.mkdir(htmlOutput))
+  {
+    err("Could not create output directory %s\n",htmlOutput.data());
+    cleanUpDoxygen();
+    exit(1);
+  }
+  
+  QCString &xmlOutput = Config_getString("XML_OUTPUT");
+  bool &generateXml = Config_getBool("GENERATE_XML");
+  if (xmlOutput.isEmpty() && generateXml)
+  {
+    xmlOutput=outputDirectory+"/xml";
+  }
+  else if (xmlOutput && xmlOutput[0]!='/' && xmlOutput[1]!=':')
+  {
+    xmlOutput.prepend(outputDirectory+'/');
+  }
+  QDir xmlDir(xmlOutput);
+  if (generateXml && !xmlDir.exists() && !xmlDir.mkdir(xmlOutput))
+  {
+    err("Could not create output directory %s\n",xmlOutput.data());
+    cleanUpDoxygen();
+    exit(1);
+  }
+  
+  QCString &latexOutput = Config_getString("LATEX_OUTPUT");
+  bool &generateLatex = Config_getBool("GENERATE_LATEX");
+  if (latexOutput.isEmpty() && generateLatex)
+  {
+    latexOutput=outputDirectory+"/latex";
+  }
+  else if (latexOutput && latexOutput[0]!='/' && latexOutput[1]!=':')
+  {
+    latexOutput.prepend(outputDirectory+'/');
+  }
+  QDir latexDir(latexOutput);
+  if (generateLatex && !latexDir.exists() && !latexDir.mkdir(latexOutput))
+  {
+    err("Could not create output directory %s\n",latexOutput.data());
+    cleanUpDoxygen();
+    exit(1);
+  }
+  
+  QCString &rtfOutput = Config_getString("RTF_OUTPUT");
+  bool &generateRtf = Config_getBool("GENERATE_RTF");
+  if (rtfOutput.isEmpty() && generateRtf)
+  {
+    rtfOutput=outputDirectory+"/rtf";
+  }
+  else if (rtfOutput && rtfOutput[0]!='/' && rtfOutput[1]!=':')
+  {
+    rtfOutput.prepend(outputDirectory+'/');
+  }
+  QDir rtfDir(rtfOutput);
+  if (generateRtf && !rtfDir.exists() && !rtfDir.mkdir(rtfOutput))
+  {
+    err("Could not create output directory %s\n",rtfOutput.data());
+    cleanUpDoxygen();
+    exit(1);
+  }
+
+  QCString &manOutput = Config_getString("MAN_OUTPUT");
+  bool &generateMan = Config_getBool("GENERATE_MAN");
+  if (manOutput.isEmpty() && generateMan)
+  {
+    manOutput=outputDirectory+"/man";
+  }
+  else if (manOutput && manOutput[0]!='/' && manOutput[1]!=':')
+  {
+    manOutput.prepend(outputDirectory+'/');
+  }
+  QDir manDir(manOutput);
+  if (generateMan && !manDir.exists() && !manDir.mkdir(manOutput))
+  {
+    err("Could not create output directory %s\n",manOutput.data());
+    cleanUpDoxygen();
+    exit(1);
+  }
+  /**************************************************************************
    *             Read and preprocess input                                  *
    **************************************************************************/
+ 
+  QStrList &exclPatterns = Config_getList("EXCLUDE_PATTERNS");
+  // prevent search in the output directories
+  if (generateHtml)  exclPatterns.append(htmlOutput);
+  if (generateXml)   exclPatterns.append(xmlOutput);
+  if (generateLatex) exclPatterns.append(latexOutput);
+  if (generateRtf)   exclPatterns.append(rtfOutput);
+  if (generateMan)   exclPatterns.append(manOutput);
 
   // gather names of all files in the include path
   msg("Searching for include files...\n");
@@ -9152,7 +9302,7 @@ void parseInput()
       pl = Config_getList("FILE_PATTERNS");
     }
     readFileOrDirectory(s,0,Doxygen::includeNameDict,0,&pl,
-                        &Config_getList("EXCLUDE_PATTERNS"),0,0,
+                        &exclPatterns,0,0,
                         alwaysRecursive);
     s=includePathList.next(); 
   }
@@ -9226,7 +9376,7 @@ void parseInput()
         Doxygen::inputNameDict,
         &excludeNameDict,
         &Config_getList("FILE_PATTERNS"),
-        &Config_getList("EXCLUDE_PATTERNS"),
+        &exclPatterns,
         &inputFiles,0,
         alwaysRecursive,
         TRUE,
@@ -9250,99 +9400,6 @@ void parseInput()
   // read aliases and store them in a dictionary
   readAliases();
 
-  /**************************************************************************
-   *            Check/create output directorties                            *
-   **************************************************************************/
-
-  QCString &htmlOutput = Config_getString("HTML_OUTPUT");
-  bool &generateHtml = Config_getBool("GENERATE_HTML");
-  if (htmlOutput.isEmpty() && generateHtml)
-  {
-    htmlOutput=outputDirectory+"/html";
-  }
-  else if (htmlOutput && htmlOutput[0]!='/' && htmlOutput[1]!=':')
-  {
-    htmlOutput.prepend(outputDirectory+'/');
-  }
-  QDir htmlDir(htmlOutput);
-  if (generateHtml && !htmlDir.exists() && !htmlDir.mkdir(htmlOutput))
-  {
-    err("Could not create output directory %s\n",htmlOutput.data());
-    cleanUpDoxygen();
-    exit(1);
-  }
-  
-  QCString &xmlOutput = Config_getString("XML_OUTPUT");
-  bool &generateXml = Config_getBool("GENERATE_XML");
-  if (xmlOutput.isEmpty() && generateXml)
-  {
-    xmlOutput=outputDirectory+"/xml";
-  }
-  else if (xmlOutput && xmlOutput[0]!='/' && xmlOutput[1]!=':')
-  {
-    xmlOutput.prepend(outputDirectory+'/');
-  }
-  QDir xmlDir(xmlOutput);
-  if (generateXml && !xmlDir.exists() && !xmlDir.mkdir(xmlOutput))
-  {
-    err("Could not create output directory %s\n",xmlOutput.data());
-    cleanUpDoxygen();
-    exit(1);
-  }
-  
-  QCString &latexOutput = Config_getString("LATEX_OUTPUT");
-  bool &generateLatex = Config_getBool("GENERATE_LATEX");
-  if (latexOutput.isEmpty() && generateLatex)
-  {
-    latexOutput=outputDirectory+"/latex";
-  }
-  else if (latexOutput && latexOutput[0]!='/' && latexOutput[1]!=':')
-  {
-    latexOutput.prepend(outputDirectory+'/');
-  }
-  QDir latexDir(latexOutput);
-  if (generateLatex && !latexDir.exists() && !latexDir.mkdir(latexOutput))
-  {
-    err("Could not create output directory %s\n",latexOutput.data());
-    cleanUpDoxygen();
-    exit(1);
-  }
-  
-  QCString &rtfOutput = Config_getString("RTF_OUTPUT");
-  bool &generateRtf = Config_getBool("GENERATE_RTF");
-  if (rtfOutput.isEmpty() && generateRtf)
-  {
-    rtfOutput=outputDirectory+"/rtf";
-  }
-  else if (rtfOutput && rtfOutput[0]!='/' && rtfOutput[1]!=':')
-  {
-    rtfOutput.prepend(outputDirectory+'/');
-  }
-  QDir rtfDir(rtfOutput);
-  if (generateRtf && !rtfDir.exists() && !rtfDir.mkdir(rtfOutput))
-  {
-    err("Could not create output directory %s\n",rtfOutput.data());
-    cleanUpDoxygen();
-    exit(1);
-  }
-
-  QCString &manOutput = Config_getString("MAN_OUTPUT");
-  bool &generateMan = Config_getBool("GENERATE_MAN");
-  if (manOutput.isEmpty() && generateMan)
-  {
-    manOutput=outputDirectory+"/man";
-  }
-  else if (manOutput && manOutput[0]!='/' && manOutput[1]!=':')
-  {
-    manOutput.prepend(outputDirectory+'/');
-  }
-  QDir manDir(manOutput);
-  if (generateMan && !manDir.exists() && !manDir.mkdir(manOutput))
-  {
-    err("Could not create output directory %s\n",manOutput.data());
-    cleanUpDoxygen();
-    exit(1);
-  }
 
   // Notice: the order of the function calls below is very important!
   
@@ -9390,6 +9447,8 @@ void parseInput()
     exit(1);
   }
 
+  //printNavTree(rootNav,0);
+
   // we are done with input scanning now, so free up the buffers used by flex
   // (can be around 4MB)
   preFreeScanner();
diff --git a/src/doxygen.h b/src/doxygen.h
index 4227f4a..c52829c 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/doxygen.pro.in b/src/doxygen.pro.in
index 99e241f..7d1e812 100644
--- a/src/doxygen.pro.in
+++ b/src/doxygen.pro.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 #
diff --git a/src/doxytag.l b/src/doxytag.l
index 2a1f0a1..53e89a3 100644
--- a/src/doxytag.l
+++ b/src/doxytag.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/doxytag.pro.in b/src/doxytag.pro.in
index 3d4e9f8..8df2777 100644
--- a/src/doxytag.pro.in
+++ b/src/doxytag.pro.in
@@ -1,5 +1,5 @@
 # 
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 # 
diff --git a/src/doxytag.t b/src/doxytag.t
index 5a5fbc1..82cf04b 100644
--- a/src/doxytag.t
+++ b/src/doxytag.t
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 #
diff --git a/src/entry.cpp b/src/entry.cpp
index 0d0cb4f..eaeaf5e 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/entry.h b/src/entry.h
index ba1abaf..30b55fb 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/example.h b/src/example.h
index 4b795c3..4b6e06e 100644
--- a/src/example.h
+++ b/src/example.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 4968f50..046232c 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -43,9 +43,9 @@ class DevNullCodeDocInterface : public CodeOutputInterface
 {
   public:
     virtual void codify(const char *) {}
-    virtual void writeCodeLink(const char *ref,const char *file,
-                               const char *anchor,const char *name) 
-    { ref=ref; file=file; anchor=anchor; name=name; }
+    virtual void writeCodeLink(const char *,const char *,
+                               const char *,const char *,
+                               const char *) {}
     virtual void writeLineNumber(const char *,const char *,
                                  const char *,int) {}
     virtual void startCodeLine() {}
@@ -324,9 +324,10 @@ void FileDef::writeDocumentation(OutputList &ol)
       bool isIDLorJava = FALSE;
       if (fd)
       {
-        isIDLorJava = fd->name().right(4)==".idl" || 
+        isIDLorJava = fd->name().right(4)==".idl" ||   // M$ or Corba IDL
                       fd->name().right(5)==".pidl" ||
-                      fd->name().right(5)==".java";
+                      fd->name().right(5)==".java" ||  // Sun's Java
+                      fd->name().right(4)==".jsl";     // M$ J#
       }
       ol.startTypewriter();
       if (isIDLorJava) // IDL/Java include
@@ -393,7 +394,7 @@ void FileDef::writeDocumentation(OutputList &ol)
   if (Config_getBool("HAVE_DOT") && Config_getBool("INCLUDE_GRAPH"))
   {
     //printf("Graph for file %s\n",name().data());
-    DotInclDepGraph incDepGraph(this,Config_getInt("MAX_DOT_GRAPH_DEPTH"),FALSE);
+    DotInclDepGraph incDepGraph(this,FALSE);
     if (!incDepGraph.isTrivial())
     {
       ol.startTextBlock(); 
@@ -411,7 +412,7 @@ void FileDef::writeDocumentation(OutputList &ol)
   if (Config_getBool("HAVE_DOT") && Config_getBool("INCLUDED_BY_GRAPH"))
   {
     //printf("Graph for file %s\n",name().data());
-    DotInclDepGraph incDepGraph(this,Config_getInt("MAX_DOT_GRAPH_DEPTH"),TRUE);
+    DotInclDepGraph incDepGraph(this,TRUE);
     if (!incDepGraph.isTrivial())
     {
       ol.startTextBlock(); 
diff --git a/src/filedef.h b/src/filedef.h
index cda5730..c5b99ab 100644
--- a/src/filedef.h
+++ b/src/filedef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/filename.cpp b/src/filename.cpp
index 3126811..2399124 100644
--- a/src/filename.cpp
+++ b/src/filename.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/filename.h b/src/filename.h
index 749bf4e..c1b30b6 100644
--- a/src/filename.h
+++ b/src/filename.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/formula.cpp b/src/formula.cpp
index fbe02ee..07d60d2 100644
--- a/src/formula.cpp
+++ b/src/formula.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  i
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/formula.h b/src/formula.h
index 9438f37..a4c0f53 100644
--- a/src/formula.h
+++ b/src/formula.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/groupdef.cpp b/src/groupdef.cpp
index c429780..13a5681 100644
--- a/src/groupdef.cpp
+++ b/src/groupdef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/groupdef.h b/src/groupdef.h
index b4c31bf..25bc79d 100644
--- a/src/groupdef.h
+++ b/src/groupdef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/htmlattrib.h b/src/htmlattrib.h
index cc87b23..9a1609b 100644
--- a/src/htmlattrib.h
+++ b/src/htmlattrib.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 4eb6a8a..cc59c47 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -69,7 +69,7 @@ void HtmlDocVisitor::visit(DocWord *w)
 void HtmlDocVisitor::visit(DocLinkedWord *w)
 {
   if (m_hide) return;
-  startLink(w->ref(),w->file(),w->relPath(),w->anchor());
+  startLink(w->ref(),w->file(),w->relPath(),w->anchor(),w->tooltip());
   filter(w->word());
   endLink();
 }
@@ -228,9 +228,10 @@ void HtmlDocVisitor::visit(DocVerbatim *s)
         static int dotindex = 1;
         QCString fileName(4096);
 
-        fileName.sprintf("%s%d", 
+        fileName.sprintf("%s%d%s", 
             (Config_getString("HTML_OUTPUT")+"/inline_dotgraph_").data(), 
-            dotindex++
+            dotindex++,
+            ".dot"
            );
         QFile file(fileName);
         if (!file.open(IO_WriteOnly))
@@ -244,7 +245,7 @@ void HtmlDocVisitor::visit(DocVerbatim *s)
         writeDotFile(fileName,s->relPath());
         m_t << "</div>" << endl;
 
-        file.remove();
+        if (Config_getBool("DOT_CLEANUP")) file.remove();
       }
       break;
   }
@@ -1062,7 +1063,8 @@ void HtmlDocVisitor::filterQuotedCdataAttr(const char* str)
 }
 
 void HtmlDocVisitor::startLink(const QString &ref,const QString &file,
-                               const QString &relPath,const QString &anchor)
+                               const QString &relPath,const QString &anchor,
+                               const QString &tooltip)
 {
   QCString *dest;
   if (!ref.isEmpty()) // link to entity imported via tag file
@@ -1087,7 +1089,9 @@ void HtmlDocVisitor::startLink(const QString &ref,const QString &file,
   }
   if (!file.isEmpty()) m_t << file << Doxygen::htmlFileExtension;
   if (!anchor.isEmpty()) m_t << "#" << anchor;
-  m_t << "\">";
+  m_t << "\"";
+  if (!tooltip.isEmpty()) m_t << " title=\"" << tooltip << "\"";
+  m_t << ">";
 }
 
 void HtmlDocVisitor::endLink()
diff --git a/src/htmldocvisitor.h b/src/htmldocvisitor.h
index 069d3f9..5cf95c0 100644
--- a/src/htmldocvisitor.h
+++ b/src/htmldocvisitor.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -132,7 +132,8 @@ class HtmlDocVisitor : public DocVisitor
     void filter(const char *str);
     void filterQuotedCdataAttr(const char* str);
     void startLink(const QString &ref,const QString &file,
-                   const QString &relPath,const QString &anchor);
+                   const QString &relPath,const QString &anchor,
+                   const QString &tooltip = QString::null);
     void endLink();
     void writeDotFile(const QString &fileName,const QString &relPath);
 
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 90184f2..235fb64 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -586,7 +586,7 @@ void HtmlGenerator::writeHeaderFile(QFile &file)
 void HtmlGenerator::writeFooterFile(QFile &file)
 {
   QTextStream t(&file);
-  t << "<hr size=\"1\"><address style=\"align: right;\"><small>\n";
+  t << "<hr size=\"1\"><address style=\"text-align: right;\"><small>\n";
   t << theTranslator->trGeneratedAt( "$datetime", "$projectname" );
   t << "&nbsp;<a href=\"http://www.doxygen.org/index.html\">"
     << "<img src=\"doxygen.png\" alt=\"doxygen\" " 
@@ -642,7 +642,7 @@ static void writePageFooter(QTextStream &t,const QCString &lastTitle,
 {
   if (g_footer.isEmpty())
   {
-    t << "<hr size=\"1\"><address style=\"align: right;\"><small>";
+    t << "<hr size=\"1\"><address style=\"text-align: right;\"><small>";
     t << theTranslator->trGeneratedAt(
         dateToString(TRUE),
         Config_getString("PROJECT_NAME")
@@ -841,7 +841,8 @@ void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
 }
 
 void HtmlGenerator::writeCodeLink(const char *ref,const char *f,
-                                  const char *anchor, const char *name)
+                                  const char *anchor, const char *name,
+                                  const char *tooltip)
 {
   QCString *dest;
   if (ref) 
@@ -866,7 +867,9 @@ void HtmlGenerator::writeCodeLink(const char *ref,const char *f,
   }
   if (f) t << f << Doxygen::htmlFileExtension;
   if (anchor) t << "#" << anchor;
-  t << "\">";
+  t << "\"";
+  if (tooltip) t << " title=\"" << tooltip << "\"";
+  t << ">";
   docify(name);
   t << "</a>";
   col+=strlen(name);
@@ -1508,7 +1511,7 @@ void HtmlGenerator::writeLineNumber(const char *ref,const char *file,
   if (file)
   {
     startCodeAnchor(lineAnchor);
-    writeCodeLink(ref,file,anchor,lineNumber);
+    writeCodeLink(ref,file,anchor,lineNumber,0);
     endCodeAnchor();
   }
   else
diff --git a/src/htmlgen.h b/src/htmlgen.h
index a8a3225..ed57628 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -79,7 +79,8 @@ class HtmlGenerator : public OutputGenerator
     void writeObjectLink(const char *ref,const char *file,
                          const char *anchor,const char *name);
     void writeCodeLink(const char *ref,const char *file,
-                       const char *anchor,const char *name);
+                       const char *anchor,const char *name,
+                       const char *tooltip);
     void startTextLink(const char *file,const char *anchor);
     void endTextLink();
     void startHtmlLink(const char *url);
diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp
index 598ed6a..c9328e6 100644
--- a/src/htmlhelp.cpp
+++ b/src/htmlhelp.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/htmlhelp.h b/src/htmlhelp.h
index f323894..67e0e20 100644
--- a/src/htmlhelp.h
+++ b/src/htmlhelp.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/image.cpp b/src/image.cpp
index e769c76..ee00835 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/image.h b/src/image.h
index 998b93d..49ba9ba 100644
--- a/src/image.h
+++ b/src/image.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/index.cpp b/src/index.cpp
index 7345347..076a68b 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/index.h b/src/index.h
index cda0678..e63537f 100644
--- a/src/index.h
+++ b/src/index.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/instdox.cpp b/src/instdox.cpp
index 5fc89a5..3f814d4 100644
--- a/src/instdox.cpp
+++ b/src/instdox.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/instdox.h b/src/instdox.h
index 82d2910..ede8e8f 100644
--- a/src/instdox.h
+++ b/src/instdox.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/language.h b/src/language.h
index 06aef66..22932eb 100644
--- a/src/language.h
+++ b/src/language.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
index c58315a..9ac9a87 100644
--- a/src/latexdocvisitor.cpp
+++ b/src/latexdocvisitor.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -261,7 +261,7 @@ void LatexDocVisitor::visit(DocVerbatim *s)
       Doxygen::parserManager->getParser(m_langExt)
                             ->parseCode(m_ci,s->context(),s->text().latin1(),
                                         s->isExample(),s->exampleFile());
-      m_t << "\\end{verbatim}\\end{Code}\n" << endl; 
+      m_t << "\\end{verbatim}\n\\end{Code}\n" << endl; 
       break;
     case DocVerbatim::Verbatim: 
       m_t << "\n\n\\footnotesize\\begin{verbatim}"; 
@@ -281,9 +281,10 @@ void LatexDocVisitor::visit(DocVerbatim *s)
         static int dotindex = 1;
         QCString fileName(4096);
 
-        fileName.sprintf("%s%d", 
+        fileName.sprintf("%s%d%s", 
             (Config_getString("LATEX_OUTPUT")+"/inline_dotgraph_").data(), 
-            dotindex++
+            dotindex++,
+            ".dot"
            );
         QFile file(fileName);
         if (!file.open(IO_WriteOnly))
@@ -298,7 +299,7 @@ void LatexDocVisitor::visit(DocVerbatim *s)
         endDotFile(FALSE);
         m_t << "\\end{center}\n";
 
-        file.remove();
+        if (Config_getBool("DOT_CLEANUP")) file.remove();
       }
       break;
   }
diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h
index 2625a7c..2241f06 100644
--- a/src/latexdocvisitor.h
+++ b/src/latexdocvisitor.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 5088b7c..624278d 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -1022,7 +1022,8 @@ void LatexGenerator::endPageRef(const char *clname, const char *anchor)
 }
 
 void LatexGenerator::writeCodeLink(const char *,const char *,
-                                   const char *,const char *name)
+                                   const char *,const char *name,
+                                   const char *)
 {
   t << name;
   col+=strlen(name);
diff --git a/src/latexgen.h b/src/latexgen.h
index a5fbd1d..4d361ab 100644
--- a/src/latexgen.h
+++ b/src/latexgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -77,7 +77,8 @@ class LatexGenerator : public OutputGenerator
     void writeObjectLink(const char *ref,const char *file,
                          const char *anchor,const char *name);
     void writeCodeLink(const char *ref, const char *file,
-                       const char *anchor,const char *name);
+                       const char *anchor,const char *name,
+                       const char *tooltip);
     void startTextLink(const char *,const char *);
     void endTextLink();
     void startHtmlLink(const char *url);
@@ -117,7 +118,7 @@ class LatexGenerator : public OutputGenerator
     void writeRuler() { t << endl << endl; /*t << "\\vspace{0.4cm}\\hrule\\vspace{0.2cm}" << endl; */ }
     void writeAnchor(const char *fileName,const char *name);
     void startCodeFragment() { t << endl << endl << "\\begin{Code}\\begin{verbatim}"; }
-    void endCodeFragment()   { t << "\\end{verbatim}\\end{Code}" << endl; }
+    void endCodeFragment()   { t << "\\end{verbatim}\n\\end{Code}" << endl; }
     void writeLineNumber(const char *,const char *,const char *,int l) { t << l << " "; }
     void startCodeLine() { col=0; }
     void endCodeLine() { codify("\n"); }
diff --git a/src/libdoxycfg.pro.in b/src/libdoxycfg.pro.in
index 6cff964..cf4454e 100644
--- a/src/libdoxycfg.pro.in
+++ b/src/libdoxycfg.pro.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 #
diff --git a/src/libdoxycfg.t b/src/libdoxycfg.t
index 3a63100..aa75498 100644
--- a/src/libdoxycfg.t
+++ b/src/libdoxycfg.t
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 #
diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in
index 20fd265..ae89a80 100644
--- a/src/libdoxygen.pro.in
+++ b/src/libdoxygen.pro.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 #
@@ -93,6 +93,7 @@ HEADERS      =	bufstr.h \
 		sortdict.h \
                 store.h \
 		tagreader.h \
+                textdocvisitor.h \
 		translator.h \
 		translator_adapter.h \
 		translator_br.h \
@@ -195,6 +196,7 @@ SOURCES      =	ce_lex.cpp \
 		searchindex.cpp \
                 store.cpp \
 		tagreader.cpp \
+                textdocvisitor.cpp \
 		translator.cpp \
 		util.cpp \
 		version.cpp \
diff --git a/src/libdoxygen.t b/src/libdoxygen.t
index ff31523..7910d01 100644
--- a/src/libdoxygen.t
+++ b/src/libdoxygen.t
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2006 by Dimitri van Heesch.
 #
diff --git a/src/lockingptr.h b/src/lockingptr.h
index 64217f5..99a1772 100644
--- a/src/lockingptr.h
+++ b/src/lockingptr.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/logos.cpp b/src/logos.cpp
index 12a1e86..861e942 100644
--- a/src/logos.cpp
+++ b/src/logos.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/logos.h b/src/logos.h
index dd45a0c..b4c95ad 100644
--- a/src/logos.h
+++ b/src/logos.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/main.cpp b/src/main.cpp
index 1b69973..232bf0e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp
index d9c35d6..530b272 100644
--- a/src/mandocvisitor.cpp
+++ b/src/mandocvisitor.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/mandocvisitor.h b/src/mandocvisitor.h
index ad2beff..93e2eb1 100644
--- a/src/mandocvisitor.h
+++ b/src/mandocvisitor.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/mangen.cpp b/src/mangen.cpp
index 4f7ed3f..3a47043 100644
--- a/src/mangen.cpp
+++ b/src/mangen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -204,7 +204,8 @@ void ManGenerator::writeObjectLink(const char *,const char *,
 }
 
 void ManGenerator::writeCodeLink(const char *,const char *,
-                                    const char *, const char *name)
+                                 const char *, const char *name,
+                                 const char *)
 {
   docify(name);
 }
diff --git a/src/mangen.h b/src/mangen.h
index ad6a59d..df9effa 100644
--- a/src/mangen.h
+++ b/src/mangen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -81,7 +81,8 @@ class ManGenerator : public OutputGenerator
     void writeObjectLink(const char *ref,const char *file,
                          const char *anchor,const char *name);
     void writeCodeLink(const char *ref,const char *file,
-                       const char *anchor,const char *name);
+                       const char *anchor,const char *name,
+                       const char *tooltip);
     void startTextLink(const char *,const char *) {}
     void endTextLink() {}
     void startHtmlLink(const char *url);
diff --git a/src/marshal.cpp b/src/marshal.cpp
index a625369..de659b1 100644
--- a/src/marshal.cpp
+++ b/src/marshal.cpp
@@ -243,6 +243,22 @@ void marshalDocInfo(StorageIntf *s,DocInfo *docInfo)
   }
 }
 
+void marshalBriefInfo(StorageIntf *s,BriefInfo *briefInfo)
+{
+  if (briefInfo==0)
+  {
+    marshalUInt(s,NULL_LIST); // null pointer representation
+  }
+  else
+  {
+    marshalUInt(s,1); 
+    marshalQCString(s,briefInfo->doc);
+    marshalQCString(s,briefInfo->tooltip);
+    marshalInt(s,briefInfo->line);
+    marshalQCString(s,briefInfo->file);
+  }
+}
+
 void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo)
 {
   if (bodyInfo==0)
@@ -566,6 +582,18 @@ DocInfo *unmarshalDocInfo(StorageIntf *s)
   return result;
 }
 
+BriefInfo *unmarshalBriefInfo(StorageIntf *s)
+{
+  uint count = unmarshalUInt(s); 
+  if (count==NULL_LIST) return 0;
+  BriefInfo *result = new BriefInfo;
+  result->doc     = unmarshalQCString(s);
+  result->tooltip = unmarshalQCString(s);
+  result->line    = unmarshalInt(s);
+  result->file    = unmarshalQCString(s);
+  return result;
+}
+
 BodyInfo *unmarshalBodyInfo(StorageIntf *s)
 {
   uint count = unmarshalUInt(s); 
diff --git a/src/marshal.h b/src/marshal.h
index 864e8b3..26c7571 100644
--- a/src/marshal.h
+++ b/src/marshal.h
@@ -18,6 +18,7 @@ class MemberSDict;
 class GroupList;
 struct BodyInfo;
 struct DocInfo;
+struct BriefInfo;
 class MemberList;
 class ExampleSDict;
 
@@ -49,6 +50,7 @@ void marshalObjPointer(StorageIntf *s,void *obj);
 void marshalSectionDict(StorageIntf *s,SectionDict *sections);
 void marshalMemberSDict(StorageIntf *s,MemberSDict *memberSDict);
 void marshalDocInfo(StorageIntf *s,DocInfo *docInfo);
+void marshalBriefInfo(StorageIntf *s,BriefInfo *briefInfo);
 void marshalBodyInfo(StorageIntf *s,BodyInfo *bodyInfo);
 void marshalGroupList(StorageIntf *s,GroupList *groupList);
 void marshalMemberList(StorageIntf *s,MemberList *ml);
@@ -72,6 +74,7 @@ void *               unmarshalObjPointer(StorageIntf *s);
 SectionDict *        unmarshalSectionDict(StorageIntf *s);
 MemberSDict *        unmarshalMemberSDict(StorageIntf *s);
 DocInfo *            unmarshalDocInfo(StorageIntf *s);
+BriefInfo *          unmarshalBriefInfo(StorageIntf *s);
 BodyInfo *           unmarshalBodyInfo(StorageIntf *s);
 GroupList *          unmarshalGroupList(StorageIntf *s);
 MemberList *         unmarshalMemberList(StorageIntf *s);
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 32c6b4c..55a8fb8 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -581,121 +581,6 @@ MemberDef::MemberDef(const char *df,int dl,
   m_impl = new MemberDefImpl;
   m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al);
   m_flushPending = FALSE;
-
-#if 0
-  //printf("++++++ MemberDef(%s file=%s,line=%d static=%d) ++++++ \n",
-  //    na,df,dl,s);
-  classDef=0;
-  fileDef=0;
-  redefines=0;
-  m_relatedAlso=0;
-  redefinedBy=0;
-  nspace=0;
-  memDef=0;
-  memDec=0;
-  group=0;
-  grpId=-1;
-  exampleSDict=0;
-  enumFields=0;
-  enumScope=0;
-  m_defTmpArgLists=0;
-  m_hasCallGraph = FALSE;
-  m_hasCallerGraph = FALSE;
-  initLines=0;
-  type=t;
-  if (mt==Typedef) type.stripPrefix("typedef ");
-  type.stripPrefix("struct ");
-  type.stripPrefix("class " );
-  type.stripPrefix("union " );
-  type=removeRedundantWhiteSpace(type);
-
-  args=a;
-  args=removeRedundantWhiteSpace(args);
-  if (type.isEmpty()) decl=name()+args; else decl=type+" "+name()+args;
-
-  memberGroup=0;
-  virt=v;
-  prot=p;
-  related=r;
-  stat=s;
-  mtype=mt;
-  exception=e;
-  proto=FALSE;
-  annScope=FALSE;
-  memSpec=0;
-  annMemb=0;
-  annUsed=FALSE;
-  annEnumType=0;
-  groupAlias=0;
-  explExt=FALSE;
-  tspec=FALSE;
-  cachedAnonymousType=0;
-  maxInitLines=Config_getInt("MAX_INITIALIZER_LINES");
-  userInitLines=-1;
-  docEnumValues=FALSE;
-  // copy function template arguments (if any)
-  if (tal)
-  {
-    tArgList = new ArgumentList;
-    tArgList->setAutoDelete(TRUE);
-    ArgumentListIterator ali(*tal);
-    Argument *a;
-    for (;(a=ali.current());++ali)
-    {
-      tArgList->append(new Argument(*a));
-    }
-  }
-  else
-  {
-    tArgList=0;
-  }
-  //printf("new member al=%p\n",al);
-  // copy function definition arguments (if any)
-  if (al)
-  {
-    defArgList = new ArgumentList;
-    defArgList->setAutoDelete(TRUE);
-    ArgumentListIterator ali(*al);
-    Argument *a;
-    for (;(a=ali.current());++ali)
-    {
-      //printf("copy argument %s (doc=%s)\n",a->name.data(),a->docs.data());
-      defArgList->append(new Argument(*a));
-    }
-    defArgList->constSpecifier    = al->constSpecifier;
-    defArgList->volatileSpecifier = al->volatileSpecifier;
-    defArgList->pureSpecifier     = al->pureSpecifier;
-    //printf("defArgList(%p)->constSpecifier=%d\n",defArgList,defArgList->constSpecifier);
-  }
-  else
-  {
-    defArgList=0;
-  }
-  // convert function declaration arguments (if any)
-  if (!args.isEmpty())
-  {
-    declArgList = new ArgumentList;
-    stringToArgumentList(args,declArgList);
-    //printf("setDeclArgList %s to %p const=%d\n",args.data(),
-    //    declArgList,declArgList->constSpecifier);
-  }
-  else
-  {
-    declArgList = 0;
-  }
-  m_templateMaster = 0;
-  classSectionSDict = 0;
-  docsForDefinition = TRUE;
-  m_isTypedefValCached = FALSE;
-  m_cachedTypedefValue = 0;
-  m_inbodyLine = -1;
-  m_implOnly=FALSE;
-  groupMember = 0;
-  m_hasDocumentedParams = FALSE;
-  m_hasDocumentedReturnType = FALSE;
-  m_docProvider = 0;
-  m_isDMember = getDefFileName().right(2).lower()==".d";
-#endif
 }
 
 /*! Destroys the member definition. */
@@ -1632,6 +1517,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
   bool hasParameterList = FALSE;
   bool inFile = container->definitionType()==Definition::TypeFile;
   bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
+  static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
   //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d\n",
   //    name().data(),hasDocs,container->definitionType(),inGroup);
   if ( !hasDocs ) return;
@@ -1660,7 +1546,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
   QCString cfname = getOutputFileBase();
   QCString cfiname = container->getOutputFileBase();
 
-  bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
+  static bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
   HtmlHelp *htmlHelp = 0;
   if (hasHtmlHelp)
   {
@@ -1671,7 +1557,11 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
     else
     {
       htmlHelp = HtmlHelp::getInstance();
-      htmlHelp->addIndexItem(ciname,name(),cfiname,cfname,memAnchor);
+      htmlHelp->addIndexItem(ciname,                                // level1
+                             name(),                                // level2
+                             separateMemPages ? cfname : cfiname,   // contRef
+                             cfname,                                // memRef
+                             memAnchor);                            // anchor
     }
   }
 
@@ -2062,7 +1952,11 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
 
           if (hasHtmlHelp)
           {
-            HtmlHelp::getInstance()->addIndexItem(cname,fmd->name(),cfiname,cfname,fmd->anchor());
+             htmlHelp->addIndexItem(ciname,                                // level1
+                                    fmd->name(),                           // level2
+                                    separateMemPages ? cfname : cfiname,   // contRef
+                                    cfname,                                // memRef
+                                    fmd->anchor());                        // anchor
           }
           //ol.writeListItem();
           ol.startDescTableTitle(); // this enables emphasis!
@@ -2261,7 +2155,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
       && isFunction() && Config_getBool("HAVE_DOT")
      )
   {
-    DotCallGraph callGraph(this,Config_getInt("MAX_DOT_GRAPH_DEPTH"), FALSE);
+    DotCallGraph callGraph(this,FALSE);
     if (!callGraph.isTrivial())
     {
       msg("Generating call graph for function %s\n",qualifiedName().data());
@@ -2277,7 +2171,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
       && isFunction() && Config_getBool("HAVE_DOT")
      )
   {
-    DotCallGraph callerGraph(this,Config_getInt("MAX_DOT_GRAPH_DEPTH"), true);
+    DotCallGraph callerGraph(this, true);
     if (!callerGraph.isTrivial())
     {
       msg("Generating caller graph for function %s\n",qualifiedName().data());
@@ -2567,7 +2461,8 @@ bool MemberDef::hasOneLineInitializer() const
 {
   makeResident();
   //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
-  //    name().data(),init.data(),initLines,maxInitLines,userInitLines);
+  //    name().data(),m_impl->initializer.data(),m_impl->initLines,
+  //    m_impl->maxInitLines,m_impl->userInitLines);
   return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
          ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
 }
@@ -2586,7 +2481,6 @@ bool MemberDef::hasMultiLineInitializer() const
 void MemberDef::setInitializer(const char *initializer)    
 { 
   makeResident();
-  //printf("setInitializer(%s)\n",initializer);
   m_impl->initializer=initializer; 
   int p=m_impl->initializer.length()-1;
   while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
@@ -3955,5 +3849,35 @@ void MemberDef::unlock() const
   }
 }
 
+void MemberDef::copyArgumentNames(MemberDef *bmd)
+{
+  makeResident();
+  {
+    LockingPtr<ArgumentList> arguments = bmd->argumentList();
+    if (m_impl->defArgList && arguments!=0)
+    {
+      ArgumentListIterator aliDst(*m_impl->defArgList);
+      ArgumentListIterator aliSrc(*arguments);
+      Argument *argDst, *argSrc;
+      for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
+      {
+        argDst->name = argSrc->name;
+      }
+    }
+  }
+  {
+    LockingPtr<ArgumentList> arguments = bmd->declArgumentList();
+    if (m_impl->defArgList && arguments!=0)
+    {
+      ArgumentListIterator aliDst(*m_impl->declArgList);
+      ArgumentListIterator aliSrc(*arguments);
+      Argument *argDst, *argSrc;
+      for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
+      {
+        argDst->name = argSrc->name;
+      }
+    }
+  }
+}
 
 
diff --git a/src/memberdef.h b/src/memberdef.h
index f6d1a0b..b313f30 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -310,6 +310,7 @@ class MemberDef : public Definition
     void setMemberDeclaration(MemberDef *md);
         
     void setAnonymousUsed();
+    void copyArgumentNames(MemberDef *bmd);
     
     //-----------------------------------------------------------------------------------
     // --- actions ----
diff --git a/src/membergroup.cpp b/src/membergroup.cpp
index 0c6c050..60ac5d4 100644
--- a/src/membergroup.cpp
+++ b/src/membergroup.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -65,11 +65,12 @@ MemberGroup::~MemberGroup()
 
 void MemberGroup::insertMember(MemberDef *md)
 {
-  //printf("MemberGroup::insertMember memberList=%p count=%d"
+  //printf("MemberGroup::insertMember m_parent=%s memberList=%p count=%d"
   //       " member section list: %p\n",
-  //       memberList->first() ? memberList->first()->getSectionList() : 0,
+  //       m_parent ? m_parent->name().data() : "<null>",
+  //       memberList->first() ? memberList->first()->getSectionList(m_parent) : 0,
   //       memberList->count(),
-  //       md->getSectionList());
+  //       md->getSectionList(m_parent));
   MemberDef *firstMd = memberList->first();
   if (inSameSection && memberList->count()>0 && 
       firstMd->getSectionList(m_parent)!=md->getSectionList(m_parent))
@@ -134,7 +135,8 @@ void MemberGroup::addToDeclarationSection()
 {
   if (inDeclSection)
   {
-    //printf("Adding group %p to list %p (type=%d)\n",this,inDeclSection,inDeclSection->listType());
+    //printf("Adding group %p to list %p (type=%d)\n",this,
+    //                              inDeclSection,inDeclSection->listType());
     inDeclSection->addMemberGroup(this);
   }
 }
diff --git a/src/membergroup.h b/src/membergroup.h
index 4f7cb4c..885341a 100644
--- a/src/membergroup.h
+++ b/src/membergroup.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/memberlist.cpp b/src/memberlist.cpp
index f684cbd..8864488 100644
--- a/src/memberlist.cpp
+++ b/src/memberlist.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/memberlist.h b/src/memberlist.h
index be2e38e..1467835 100644
--- a/src/memberlist.h
+++ b/src/memberlist.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/membername.cpp b/src/membername.cpp
index 5c3fff4..e05e28b 100644
--- a/src/membername.cpp
+++ b/src/membername.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/membername.h b/src/membername.h
index ee227e8..8c71af0 100644
--- a/src/membername.h
+++ b/src/membername.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/message.cpp b/src/message.cpp
index 02bf52d..572542a 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/message.h b/src/message.h
index af9eecc..12af48c 100644
--- a/src/message.h
+++ b/src/message.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index 419ba2c..54278b1 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/namespacedef.h b/src/namespacedef.h
index 098cfee..827ace3 100644
--- a/src/namespacedef.h
+++ b/src/namespacedef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/objcache.cpp b/src/objcache.cpp
index 4c53ade..f45a0e7 100644
--- a/src/objcache.cpp
+++ b/src/objcache.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/objcache.h b/src/objcache.h
index 33dfbfe..3516534 100644
--- a/src/objcache.h
+++ b/src/objcache.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/outputgen.cpp b/src/outputgen.cpp
index 28878f3..4a5c54a 100644
--- a/src/outputgen.cpp
+++ b/src/outputgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/outputgen.h b/src/outputgen.h
index 69390ba..13f2970 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -51,15 +51,17 @@ class CodeOutputInterface
     virtual void codify(const char *s) = 0;
 
     /*! Writes a link to an object in a code fragment.
-     *  \param ref    If this is non-zero, the object is to be found in
-     *                an external documentation file.
-     *  \param file   The file in which the object is located.
-     *  \param anchor The anchor uniquely identifying the object within 
-     *                the file. 
-     *  \param name   The text to display as a placeholder for the link.
+     *  \param ref      If this is non-zero, the object is to be found in
+     *                  an external documentation file.
+     *  \param file     The file in which the object is located.
+     *  \param anchor   The anchor uniquely identifying the object within 
+     *                  the file. 
+     *  \param name     The text to display as a placeholder for the link.
+     *  \param tooltip  The tooltip to display when the mouse is on the link.
      */
     virtual void writeCodeLink(const char *ref,const char *file,
-                               const char *anchor,const char *name) = 0;
+                               const char *anchor,const char *name,
+                               const char *tooltip) = 0;
 
     virtual void writeLineNumber(const char *ref,const char *file,
                                  const char *anchor,int lineNumber) = 0;
diff --git a/src/outputlist.cpp b/src/outputlist.cpp
index 993f321..dac4972 100644
--- a/src/outputlist.cpp
+++ b/src/outputlist.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/outputlist.h b/src/outputlist.h
index 376bb28..6a8c4c8 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -127,8 +127,9 @@ class OutputList : public OutputDocInterface
                          const char *anchor, const char *name)
     { forall(&OutputGenerator::writeObjectLink,ref,file,anchor,name); }
     void writeCodeLink(const char *ref,const char *file,
-                       const char *anchor,const char *name)
-    { forall(&OutputGenerator::writeCodeLink,ref,file,anchor,name); }
+                       const char *anchor,const char *name,
+                       const char *tooltip)
+    { forall(&OutputGenerator::writeCodeLink,ref,file,anchor,name,tooltip); }
     void startTextLink(const char *file,const char *anchor)
     { forall(&OutputGenerator::startTextLink,file,anchor); }
     void endTextLink()
diff --git a/src/pagedef.h b/src/pagedef.h
index 3c7e74e..2d4c59d 100644
--- a/src/pagedef.h
+++ b/src/pagedef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/parserintf.h b/src/parserintf.h
index 57409c0..477958a 100644
--- a/src/parserintf.h
+++ b/src/parserintf.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/pngenc.cpp b/src/pngenc.cpp
index 7251bb3..79a83ac 100644
--- a/src/pngenc.cpp
+++ b/src/pngenc.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/pngenc.h b/src/pngenc.h
index 8d0219c..f32248e 100644
--- a/src/pngenc.h
+++ b/src/pngenc.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/pre.h b/src/pre.h
index dfe772c..5ac13fd 100644
--- a/src/pre.h
+++ b/src/pre.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/pre.l b/src/pre.l
index 5cf277f..b303bf4 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -1714,7 +1714,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 					    BEGIN(Start);
 					  }
   					}
-<EndImport>[^\\]*/\n			{
+<EndImport>[^\\\n]*/\n			{
   					  BEGIN(Start);
   					}
 <EndImport>\\[\r]?"\n"			{ 
diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h
index c02a4f5..fa1ab26 100644
--- a/src/printdocvisitor.h
+++ b/src/printdocvisitor.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/pycode.h b/src/pycode.h
index 326441c..b3007d4 100644
--- a/src/pycode.h
+++ b/src/pycode.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/pycode.l b/src/pycode.l
index 96b805a..348b521 100644
--- a/src/pycode.l
+++ b/src/pycode.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -408,7 +408,8 @@ static void endCodeLine()
  */
 static void writeMultiLineCodeLink(CodeOutputInterface &ol,
                   const char *ref,const char *file,
-                  const char *anchor,const char *text)
+                  const char *anchor,const char *text,
+                  const char *tooltip)
 {
   bool done=FALSE;
   char *p=(char *)text;
@@ -422,7 +423,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol,
       g_yyLineNr++;
       *(p-1)='\0';
       //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
-      ol.writeCodeLink(ref,file,anchor,sp);
+      ol.writeCodeLink(ref,file,anchor,sp,tooltip);
       endCodeLine();
       if (g_yyLineNr<g_inputLines) 
       {
@@ -432,7 +433,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol,
     else
     {
       //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
-      ol.writeCodeLink(ref,file,anchor,sp);
+      ol.writeCodeLink(ref,file,anchor,sp,tooltip);
       done=TRUE;
     }
   }
@@ -529,7 +530,8 @@ static bool getLinkInScope(const QCString &c,  // scope
       writeMultiLineCodeLink(ol,md->getReference(),
 	                        md->getOutputFileBase(),
 	                        md->anchor(),
-				text ? text : memberText);
+				text ? text : memberText,
+                                md->briefDescriptionAsTooltip());
       addToSearchIndex(text ? text : memberText);
       return TRUE;
     } 
@@ -607,7 +609,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
 
   if (cd && cd->isLinkable()) // is it a linkable class
   {
-    writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,clName);
+    writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,clName,cd->briefDescriptionAsTooltip());
     addToSearchIndex(className);
     if (md)
     {
@@ -653,7 +655,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
         //printf("is a global md=%p g_currentDefinition=%s\n",md,g_currentDefinition?g_currentDefinition->name().data():"<none>");
 	if (md->isLinkable())
 	{
-	  writeMultiLineCodeLink(ol,md->getReference(),md->getOutputFileBase(),md->anchor(),clName);
+	  writeMultiLineCodeLink(ol,md->getReference(),md->getOutputFileBase(),md->anchor(),clName,md->briefDescriptionAsTooltip());
           addToSearchIndex(clName);
 	  if (g_currentMemberDef)
 	  {
@@ -740,7 +742,8 @@ static bool findMemberLink(CodeOutputInterface &ol,Definition *sym,const char *s
       writeMultiLineCodeLink(ol,sym->getReference(),
           sym->getOutputFileBase(),
           anchor,
-          symName);
+          symName,
+          sym->briefDescriptionAsTooltip());
       return TRUE;
     }
   }
diff --git a/src/pyscanner.h b/src/pyscanner.h
index a5aa2aa..03dce0b 100644
--- a/src/pyscanner.h
+++ b/src/pyscanner.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/pyscanner.l b/src/pyscanner.l
index 6d33aef..478a5d2 100644
--- a/src/pyscanner.l
+++ b/src/pyscanner.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/qtbc.h b/src/qtbc.h
index 029b84d..b1baec4 100644
--- a/src/qtbc.h
+++ b/src/qtbc.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/reflist.cpp b/src/reflist.cpp
index 2055e33..99d94cd 100644
--- a/src/reflist.cpp
+++ b/src/reflist.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/reflist.h b/src/reflist.h
index 90b60b9..bc2b52f 100644
--- a/src/reflist.h
+++ b/src/reflist.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp
index 356af3c..0d99613 100644
--- a/src/rtfdocvisitor.cpp
+++ b/src/rtfdocvisitor.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -354,9 +354,10 @@ void RTFDocVisitor::visit(DocVerbatim *s)
         static int dotindex = 1;
         QCString fileName(4096);
 
-        fileName.sprintf("%s%d", 
+        fileName.sprintf("%s%d%s", 
             (Config_getString("RTF_OUTPUT")+"/inline_dotgraph_").data(), 
-            dotindex++
+            dotindex++,
+            ".dot"
            );
         QFile file(fileName);
         if (!file.open(IO_WriteOnly))
@@ -368,7 +369,7 @@ void RTFDocVisitor::visit(DocVerbatim *s)
         m_t << "\\par{\\qc "; // center picture
         writeDotFile(fileName);
         m_t << "} ";
-        file.remove();
+        if (Config_getBool("DOT_CLEANUP")) file.remove();
       }
       break;
   }
diff --git a/src/rtfdocvisitor.h b/src/rtfdocvisitor.h
index 57ce53b..5462480 100644
--- a/src/rtfdocvisitor.h
+++ b/src/rtfdocvisitor.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index 51035b7..447cbdb 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Parker Waechter & Dimitri van Heesch.
  *
@@ -1266,7 +1266,8 @@ void RTFGenerator::endPageRef(const char *clname, const char *anchor)
 }
 
 void RTFGenerator::writeCodeLink(const char *ref,const char *f,
-    const char *anchor,const char *name)
+                                 const char *anchor,const char *name,
+                                 const char *)
 {
   if (!ref && Config_getBool("RTF_HYPERLINKS"))
   {
diff --git a/src/rtfgen.h b/src/rtfgen.h
index d1dcd95..8cc8c5c 100644
--- a/src/rtfgen.h
+++ b/src/rtfgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Parker Waechter & Dimitri van Heesch.
  *
@@ -79,7 +79,8 @@ class RTFGenerator : public OutputGenerator
     void writeObjectLink(const char *ref,const char *file,
                          const char *anchor,const char *name);
     void writeCodeLink(const char *ref, const char *file,
-                       const char *anchor,const char *name);
+                       const char *anchor,const char *name,
+                       const char *tooltip);
     void startTextLink(const char *f,const char *anchor);
     void endTextLink();
     void startHtmlLink(const char *url);
diff --git a/src/rtfstyle.cpp b/src/rtfstyle.cpp
index b52b37d..430ed37 100644
--- a/src/rtfstyle.cpp
+++ b/src/rtfstyle.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/rtfstyle.h b/src/rtfstyle.h
index bc1a3bb..6f4af29 100644
--- a/src/rtfstyle.h
+++ b/src/rtfstyle.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/scanner.h b/src/scanner.h
index d0f384b..e82daf8 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/scanner.l b/src/scanner.l
index c0189e3..5d75f5f 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2005 by Dimitri van Heesch.
  *
@@ -2533,6 +2533,16 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
 					    current->mtype = mtype;
 					    BEGIN( IDLAttribute );
 					  }
+                                          else if (insideCS &&
+                                                  current->name.isEmpty())
+                                          {
+                                            squareCount=1;
+                                            lastSquareContext = YY_START;
+                                            // Skip the C# attribute
+                                            // for this member
+                                            current->args.resize(0);
+                                            BEGIN( SkipSquare );
+                                          }
 					  else
 					  {
   					    current->args += yytext ;
@@ -2643,8 +2653,16 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
 					}
 <Sharp>.				{ current->type += *yytext ; }
 <FindFields>{ID}			{
-  					  current->name = yytext;
+  					  current->bodyLine = yyLineNr;
+  					  current->name     = yytext;
 					}
+<FindFields>"("				{
+  					  // Java enum initializer
+  					  unput('(');
+  					  lastInitializerContext = YY_START;
+					  initBracketCount=0;
+  					  BEGIN(ReadInitializer);
+  					}
 <FindFields>"="				{
   					  lastInitializerContext = YY_START;
 					  initBracketCount=0;
@@ -2664,9 +2682,12 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
 					    current->section    = Entry::VARIABLE_SEC;
 					    // add to the scope of the enum
 					    current_root->addSubEntry(current);
-					    current             = new Entry(*current);
-					    // add to the scope surrounding the enum (copy!)
-					    current_root->parent()->addSubEntry(current);
+					    if (!insideCS && !insideJava) // for C# and Java 1.5+ enum values always have to be explicitly qualified
+					    {
+					      current             = new Entry(*current);
+					      // add to the scope surrounding the enum (copy!)
+					      current_root->parent()->addSubEntry(current);
+					    }
 					    current             = new Entry ;
 					    initEntry();
 					  }
@@ -4708,7 +4729,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
   					}
 <DocCopyBlock><<EOF>>			{
   					  warn(yyFileName,yyLineNr,
-					      "Warning: reached end of file while inside a %s block!\n",
+					      "Warning: reached end of file while inside a %s block!\n"
+					      "The command that should end the block seems to be missing!\n",
 					      docBlockName.data());
   					  yyterminate();
   					}
@@ -5223,7 +5245,7 @@ bool CLanguageScanner::needsPreprocessing(const QCString &extension)
 {
   QCString fe=extension.lower();
   return 
-   !( fe==".java" || fe==".as"  || fe==".cs"    || fe==".d"    || fe==".php" || 
+   !( fe==".java" || fe==".as"  || fe==".d"    || fe==".php" || 
       fe==".php4" || fe==".inc" || fe==".phtml" 
     );
 }
diff --git a/src/searchindex.cpp b/src/searchindex.cpp
index 89e8106..2610c52 100644
--- a/src/searchindex.cpp
+++ b/src/searchindex.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/searchindex.h b/src/searchindex.h
index 5293b94..e5c9387 100644
--- a/src/searchindex.h
+++ b/src/searchindex.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/section.h b/src/section.h
index ae79b2e..70dd5e1 100644
--- a/src/section.h
+++ b/src/section.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/sortdict.h b/src/sortdict.h
index 4a423c3..07c450a 100644
--- a/src/sortdict.h
+++ b/src/sortdict.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/store.cpp b/src/store.cpp
index f1f24cd..5e6e8f7 100644
--- a/src/store.cpp
+++ b/src/store.cpp
@@ -1,3 +1,21 @@
+/******************************************************************************
+ *
+ * 
+ *
+ *
+ * Copyright (C) 1997-2006 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby 
+ * granted. No representations are made about the suitability of this software 
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
 #include "store.h"
 
 
diff --git a/src/store.h b/src/store.h
index eda055e..3fc3ac0 100644
--- a/src/store.h
+++ b/src/store.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/tagreader.cpp b/src/tagreader.cpp
index 7c807f3..8fd61a8 100644
--- a/src/tagreader.cpp
+++ b/src/tagreader.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/tagreader.h b/src/tagreader.h
index b8d89db..d52b3df 100644
--- a/src/tagreader.h
+++ b/src/tagreader.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/textdocvisitor.cpp b/src/textdocvisitor.cpp
new file mode 100644
index 0000000..a2c722b
--- /dev/null
+++ b/src/textdocvisitor.cpp
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * 
+ *
+ *
+ * Copyright (C) 1997-2006 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby 
+ * granted. No representations are made about the suitability of this software 
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qdir.h>
+#include "textdocvisitor.h"
+#include "message.h"
+
+//-------------------------------------------------------------------------
+
+void TextDocVisitor::visit(DocSymbol *s)
+{
+  switch(s->symbol())
+  {
+    case DocSymbol::BSlash:  m_t << "\\"; break;
+    case DocSymbol::At:      m_t << "@"; break;
+    case DocSymbol::Less:    m_t << "&lt;"; break;
+    case DocSymbol::Greater: m_t << "&gt;"; break;
+    case DocSymbol::Amp:     m_t << "&amp;"; break;
+    case DocSymbol::Dollar:  m_t << "$"; break;
+    case DocSymbol::Hash:    m_t << "#"; break;
+    case DocSymbol::Percent: m_t << "%"; break;
+    case DocSymbol::Copy:    m_t << "&copy;"; break;
+    case DocSymbol::Tm:      m_t << "&tm;"; break;
+    case DocSymbol::Reg:     m_t << "&reg;"; break;
+    case DocSymbol::Apos:    m_t << "'"; break;
+    case DocSymbol::Quot:    m_t << "\""; break;
+    case DocSymbol::Lsquo:   m_t << "&lsquo;"; break;
+    case DocSymbol::Rsquo:   m_t << "&rsquo;"; break;
+    case DocSymbol::Ldquo:   m_t << "&ldquo;"; break;
+    case DocSymbol::Rdquo:   m_t << "&rdquo;"; break;
+    case DocSymbol::Ndash:   m_t << "&ndash;"; break;
+    case DocSymbol::Mdash:   m_t << "&mdash;"; break;
+    case DocSymbol::Uml:     m_t << "&" << s->letter() << "uml;"; break;
+    case DocSymbol::Acute:   m_t << "&" << s->letter() << "acute;"; break;
+    case DocSymbol::Grave:   m_t << "&" << s->letter() << "grave;"; break;
+    case DocSymbol::Circ:    m_t << "&" << s->letter() << "circ;"; break;
+    case DocSymbol::Slash:   m_t << "&" << s->letter() << "slash;"; break;
+    case DocSymbol::Tilde:   m_t << "&" << s->letter() << "tilde;"; break;
+    case DocSymbol::Szlig:   m_t << "&szlig;"; break;
+    case DocSymbol::Cedil:   m_t << "&" << s->letter() << "cedil;"; break;
+    case DocSymbol::Ring:    m_t << "&" << s->letter() << "ring;"; break;
+    case DocSymbol::Nbsp:    m_t << "&nbsp;"; break;
+    default:
+                             err("Error: unknown symbol found\n");
+  }
+}
+
+
+void TextDocVisitor::filter(const char *str)
+{ 
+  if (str==0) return;
+  const char *p=str;
+  char c;
+  while (*p)
+  {
+    c=*p++;
+    switch(c)
+    {
+      case '\n': m_t << " "; break;
+      default:   m_t << c;
+    }
+  }
+}
+
diff --git a/src/textdocvisitor.h b/src/textdocvisitor.h
new file mode 100644
index 0000000..3fcf96a
--- /dev/null
+++ b/src/textdocvisitor.h
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ * 
+ *
+ *
+ * Copyright (C) 1997-2006 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby 
+ * granted. No representations are made about the suitability of this software 
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef _TEXTDOCVISITOR_H
+#define _TEXTDOCVISITOR_H
+
+#include "docvisitor.h"
+#include "docparser.h"
+#include <qstack.h>
+#include <qcstring.h>
+#include <qtextstream.h>
+
+
+/*! @brief Concrete visitor implementation for TEXT output. */
+class TextDocVisitor : public DocVisitor
+{
+  public:
+    TextDocVisitor(QTextStream &t) : DocVisitor(DocVisitor_Text), m_t(t) {}
+    
+    //--------------------------------------
+    // visitor functions for leaf nodes
+    //--------------------------------------
+    
+    void visit(DocWord *w)        { m_t << w->word(); }
+    void visit(DocLinkedWord *w)  { m_t << w->word(); }
+    void visit(DocWhiteSpace *)   { m_t << " ";       }
+    void visit(DocSymbol *);
+    void visit(DocURL *u)         { m_t << u->url();  }
+    void visit(DocLineBreak *)    { m_t << " ";       }
+    void visit(DocHorRuler *)     {}
+    void visit(DocStyleChange *)  {}
+    void visit(DocVerbatim *s)    { filter(s->text()); }
+    void visit(DocAnchor *)       {}
+    void visit(DocInclude *)      {}
+    void visit(DocIncOperator *)  {}
+    void visit(DocFormula *)      {}
+    void visit(DocIndexEntry *)   {}
+
+    //--------------------------------------
+    // visitor functions for compound nodes
+    //--------------------------------------
+    
+    void visitPre(DocAutoList *) {}
+    void visitPost(DocAutoList *) {}
+    void visitPre(DocAutoListItem *) {}
+    void visitPost(DocAutoListItem *) {}
+    void visitPre(DocPara *)  {}
+    void visitPost(DocPara *) {}
+    void visitPre(DocRoot *) {}
+    void visitPost(DocRoot *) {}
+    void visitPre(DocSimpleSect *) {}
+    void visitPost(DocSimpleSect *) {}
+    void visitPre(DocTitle *) {}
+    void visitPost(DocTitle *) {}
+    void visitPre(DocSimpleList *) {}
+    void visitPost(DocSimpleList *) {}
+    void visitPre(DocSimpleListItem *) {}
+    void visitPost(DocSimpleListItem *) {}
+    void visitPre(DocSection *) {}
+    void visitPost(DocSection *) {}
+    void visitPre(DocHtmlList *) {}
+    void visitPost(DocHtmlList *)  {}
+    void visitPre(DocHtmlListItem *) {}
+    void visitPost(DocHtmlListItem *) {}
+    void visitPre(DocHtmlDescList *) {}
+    void visitPost(DocHtmlDescList *) {}
+    void visitPre(DocHtmlDescTitle *) {}
+    void visitPost(DocHtmlDescTitle *) {}
+    void visitPre(DocHtmlDescData *) {}
+    void visitPost(DocHtmlDescData *) {}
+    void visitPre(DocHtmlTable *) {}
+    void visitPost(DocHtmlTable *) {}
+    void visitPre(DocHtmlRow *) {}
+    void visitPost(DocHtmlRow *)  {}
+    void visitPre(DocHtmlCell *) {}
+    void visitPost(DocHtmlCell *) {}
+    void visitPre(DocHtmlCaption *) {}
+    void visitPost(DocHtmlCaption *) {}
+    void visitPre(DocInternal *) {}
+    void visitPost(DocInternal *) {}
+    void visitPre(DocHRef *) {}
+    void visitPost(DocHRef *) {}
+    void visitPre(DocHtmlHeader *) {}
+    void visitPost(DocHtmlHeader *) {}
+    void visitPre(DocImage *) {}
+    void visitPost(DocImage *) {}
+    void visitPre(DocDotFile *) {}
+    void visitPost(DocDotFile *) {}
+    void visitPre(DocLink *) {}
+    void visitPost(DocLink *) {}
+    void visitPre(DocRef *) {}
+    void visitPost(DocRef *) {}
+    void visitPre(DocSecRefItem *) {}
+    void visitPost(DocSecRefItem *) {}
+    void visitPre(DocSecRefList *) {}
+    void visitPost(DocSecRefList *) {}
+    void visitPre(DocParamSect *) {}
+    void visitPost(DocParamSect *) {}
+    void visitPre(DocParamList *) {}
+    void visitPost(DocParamList *) {}
+    void visitPre(DocXRefItem *) {}
+    void visitPost(DocXRefItem *) {}
+    void visitPre(DocInternalRef *) {}
+    void visitPost(DocInternalRef *) {}
+    void visitPre(DocCopy *) {}
+    void visitPost(DocCopy *) {}
+    void visitPre(DocText *) {}
+    void visitPost(DocText *) {}
+
+  private:
+
+   void filter(const char *str);
+
+    QTextStream &m_t;
+};
+
+#endif
diff --git a/src/translator_adapter.h b/src/translator_adapter.h
index e3a1119..631da7b 100644
--- a/src/translator_adapter.h
+++ b/src/translator_adapter.h
@@ -155,49 +155,6 @@ class TranslatorAdapter_1_2_18 : public TranslatorAdapter_1_3
     { return english.trEventDocumentation(); }
 };
 
-class TranslatorAdapter_1_2_17 : public TranslatorAdapter_1_2_18
-{
-  public:
-    virtual QCString updateNeededMessage() 
-    { return createUpdateNeededMessage(idLanguage(),"release 1.2.17"); }
-
-    virtual QCString trDeprecatedList()
-    { return english.trDeprecatedList(); }
-};
-
-class TranslatorAdapter_1_2_16 : public TranslatorAdapter_1_2_17
-{
-  public:
-    virtual QCString updateNeededMessage() 
-    { return createUpdateNeededMessage(idLanguage(),"release 1.2.16"); }
-
-    virtual QCString trRTFTableOfContents()
-    { return english.trRTFTableOfContents(); }
-};
-
-class TranslatorAdapter_1_2_13 : public TranslatorAdapter_1_2_16
-{
-  public:
-    virtual QCString updateNeededMessage() 
-    { return createUpdateNeededMessage(idLanguage(),"release 1.2.13"); }
-
-    virtual QCString trImplementedFromList(int numEntries) 
-    { return english.trImplementedFromList(numEntries); }
-
-    virtual QCString trImplementedInList(int numEntries) 
-    { return english.trImplementedInList(numEntries); }
-};
-
-class TranslatorAdapter_1_2_11 : public TranslatorAdapter_1_2_13
-{
-  public:
-    virtual QCString updateNeededMessage() 
-    { return createUpdateNeededMessage(idLanguage(),"release 1.2.11"); }
-   
-    virtual QCString trReferences()
-    { return english.trReferences(); }
-    
-};
 
 #endif
 
diff --git a/src/translator_jp.h b/src/translator_jp.h
index 01aec89..8e84750 100644
--- a/src/translator_jp.h
+++ b/src/translator_jp.h
@@ -655,7 +655,12 @@ class TranslatorJapanese : public Translator
                                    // (order is left to right)
 
         if (i!=numEntries-1)  // not the last entry, so we need a separator
-	  result+=decode("��");
+        {
+          if (i<numEntries-2) // not the fore last entry
+            result+=decode(", ");
+          else                // the fore last entry
+            result+=decode(", �� ");
+        }
       }
       return result;
     }
diff --git a/src/translator_nl.h b/src/translator_nl.h
index 42d48e6..fb24e83 100644
--- a/src/translator_nl.h
+++ b/src/translator_nl.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/translator_pt.h b/src/translator_pt.h
index 711fa52..e53efdd 100644
--- a/src/translator_pt.h
+++ b/src/translator_pt.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/translator_ro.h b/src/translator_ro.h
index a2ca363..fe12908 100644
--- a/src/translator_ro.h
+++ b/src/translator_ro.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/translator_si.h b/src/translator_si.h
index 8bb16cc..005ffc7 100644
--- a/src/translator_si.h
+++ b/src/translator_si.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/util.cpp b/src/util.cpp
index dac8532..553cfec 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -48,6 +48,7 @@
 #include "debug.h"
 #include "searchindex.h"
 #include "doxygen.h"
+#include "textdocvisitor.h"
 
 #if !defined(_WIN32) || defined(__CYGWIN__)
 #include <unistd.h>
@@ -205,7 +206,14 @@ int iSystem(const char *command,const char *args,bool commandHasConsole)
     else
     {
       Doxygen::sysElapsedTime+=((double)time.elapsed())/1000.0;
-      return status;
+      if (WIFEXITED(status))
+      {
+        return WEXITSTATUS(status);
+      }
+      else
+      {
+        return status;
+      }
     }
   }
 #endif // _OS_SOLARIS
@@ -1656,8 +1664,8 @@ nextChar:
       result+=" :";
       vsp=0;
     }
-    else if (!isspace((uchar)c) ||
-        ( i>0 && i<l-1 && 
+    else if (!isspace((uchar)c) || // not a space
+        ( i>0 && i<l-1 &&          // internal character
           (isId(s.at(i-1)) || s.at(i-1)==')' || s.at(i-1)==',' || s.at(i-1)=='>' || s.at(i-1)==']')
           && (isId(s.at(i+1)) || (i<l-2 && s.at(i+1)=='$' && isId(s.at(i+2)))
             || (i<l-3 && s.at(i+1)=='&' && s.at(i+2)=='$' && isId(s.at(i+3))))
@@ -3901,7 +3909,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
  *   - if `cd' is non zero, the scope was a class pointed to by cd.
  *   - if `nd' is non zero, the scope was a namespace pointed to by nd.
  */
-bool getScopeDefs(const char *docScope,const char *scope,
+static bool getScopeDefs(const char *docScope,const char *scope,
     ClassDef *&cd, NamespaceDef *&nd)
 {
   cd=0;nd=0;
@@ -3946,14 +3954,14 @@ bool getScopeDefs(const char *docScope,const char *scope,
   return FALSE;
 }
 
-static bool isLowerCase(QCString &s)
-{
-  char *p=s.data();
-  if (p==0) return TRUE;
-  int c;
-  while ((c=*p++)) if (!islower(c)) return FALSE;
-  return TRUE; 
-}
+//static bool isLowerCase(QCString &s)
+//{
+//  char *p=s.data();
+//  if (p==0) return TRUE;
+//  int c;
+//  while ((c=*p++)) if (!islower(c)) return FALSE;
+//  return TRUE; 
+//}
 
 
 
@@ -3967,8 +3975,6 @@ bool resolveRef(/* in */  const char *scName,
     /* out */ MemberDef  **resMember
     )
 {
-  //printf("resolveRef(scName=%s,name=%s,inSeeBlock=%d)\n",scName,name,inSeeBlock);
-
   QCString tsName = name;
   bool memberScopeFirst = tsName.find('#')!=-1;
   QCString fullName = substitute(tsName,"#","::");
@@ -3987,10 +3993,10 @@ bool resolveRef(/* in */  const char *scName,
     ClassDef *cd=0;
     NamespaceDef *nd=0;
 
-    if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
-    { // link to lower case only name => do not try to autolink 
-      return FALSE;
-    }
+    //if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
+    //{ // link to lower case only name => do not try to autolink 
+    //  return FALSE;
+    //}
 
     //printf("scName=%s fullName=%s\n",scName,fullName.data());
 
@@ -6024,6 +6030,7 @@ SrcLangExt getLanguageFromFileName(const QCString fileName)
     extLookup.insert(".idl",   (void*)SrcLangExt_IDL);
     extLookup.insert(".odl",   (void*)SrcLangExt_IDL);
     extLookup.insert(".java",  (void*)SrcLangExt_Java);
+    extLookup.insert(".jsl",   (void*)SrcLangExt_Java);
     extLookup.insert(".as",    (void*)SrcLangExt_Java);
     extLookup.insert(".cs",    (void*)SrcLangExt_CSharp);
     extLookup.insert(".d",     (void*)SrcLangExt_D);
@@ -6121,3 +6128,31 @@ bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n)
   else
     return FALSE;
 }
+
+QCString parseCommentAsText(const QString &doc,const QCString &fileName,int lineNr)
+{
+  QString result;
+  QTextStream t(&result,IO_WriteOnly);
+  DocNode *root = validatingParseDoc(fileName,lineNr,Doxygen::globalScope,0,doc,FALSE,FALSE);
+  TextDocVisitor *visitor = new TextDocVisitor(t);
+  root->accept(visitor);
+  delete visitor;
+  delete root;
+  int i=0;
+  if (result.length()>80)
+  {
+    for (i=80;i<100;i++) // search for nice truncation point
+    {
+      if (result.at(i).isSpace() || 
+          result.at(i)==',' || 
+          result.at(i)=='.' || 
+          result.at(i)=='?')
+      {
+        break;
+      }
+    }
+  }
+  if (i>0) result=result.left(i)+"...";
+  return result.data();
+}
+
diff --git a/src/util.h b/src/util.h
index 0253813..d0ac3af 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
@@ -332,6 +332,7 @@ ClassDef *newResolveTypedef(FileDef *fileScope,MemberDef *md,
                             MemberDef **pMemType=0,QCString *pTemplSpec=0,
                             QCString *pResolvedType=0);
 
+QCString parseCommentAsText(const QString &doc,const QCString &fileName,int lineNr);
 
 #endif
 
diff --git a/src/version.h b/src/version.h
index b86bb2e..226de7e 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp
index 514d681..d9b63a3 100644
--- a/src/xmldocvisitor.cpp
+++ b/src/xmldocvisitor.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/xmldocvisitor.h b/src/xmldocvisitor.h
index dcb879f..c347e0e 100644
--- a/src/xmldocvisitor.h
+++ b/src/xmldocvisitor.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 5d0763c..3d0788e 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
@@ -182,7 +182,7 @@ static void writeCombineScript()
 }
 
 void writeXMLLink(QTextStream &t,const char *extRef,const char *compoundId,
-                  const char *anchorId,const char *text)
+                  const char *anchorId,const char *text,const char *tooltip)
 {
   t << "<ref refid=\"" << compoundId;
   if (anchorId) t << "_1" << anchorId;
@@ -190,6 +190,7 @@ void writeXMLLink(QTextStream &t,const char *extRef,const char *compoundId,
   if (anchorId) t << "member"; else t << "compound"; 
   t << "\"";
   if (extRef) t << " external=\"" << extRef << "\"";
+  if (tooltip) t << " tooltip=\"" << tooltip << "\"";
   t << ">";
   writeXMLString(t,text);
   t << "</ref>";
@@ -208,7 +209,7 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf
                    const char *anchor,const char *text
                   ) const
     {
-      writeXMLLink(m_t,extRef,file,anchor,text);
+      writeXMLLink(m_t,extRef,file,anchor,text,0);
     }
   private:
     QTextStream &m_t;
@@ -288,7 +289,8 @@ class XMLCodeGenerator : public CodeOutputInterface
       writeXMLCodeString(m_t,text,col);
     }
     void writeCodeLink(const char *ref,const char *file,
-                               const char *anchor,const char *name) 
+                       const char *anchor,const char *name,
+                       const char *tooltip) 
     {
       XML_DB(("(writeCodeLink)\n"));
       if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
@@ -296,7 +298,7 @@ class XMLCodeGenerator : public CodeOutputInterface
         m_t << "<highlight class=\"normal\">";
         m_normalHLNeedStartTag=FALSE;
       }
-      writeXMLLink(m_t,ref,file,anchor,name);
+      writeXMLLink(m_t,ref,file,anchor,name,tooltip);
       col+=strlen(name);
     }
     void startCodeLine() 
@@ -1345,16 +1347,14 @@ static void generateXMLForClass(ClassDef *cd,QTextStream &ti)
   t << "    <detaileddescription>" << endl;
   writeXMLDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
   t << "    </detaileddescription>" << endl;
-  DotClassGraph inheritanceGraph(cd,DotNode::Inheritance,
-                                 Config_getInt("MAX_DOT_GRAPH_DEPTH"));
+  DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
   if (!inheritanceGraph.isTrivial())
   {
     t << "    <inheritancegraph>" << endl;
     inheritanceGraph.writeXML(t);
     t << "    </inheritancegraph>" << endl;
   }
-  DotClassGraph collaborationGraph(cd,DotNode::Collaboration,
-                                 Config_getInt("MAX_DOT_GRAPH_DEPTH"));
+  DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
   if (!collaborationGraph.isTrivial())
   {
     t << "    <collaborationgraph>" << endl;
@@ -1538,7 +1538,7 @@ static void generateXMLForFile(FileDef *fd,QTextStream &ti)
     }
   }
 
-  DotInclDepGraph incDepGraph(fd,Config_getInt("MAX_DOT_GRAPH_DEPTH"),FALSE);
+  DotInclDepGraph incDepGraph(fd,FALSE);
   if (!incDepGraph.isTrivial())
   {
     t << "    <incdepgraph>" << endl;
@@ -1546,7 +1546,7 @@ static void generateXMLForFile(FileDef *fd,QTextStream &ti)
     t << "    </incdepgraph>" << endl;
   }
 
-  DotInclDepGraph invIncDepGraph(fd,Config_getInt("MAX_DOT_GRAPH_DEPTH"),TRUE);
+  DotInclDepGraph invIncDepGraph(fd,TRUE);
   if (!invIncDepGraph.isTrivial())
   {
     t << "    <invincdepgraph>" << endl;
diff --git a/src/xmlgen.h b/src/xmlgen.h
index c714903..5193b76 100644
--- a/src/xmlgen.h
+++ b/src/xmlgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2006 by Dimitri van Heesch.
  *
-- 
cgit v0.12