From 704253e04cc098b9cbc52ffbc82ef3de23b349e7 Mon Sep 17 00:00:00 2001
From: dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>
Date: Sun, 26 Mar 2000 18:52:22 +0000
Subject: Release-1.1.1-20000326

---
 INSTALL                   |   8 +-
 README                    |   4 +-
 VERSION                   |   2 +-
 doc/Doxyfile              |   2 +-
 doc/Makefile.in           |   2 +-
 doc/Makefile.latex        |   2 +-
 doc/Makefile.win.in       |   2 +-
 doc/autolink.doc          |   2 +-
 doc/commands.doc          |   2 +-
 doc/config.doc            |   2 +-
 doc/doxygen.sty           |   2 +-
 doc/doxygen_manual.tex    |   2 +-
 doc/doxygen_usage.doc     |   2 +-
 doc/doxysearch_usage.doc  |   2 +-
 doc/doxytag_usage.doc     |   2 +-
 doc/faq.doc               |  13 +-
 doc/features.doc          |   2 +-
 doc/history.doc           |   2 +-
 doc/htmlcmds.doc          |   2 +-
 doc/index.doc             |   2 +-
 doc/install.doc           |   2 +-
 doc/installdox_usage.doc  |   2 +-
 doc/language.doc          |   2 +-
 doc/output.doc            |   2 +-
 doc/starting.doc          |   2 +-
 doc/todo.doc              |   2 +-
 doc/trouble.doc           |   2 +-
 packages/rpm/doxygen.spec |   2 +-
 src/Makefile.in           |   2 +-
 src/classdef.cpp          | 234 +++++++++---
 src/classdef.h            |  32 +-
 src/classlist.cpp         |   2 +-
 src/classlist.h           |   2 +-
 src/code.h                |   2 +-
 src/code.l                |   2 +-
 src/config.h              |   2 +-
 src/config.l              |   7 +-
 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            |   4 +-
 src/defargs.h             |   2 +-
 src/defargs.l             |   2 +-
 src/define.cpp            |   2 +-
 src/define.h              |   2 +-
 src/definition.cpp        |  10 +-
 src/definition.h          |   2 +-
 src/diagram.cpp           |   2 +-
 src/diagram.h             |   2 +-
 src/dot.cpp               |  20 +-
 src/dot.h                 |   2 +-
 src/doxygen.cpp           | 192 +++++++---
 src/doxygen.h             |   8 +-
 src/doxygen.pro.in        |   2 +-
 src/doxygen.t             |   2 +-
 src/doxysearch.cpp        |   2 +-
 src/doxysearch.pro.in     |   2 +-
 src/doxytag.l             |   2 +-
 src/doxytag.pro.in        |   2 +-
 src/doxytag.t             |   2 +-
 src/entry.cpp             |   2 +-
 src/entry.h               |   5 +-
 src/example.h             |   2 +-
 src/filedef.cpp           |  56 ++-
 src/filedef.h             |  14 +-
 src/filename.cpp          |   2 +-
 src/filename.h            |   2 +-
 src/formula.cpp           |   2 +-
 src/formula.h             |   2 +-
 src/gifenc.cpp            |   2 +-
 src/gifenc.h              |   2 +-
 src/groupdef.cpp          |  50 ++-
 src/groupdef.h            |  12 +-
 src/htmlgen.cpp           | 102 +++---
 src/htmlgen.h             |  10 +-
 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.cpp          |   2 +-
 src/language.h            |   2 +-
 src/latexgen.cpp          |   6 +-
 src/latexgen.h            |  10 +-
 src/logos.cpp             |   2 +-
 src/logos.h               |   2 +-
 src/mangen.cpp            |   6 +-
 src/mangen.h              |  10 +-
 src/memberdef.cpp         | 182 +++++----
 src/memberdef.h           |  17 +-
 src/membergroup.cpp       | 238 ++----------
 src/membergroup.h         |  41 ++-
 src/memberlist.cpp        | 156 ++++----
 src/memberlist.h          |   6 +-
 src/membername.cpp        |   2 +-
 src/membername.h          |   2 +-
 src/message.cpp           |   2 +-
 src/message.h             |   2 +-
 src/namespacedef.cpp      |  52 ++-
 src/namespacedef.h        |  11 +-
 src/outputgen.cpp         |   2 +-
 src/outputgen.h           |  10 +-
 src/outputlist.cpp        |   3 +-
 src/outputlist.h          |  19 +-
 src/pre.h                 |   2 +-
 src/pre.l                 |   4 +-
 src/qtbc.h                |   2 +-
 src/rtfgen.cpp            |  21 +-
 src/rtfgen.h              |  10 +-
 src/scanner.h             |   7 +-
 src/scanner.l             | 176 ++++++---
 src/searchindex.cpp       |   2 +-
 src/searchindex.h         |   2 +-
 src/section.h             |   2 +-
 src/suffixtree.cpp        |   2 +-
 src/suffixtree.h          |   2 +-
 src/tag.h                 |   2 +-
 src/tag.l                 |   8 +-
 src/translator.h          |  17 +-
 src/translator_cz.h       |   2 +-
 src/translator_de.h       | 216 ++++++++++-
 src/translator_es.h       | 914 ++++++++++++++++++++++++++++++++++------------
 src/translator_fi.h       |   2 +-
 src/translator_fr.h       |  46 +--
 src/translator_it.h       |   2 +-
 src/translator_jp.h       |   2 +-
 src/translator_nl.h       |  56 ++-
 src/translator_ru.h       |   2 +-
 src/translator_se.h       |   2 +-
 src/util.cpp              |  71 +++-
 src/util.h                |   7 +-
 src/version.h             |   2 +-
 140 files changed, 2146 insertions(+), 1143 deletions(-)

diff --git a/INSTALL b/INSTALL
index 29d0245..766e33e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.1.1-20000319
+DOXYGEN Version 1.1.1-20000326
 
 CONTENTS
 --------
@@ -15,8 +15,8 @@ INSTALLATION INSTRUCTIONS FOR UNIX:
 
 1.  Unpack the archive, unless you already have:
    
-     gunzip doxygen-1.1.1-20000319.src.tar.gz    # uncompress the archive
-     tar xf doxygen-1.1.1-20000319.src.tar       # unpack it
+     gunzip doxygen-1.1.1-20000326.src.tar.gz    # uncompress the archive
+     tar xf doxygen-1.1.1-20000326.src.tar       # unpack it
 
 2.  Run the configure script:
  
@@ -252,4 +252,4 @@ The latest version of doxygen can be obtained at
 
 Enjoy,
 
-Dimitri van Heesch (19 March 2000)
+Dimitri van Heesch (26 March 2000)
diff --git a/README b/README
index 340b137..0bde18b 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.1.1-20000319
+DOXYGEN Version 1.1.1-20000326
 
 Please read INSTALL for compilation instructions.
 
@@ -7,4 +7,4 @@ The latest version of doxygen can be obtained at
 
 Enjoy,
 
-Dimitri van Heesch (19 March 2000)
+Dimitri van Heesch (26 March 2000)
diff --git a/VERSION b/VERSION
index bd15d09..37331ef 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.1.1-20000319
+1.1.1-20000326
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 3c3e114..292db32 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-1999 by Dimitri van Heesch.
 #
diff --git a/doc/Makefile.in b/doc/Makefile.in
index c6308bf..fe1d9d2 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2000 by Dimitri van Heesch.
 #
diff --git a/doc/Makefile.latex b/doc/Makefile.latex
index b4e4379..3c31b09 100644
--- a/doc/Makefile.latex
+++ b/doc/Makefile.latex
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2000 by Dimitri van Heesch.
 #
diff --git a/doc/Makefile.win.in b/doc/Makefile.win.in
index e151ecc..c9611eb 100644
--- a/doc/Makefile.win.in
+++ b/doc/Makefile.win.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2000 by Dimitri van Heesch.
 #
diff --git a/doc/autolink.doc b/doc/autolink.doc
index 4cb892b..930e95b 100644
--- a/doc/autolink.doc
+++ b/doc/autolink.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/commands.doc b/doc/commands.doc
index 497e26d..cdbd4a5 100644
--- a/doc/commands.doc
+++ b/doc/commands.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/config.doc b/doc/config.doc
index 906c86e..bfbd062 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/doxygen.sty b/doc/doxygen.sty
index e38ddc8..c0769ec 100644
--- a/doc/doxygen.sty
+++ b/doc/doxygen.sty
@@ -1,5 +1,5 @@
 %
-% $Id$
+% 
 %
 % Copyright (C) 1997-2000 by Dimitri van Heesch.
 %
diff --git a/doc/doxygen_manual.tex b/doc/doxygen_manual.tex
index f256d06..bce9b76 100644
--- a/doc/doxygen_manual.tex
+++ b/doc/doxygen_manual.tex
@@ -1,5 +1,5 @@
 %
-% $Id$
+% 
 %
 % Copyright (C) 1997-2000 by Dimitri van Heesch.
 %
diff --git a/doc/doxygen_usage.doc b/doc/doxygen_usage.doc
index 47e7431..12baef5 100644
--- a/doc/doxygen_usage.doc
+++ b/doc/doxygen_usage.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/doxysearch_usage.doc b/doc/doxysearch_usage.doc
index 79a418e..1aadceb 100644
--- a/doc/doxysearch_usage.doc
+++ b/doc/doxysearch_usage.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/doxytag_usage.doc b/doc/doxytag_usage.doc
index 0a4de9c..d90611e 100644
--- a/doc/doxytag_usage.doc
+++ b/doc/doxytag_usage.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/faq.doc b/doc/faq.doc
index 28fd574..0dae9e5 100644
--- a/doc/faq.doc
+++ b/doc/faq.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -34,6 +34,17 @@ You should use the \\mainpage command inside a comment block like this:
  */
 \endverbatim
 
+<li><b>When I set EXTRACT_ALL to NO non of my function are shown in the documentation.</b></li>
+
+In order for global functions, variables, enums, typedefs, and defines 
+to be documented you should document the file in which these commands are
+located using a (non-empty) comment block containing a \file (or @file) 
+command. 
+
+Alternatively, you can put all members in a group (or module)
+using the \ingroup command and then document the group using a comment
+block containing the \defgroup command.
+ 
 <li><b>How can I avoid that some code fragment is parsed by Doxyen?</b>
 <p>
 You can use Doxygen's preprocessor for this: 
diff --git a/doc/features.doc b/doc/features.doc
index 1984e68..8363174 100644
--- a/doc/features.doc
+++ b/doc/features.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/history.doc b/doc/history.doc
index c0b2305..9092b97 100644
--- a/doc/history.doc
+++ b/doc/history.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/htmlcmds.doc b/doc/htmlcmds.doc
index e539d7e..8b8b1c3 100644
--- a/doc/htmlcmds.doc
+++ b/doc/htmlcmds.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/index.doc b/doc/index.doc
index a28efec..b47ab4a 100644
--- a/doc/index.doc
+++ b/doc/index.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/install.doc b/doc/install.doc
index 6617900..9fc0fef 100644
--- a/doc/install.doc
+++ b/doc/install.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/installdox_usage.doc b/doc/installdox_usage.doc
index 1689602..b3ea7d8 100644
--- a/doc/installdox_usage.doc
+++ b/doc/installdox_usage.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/language.doc b/doc/language.doc
index b3ec52a..4842b68 100644
--- a/doc/language.doc
+++ b/doc/language.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/output.doc b/doc/output.doc
index 2a8f890..6dee1fc 100644
--- a/doc/output.doc
+++ b/doc/output.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/starting.doc b/doc/starting.doc
index 96a2fc1..07dc47b 100644
--- a/doc/starting.doc
+++ b/doc/starting.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/todo.doc b/doc/todo.doc
index faca7cd..c58358f 100644
--- a/doc/todo.doc
+++ b/doc/todo.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/doc/trouble.doc b/doc/trouble.doc
index b8f742b..b8e95f1 100644
--- a/doc/trouble.doc
+++ b/doc/trouble.doc
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index 2bf6c74..50f033e 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,5 +1,5 @@
 Name: doxygen
-Version: 1.1.1-20000319
+Version: 1.1.1-20000326
 Summary: documentation system for C, C++ and IDL
 Release: 1
 Source0: doxygen-%{version}.src.tar.gz
diff --git a/src/Makefile.in b/src/Makefile.in
index 24de130..4792667 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,6 +1,6 @@
 
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2000 by Dimitri van Heesch.
 # 
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 4c43d61..55cc8a0 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -79,7 +79,9 @@ ClassDef::ClassDef(const char *nm,CompoundType ct,const char *ref,const char *fN
   fileDef=0;
   usesImplClassDict=0;
   usesIntfClassDict=0;
-  //printf("*** New class `%s' *** \n",nm);
+  memberGroupList = new MemberGroupList;
+  memberGroupList->setAutoDelete(TRUE);
+  memberGroupDict = new MemberGroupDict(257);
 }
 
 // destroy the class definition
@@ -94,6 +96,8 @@ ClassDef::~ClassDef()
   delete usesImplClassDict;
   delete usesIntfClassDict;
   delete incInfo;
+  delete memberGroupList;
+  delete memberGroupDict;
 }
 
 // inserts a base class in the inheritance list
@@ -112,27 +116,48 @@ void ClassDef::insertSuperClass(ClassDef *cd,Protection p,
   inheritedBy->inSort(new BaseClassDef(cd,p,s,t));
 }
 
+void ClassDef::addMemberToGroup(MemberDef *md,int groupId)
+{
+  if (groupId!=-1)
+  {
+    QCString *pGrpHeader = memberHeaderDict[groupId];
+    QCString *pDocs      = memberDocDict[groupId];
+    if (pGrpHeader)
+    {
+      MemberGroup *mg = memberGroupDict->find(groupId);
+      if (mg==0)
+      {
+        mg = new MemberGroup(groupId,*pGrpHeader,pDocs ? pDocs->data() : 0);
+        memberGroupDict->insert(groupId,mg);
+        memberGroupList->append(mg);
+      }
+      mg->insertMember(md);
+      md->setMemberGroup(mg);
+    }
+  }
+}
+
 // adds new member definition to the class
-void ClassDef::insertMember(const MemberDef *md)
+void ClassDef::insertMember(MemberDef *md,int groupId)
 {
-  //printf("adding %s::%s\n",name(),md->name());
+  //printf("adding %s::%s\n",name().data(),md->name().data());
   if (!isReference())
   {
+    /*************************************************/
+    /* insert member in the appropriate member group */
+    /*************************************************/
+    addMemberToGroup(md,groupId);
+    
+    /********************************************/
+    /* insert member in the declaration section */
+    /********************************************/
     if (md->isRelated() && (Config::extractPrivateFlag || md->protection()!=Private))
     {
       related.append(md);
-      if (Config::sortMembersFlag)
-        relatedMembers.inSort(md);
-      else
-        relatedMembers.append(md);
     }
     else if (md->isFriend())
     {
       friends.append(md);
-      if (Config::sortMembersFlag)
-        relatedMembers.inSort(md);
-      else
-        relatedMembers.append(md);
     }
     else
     {
@@ -140,34 +165,18 @@ void ClassDef::insertMember(const MemberDef *md)
       {
         case MemberDef::Signal:
           signals.append(md);
-          if (Config::sortMembersFlag)
-            functionMembers.inSort(md);
-          else
-            functionMembers.append(md);
           break;
         case MemberDef::Slot:
           switch (md->protection())
           {
             case Protected: 
               proSlots.append(md); 
-              if (Config::sortMembersFlag)
-                functionMembers.inSort(md); 
-              else
-                functionMembers.append(md);
               break;
             case Public:    
               pubSlots.append(md); 
-              if (Config::sortMembersFlag)
-                functionMembers.inSort(md); 
-              else
-                functionMembers.append(md);
               break;
             case Private:   
               priSlots.append(md);
-              if (Config::sortMembersFlag)
-                functionMembers.inSort(md); 
-              else
-                functionMembers.append(md);
               break;
           }
           break;
@@ -235,6 +244,57 @@ void ClassDef::insertMember(const MemberDef *md)
               }
             }
           }
+          break; 
+      }
+    }
+
+    /*******************************************************/
+    /* insert member in the detailed documentation section */
+    /*******************************************************/
+    if ((md->isRelated() && 
+          (Config::extractPrivateFlag || md->protection()!=Private)
+        ) || md->isFriend()
+       )
+    {
+      if (Config::sortMembersFlag)
+        relatedMembers.inSort(md);
+      else
+        relatedMembers.append(md);
+    }
+    else
+    {
+      switch (md->memberType())
+      {
+        case MemberDef::Signal:
+          if (Config::sortMembersFlag)
+            functionMembers.inSort(md);
+          else
+            functionMembers.append(md);
+          break;
+        case MemberDef::Slot:
+          switch (md->protection())
+          {
+            case Protected: 
+              if (Config::sortMembersFlag)
+                functionMembers.inSort(md); 
+              else
+                functionMembers.append(md);
+              break;
+            case Public:    
+              if (Config::sortMembersFlag)
+                functionMembers.inSort(md); 
+              else
+                functionMembers.append(md);
+              break;
+            case Private:   
+              if (Config::sortMembersFlag)
+                functionMembers.inSort(md); 
+              else
+                functionMembers.append(md);
+              break;
+          }
+          break;
+        default: // any of the other members
           if (md->protection()!=Private || Config::extractPrivateFlag)
           {
             switch (md->memberType())
@@ -279,33 +339,51 @@ void ClassDef::insertMember(const MemberDef *md)
                   variableMembers.append(md);
                 break;
               default:
-                printf("Unexpected member type %d found!\n",md->memberType());
+                err("Unexpected member type %d found!\n",md->memberType());
             }
           }
           break; 
       }
     }
   }
-  // check if we should add this member in the `all members' list
-  if (1 /*md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag*/)
+
+  MemberInfo *mi = new MemberInfo((MemberDef *)md,Public,Normal);
+  MemberNameInfo *mni=0;
+  if ((mni=(*allMemberNameInfoDict)[md->name()]))
+  {
+    mni->append(mi);
+  }
+  else
   {
-    MemberInfo *mi = new MemberInfo((MemberDef *)md,Public,Normal);
-    MemberNameInfo *mni=0;
-    if ((mni=(*allMemberNameInfoDict)[md->name()]))
-    {
-      mni->append(mi);
-    }
-    else
+    mni = new MemberNameInfo(md->name());
+    mni->append(mi);
+    allMemberNameInfoList->inSort(mni);
+    allMemberNameInfoDict->insert(mni->memberName(),mni);
+  }
+}
+
+
+void ClassDef::computeMemberGroups()
+{
+  MemberNameInfoListIterator mnili(*allMemberNameInfoList);
+  MemberNameInfo *mni;
+  for (;(mni=mnili.current());++mnili)
+  {
+    MemberNameInfoIterator mnii(*mni);
+    MemberInfo *mi;
+    for (mnii.toFirst();(mi=mnii.current());++mnii)
     {
-      mni = new MemberNameInfo(md->name());
-      mni->append(mi);
-      allMemberNameInfoList->inSort(mni);
-      allMemberNameInfoDict->insert(mni->memberName(),mni);
+      MemberDef *md=mi->memberDef;
+      MemberGroup *mg = md->getMemberGroup();
+      if (mg && memberGroupDict->find(mg->groupId())==0)
+      {
+        memberGroupDict->insert(mg->groupId(),mg);
+        memberGroupList->append(mg);
+      }
     }
   }
 }
 
-
 // compute the anchors for all members
 void ClassDef::computeAnchors()
 {
@@ -330,6 +408,12 @@ void ClassDef::computeAnchors()
   setAnchors('s',&pubTypes);
   setAnchors('t',&proTypes);
   setAnchors('u',&priTypes);
+  //MemberGroupListIterator mgli(*memberGroupList);
+  //MemberGroup *mg;
+  //for (;(mg=mgli.current());++mgli)
+  //{
+  //  mg->setAnchors();
+  //}
 }
 
 // add a file name to the used files set
@@ -598,6 +682,14 @@ void ClassDef::writeDocumentation(OutputList &ol)
   // write member groups
   ol.startMemberSections();
 
+  // write user defined member groups
+  MemberGroupListIterator mgli(*memberGroupList);
+  MemberGroup *mg;
+  for (;(mg=mgli.current());++mgli)
+  {
+    mg->writeDeclarations(ol,this,0,0,0);
+  }
+
   // non static public members
   pubTypes.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicTypes(),0); 
   pubMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicMembers(),0); 
@@ -1174,10 +1266,13 @@ bool ClassDef::hasNonReferenceSuperClass()
 //  htmlHelp->decContentsDepth();
 //}
 
-void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md)
+void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup)
 {
   //ol.insertMemberAlign();
-  //printf("ClassName=`%s'\n",name().data());
+  //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup);
+
+  if (inGroup && md && md->memberClass()==this) return;
+  
   switch(compType)
   {
     case Class:  ol.docify("class"); break;
@@ -1193,24 +1288,45 @@ void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md)
     ol.writeObjectLink(0,0,md->anchor(),cn);
   }
   ol.docify(" {");
-  ol.endMemberItem(FALSE,0,0,FALSE); // TODO: pass correct group parameters
+  ol.endMemberItem(FALSE); 
 
   // insert members of this class
-  pubMembers.writePlainDeclarations(ol,this,0,0,0); 
-  pubSlots.writePlainDeclarations(ol,this,0,0,0); 
-  signals.writePlainDeclarations(ol,this,0,0,0); 
-  pubStaticMembers.writePlainDeclarations(ol,this,0,0,0); 
-  proMembers.writePlainDeclarations(ol,this,0,0,0); 
-  proSlots.writePlainDeclarations(ol,this,0,0,0); 
-  proStaticMembers.writePlainDeclarations(ol,this,0,0,0); 
-  if (Config::extractPrivateFlag)
+  if (inGroup)
   {
-    priMembers.writePlainDeclarations(ol,this,0,0,0); 
-    priSlots.writePlainDeclarations(ol,this,0,0,0); 
-    priStaticMembers.writePlainDeclarations(ol,this,0,0,0); 
+    MemberGroupListIterator mgli(*memberGroupList);
+    MemberGroup *mg;
+    for (;(mg=mgli.current());++mgli)
+    {
+      mg->writePlainDeclarations(ol,this,0,0,0);
+    }
+  }
+  else
+  {
+    pubTypes.writePlainDeclarations(ol,this,0,0,0); 
+    pubMembers.writePlainDeclarations(ol,this,0,0,0); 
+    pubAttribs.writePlainDeclarations(ol,this,0,0,0); 
+    pubSlots.writePlainDeclarations(ol,this,0,0,0); 
+    signals.writePlainDeclarations(ol,this,0,0,0); 
+    pubStaticMembers.writePlainDeclarations(ol,this,0,0,0); 
+    pubStaticAttribs.writePlainDeclarations(ol,this,0,0,0); 
+    proTypes.writePlainDeclarations(ol,this,0,0,0); 
+    proMembers.writePlainDeclarations(ol,this,0,0,0); 
+    proAttribs.writePlainDeclarations(ol,this,0,0,0); 
+    proSlots.writePlainDeclarations(ol,this,0,0,0); 
+    proStaticMembers.writePlainDeclarations(ol,this,0,0,0); 
+    proStaticAttribs.writePlainDeclarations(ol,this,0,0,0); 
+    if (Config::extractPrivateFlag)
+    {
+      priTypes.writePlainDeclarations(ol,this,0,0,0); 
+      priMembers.writePlainDeclarations(ol,this,0,0,0); 
+      priAttribs.writePlainDeclarations(ol,this,0,0,0); 
+      priSlots.writePlainDeclarations(ol,this,0,0,0); 
+      priStaticMembers.writePlainDeclarations(ol,this,0,0,0); 
+      priStaticAttribs.writePlainDeclarations(ol,this,0,0,0); 
+    }
+    friends.writePlainDeclarations(ol,this,0,0,0);
+    related.writePlainDeclarations(ol,this,0,0,0); 
   }
-  friends.writePlainDeclarations(ol,this,0,0,0);
-  related.writePlainDeclarations(ol,this,0,0,0); 
 }
 
 /*! a link to this class is possible within this project */
diff --git a/src/classdef.h b/src/classdef.h
index 1425991..e3c8da9 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -39,6 +39,8 @@ class ExampleList;
 class MemberNameInfoList;
 class MemberNameInfoDict;
 class UsesClassDict;
+class MemberGroupList;
+class MemberGroupDict;
 struct IncludeInfo;
 
 class ClassDef : public Definition
@@ -63,16 +65,18 @@ class ClassDef : public Definition
     //void setIncludeName(const char *n_) { incName=n_; }
     MemberNameInfoList *memberNameInfoList() { return allMemberNameInfoList; }
     MemberNameInfoDict *memberNameInfoDict() { return allMemberNameInfoDict; }
-    void insertMember(const MemberDef *);
+    void insertMember(MemberDef *,int grpId);
+    void addMemberToGroup(MemberDef *,int grpId);
     void insertUsedFile(const char *);
     void computeAnchors();
+    void computeMemberGroups();
     void setAnchor(MemberDef *);
     void dumpMembers();
     void writeDocumentation(OutputList &ol);
     void writeMemberList(OutputList &ol);
     //void writeIncludeFile(OutputList &ol);
     //void writeMembersToContents();
-    void writeDeclaration(OutputList &ol,MemberDef *md);
+    void writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup);
     bool addExample(const char *anchor,const char *name, const char *file);
     bool hasExamples();
     //void writeExample(OutputList &ol);
@@ -157,17 +161,21 @@ class ClassDef : public Definition
     MemberList relatedMembers;
     MemberList variableMembers;
 
+    /* user defined member groups */
+    MemberGroupList    *memberGroupList;
+    MemberGroupDict    *memberGroupDict;
+
     MemberNameInfoList *allMemberNameInfoList;
     MemberNameInfoDict *allMemberNameInfoDict;
-    ArgumentList     *tempArgs;
-    QStrList          files;
-    ExampleList      *exampleList;
-    ExampleDict      *exampleDict;
-    CompoundType      compType;
-    Protection        prot;
-    FileDef          *fileDef;
-    UsesClassDict    *usesImplClassDict;
-    UsesClassDict    *usesIntfClassDict;
+    ArgumentList       *tempArgs;
+    QStrList            files;
+    ExampleList        *exampleList;
+    ExampleDict        *exampleDict;
+    CompoundType        compType;
+    Protection          prot;
+    FileDef            *fileDef;
+    UsesClassDict      *usesImplClassDict;
+    UsesClassDict      *usesIntfClassDict;
 };
 
 struct UsesClassDef
diff --git a/src/classlist.cpp b/src/classlist.cpp
index 36ac2b7..8623347 100644
--- a/src/classlist.cpp
+++ b/src/classlist.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/classlist.h b/src/classlist.h
index c3269bd..2e52083 100644
--- a/src/classlist.h
+++ b/src/classlist.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/code.h b/src/code.h
index e13483a..00de326 100644
--- a/src/code.h
+++ b/src/code.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/code.l b/src/code.l
index 1a9a6b4..82d1d1c 100644
--- a/src/code.l
+++ b/src/code.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/config.h b/src/config.h
index 05670e9..4cd77dc 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/config.l b/src/config.l
index a806aa7..549450a 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -1634,8 +1634,9 @@ static void substEnvVarsInString(QCString &s)
   while ((i=re.match(s,p,&l))!=-1)
   {
     //printf("Found environment var s.mid(%d,%d)=`%s'\n",i+2,l-3,s.mid(i+2,l-3).data());
-    const char *env=getenv(s.mid(i+2,l-3));
-    s = s.left(i)+QCString(env)+s.right(s.length()-i-l);
+    QCString env=getenv(s.mid(i+2,l-3));
+    substEnvVarsInString(env); // recursively expand variables if needed.
+    s = s.left(i)+env+s.right(s.length()-i-l);
     p=i+l;
   }
   //printf("substEnvVarInString(%s) end\n",s.data());
diff --git a/src/constexp.h b/src/constexp.h
index 7ac5fe3..c7be36d 100644
--- a/src/constexp.h
+++ b/src/constexp.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/constexp.l b/src/constexp.l
index 5e63aa6..d69dc08 100644
--- a/src/constexp.l
+++ b/src/constexp.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/constexp.y b/src/constexp.y
index fa13d6e..6de51f6 100644
--- a/src/constexp.y
+++ b/src/constexp.y
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-1999 by Dimitri van Heesch.
diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp
index df404b9..7f0a5d9 100644
--- a/src/cppvalue.cpp
+++ b/src/cppvalue.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/cppvalue.h b/src/cppvalue.h
index d1bc13b..0818f7e 100644
--- a/src/cppvalue.h
+++ b/src/cppvalue.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/debug.cpp b/src/debug.cpp
index 8224e74..ecad34e 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/debug.h b/src/debug.h
index 7f5f41e..4f90eaa 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/declinfo.h b/src/declinfo.h
index 336e2d4..6d89545 100644
--- a/src/declinfo.h
+++ b/src/declinfo.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/declinfo.l b/src/declinfo.l
index 67f537c..a964bf9 100644
--- a/src/declinfo.l
+++ b/src/declinfo.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -93,7 +93,7 @@ static int yyread(char *buf,int max_size)
 %}
 
 B       [ \t]
-ID	[a-z_A-Z][a-z_A-Z0-9]*
+ID	([a-z_A-Z][a-z_A-Z0-9]*)|(@[0-9]+)
 
 %option noyywrap
 
diff --git a/src/defargs.h b/src/defargs.h
index ca34550..da37150 100644
--- a/src/defargs.h
+++ b/src/defargs.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/defargs.l b/src/defargs.l
index 2744869..76d1d97 100644
--- a/src/defargs.l
+++ b/src/defargs.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/define.cpp b/src/define.cpp
index eaf424e..464c0c3 100644
--- a/src/define.cpp
+++ b/src/define.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/define.h b/src/define.h
index 358f10c..a2e858d 100644
--- a/src/define.h
+++ b/src/define.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/definition.cpp b/src/definition.cpp
index d93f57d..02bb2f1 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -36,6 +36,8 @@ Definition::~Definition()
 
 QCString Definition::nameToFile(const char *name)
 {
+  return convertNameToFile(name);
+#if 0
   QCString result;
   char c;
   const char *p=name;
@@ -61,6 +63,7 @@ QCString Definition::nameToFile(const char *name)
     }
   }
   return result;
+#endif
 }
 
 void Definition::addSectionsToDefinition(QList<QCString> *anchorList)
@@ -280,10 +283,7 @@ bool Definition::hasDocumentation()
 { 
   return !doc.isEmpty() ||              // has detailed docs
          !brief.isEmpty() ||            // has brief description
-         (Config::sourceBrowseFlag && 
-          startBodyLine!=-1 && 
-          bodyDef
-         ) ||                          // has a source reference
+         /*(Config::sourceBrowseFlag && startBodyLine!=-1 && bodyDef) || // has a source reference */
          Config::extractAllFlag;       // extract everything
 }
 
diff --git a/src/definition.h b/src/definition.h
index 9eaf438..2b802c8 100644
--- a/src/definition.h
+++ b/src/definition.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/diagram.cpp b/src/diagram.cpp
index a4781d8..2763a28 100644
--- a/src/diagram.cpp
+++ b/src/diagram.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/diagram.h b/src/diagram.h
index f7b152a..6959911 100644
--- a/src/diagram.h
+++ b/src/diagram.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/dot.cpp b/src/dot.cpp
index 724c549..ffa6918 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
@@ -466,9 +466,15 @@ void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path)
   {
     QCString baseName;
     QCString diskName=n->m_url.copy();
-    int i=diskName.find('$'); /* should not return -1 */
-    ASSERT(i!=-1);
-    diskName=diskName.right(diskName.length()-i-1);
+    int i=diskName.find('$'); 
+    if (i!=-1)
+    {
+      diskName=diskName.right(diskName.length()-i-1);
+    }
+    else /* take the label name as the file name (and strip any template stuff) */
+    {
+      diskName=convertNameToFile(n->m_label);
+    }
     baseName.sprintf("inherit_graph_%s",diskName.data());
     QCString dotName=baseName+".dot";
     QCString gifName=baseName+".gif";
@@ -650,8 +656,10 @@ DotGfxHierarchyTable::DotGfxHierarchyTable()
         n->colorConnectedNodes(curColor);
         curColor++;
         const DotNode *dn=n->findDocNode();
-        ASSERT(dn!=0);
-        if (dn!=0) m_rootSubgraphs->inSort(dn);
+        if (dn!=0) 
+          m_rootSubgraphs->inSort(dn);
+        else
+          m_rootSubgraphs->inSort(n);
       }
     }
   }
diff --git a/src/dot.h b/src/dot.h
index c8e8f33..d2ba25b 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 94b25b4..8060e93 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
@@ -95,6 +95,8 @@ QDict<void>    compoundKeywordDict(7);  // keywords recognised as compounds
 OutputList     *outputList = 0;         // list of output generating objects
 
 PageInfo       *mainPage = 0;
+QIntDict<QCString> memberHeaderDict(1009); // dictionary of the member groups heading
+QIntDict<QCString> memberDocDict(1009);    // dictionary of the member groups heading
   
 
 void clearAll()
@@ -460,7 +462,7 @@ static void addMemberToGroups(Entry *root,MemberDef *md)
       GroupDef *mgd = md->groupDef();
       if (mgd==0)
       {
-        gd->addMember(md);
+        gd->insertMember(md,root->mGrpId);
         md->setGroupDef(gd);
       }
       else if (mgd!=gd)
@@ -893,6 +895,11 @@ static MemberDef *addVariableToClass(Entry *root,ClassDef *cd,
   md->setIndentDepth(indentDepth);
   md->setBodySegment(root->bodyLine,root->endBodyLine);
   md->setInitializer(root->initializer);
+  //if (root->mGrpId!=-1) 
+  //{
+  //  printf("memberdef %s in memberGroup %d\n",name.data(),root->mGrpId);
+  //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+  //
   bool ambig;
   md->setBodyDef(findFileDef(&inputNameDict,root->fileName,ambig));
 
@@ -910,7 +917,7 @@ static MemberDef *addVariableToClass(Entry *root,ClassDef *cd,
     memberNameList.inSort(mn);
     // add the member to the class
   }
-  cd->insertMember(md);
+  cd->insertMember(md,root->mGrpId);
 
   //TODO: insert FileDef instead of filename strings.
   cd->insertUsedFile(root->fileName);
@@ -950,6 +957,10 @@ static MemberDef *addVariableToFile(Entry *root,MemberDef::MemberType mtype,
   bool ambig;
   FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig);
   md->setBodyDef(fd);
+  //if (root->mGrpId!=-1) 
+  //{
+  //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+  //}
 
   // see if the function is inside a namespace
   NamespaceDef *nd = 0;
@@ -963,7 +974,7 @@ static MemberDef *addVariableToFile(Entry *root,MemberDef::MemberType mtype,
   }
   if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
   {
-    nd->insertMember(md); 
+    nd->insertMember(md,root->mGrpId); 
     md->setNamespace(nd);
   }
   else
@@ -971,7 +982,7 @@ static MemberDef *addVariableToFile(Entry *root,MemberDef::MemberType mtype,
     // find file definition
     if (fd)
     {
-      fd->insertMember(md);
+      fd->insertMember(md,root->mGrpId);
       md->setFileDef(fd); 
     }
   }
@@ -1047,11 +1058,12 @@ void buildVarList(Entry *root)
   {
     Debug::print(Debug::Variables,0,
                   "VARIABLE_SEC: \n"
-                  "  type=`%s' name=`%s' args=`%s' bodyLine=`%d'\n",
+                  "  type=`%s' name=`%s' args=`%s' bodyLine=`%d' mGrpId=%d\n",
                    root->type.data(),
                    root->name.data(),
                    root->args.data(),
-                   root->bodyLine
+                   root->bodyLine,
+                   root->mGrpId
                 );
     //printf("root->parent->name=%s\n",root->parent->name.data());
 
@@ -1286,7 +1298,10 @@ void buildMemberList(Entry *root)
         md->setBriefDescription(root->brief);
         //md->setBody(root->body);
         md->setBodySegment(root->bodyLine,root->endBodyLine);
-        md->setGroupId(root->mGrpId);
+        //if (root->mGrpId!=-1) 
+        //{
+        //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+        //}
         md->setInline(root->inLine);
         bool ambig;
         md->setBodyDef(findFileDef(&inputNameDict,root->fileName,ambig));
@@ -1374,7 +1389,7 @@ void buildMemberList(Entry *root)
         }
 
         // add member to the class cd
-        cd->insertMember(md);
+        cd->insertMember(md,root->mGrpId);
         // add file to list of used files
         cd->insertUsedFile(root->fileName);
 
@@ -1422,7 +1437,12 @@ void buildMemberList(Entry *root)
                 md->setBodySegment(root->bodyLine,root->endBodyLine);
                 bool ambig;
                 md->setBodyDef(findFileDef(&inputNameDict,root->fileName,ambig));
-              }
+              } 
+              //if (root->mGrpId!=-1 && md->getMemberGroup()==0)
+              //{
+              //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+              //}
+
               md->addSectionsToDefinition(root->anchors);
             }
             md=mn->next();
@@ -1449,7 +1469,6 @@ void buildMemberList(Entry *root)
           FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig);
           md->setBodyDef(fd);
           md->addSectionsToDefinition(root->anchors);
-          md->setGroupId(root->mGrpId);
           md->setInline(root->inLine);
           QCString def;
           if (!root->type.isEmpty())
@@ -1486,6 +1505,10 @@ void buildMemberList(Entry *root)
                      def.data()
                     );
           md->setDefinition(def);
+          //if (root->mGrpId!=-1) 
+          //{
+          //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+          //}
 
           // see if the function is inside a namespace
           NamespaceDef *nd = 0;
@@ -1500,7 +1523,7 @@ void buildMemberList(Entry *root)
 
           if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
           {
-            nd->insertMember(md); 
+            nd->insertMember(md,root->mGrpId); 
             md->setNamespace(nd);
           }
           else
@@ -1514,7 +1537,7 @@ void buildMemberList(Entry *root)
             if (fd)
             {
               // add member to the file
-              fd->insertMember(md);
+              fd->insertMember(md,root->mGrpId);
               md->setFileDef(fd); 
             }
           }
@@ -2037,18 +2060,31 @@ void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl,
   if (cd) cd->insertUsedFile(root->fileName);
   if (root->mGrpId!=-1)
   {
-    if (md->groupId()!=-1)
+    if (md->getMemberGroup())
     {
-      if (md->groupId()!=root->mGrpId)
+      if (md->getMemberGroup()->groupId()!=root->mGrpId)
       {
         warn("Warning: member %s belongs to two different group. The second "
-             "one is found at line %d of %s and will be ignored\n",
-             md->name().data(),root->startLine,root->fileName.data());
+            "one is found at line %d of %s and will be ignored\n",
+            md->name().data(),root->startLine,root->fileName.data());
       }
     }
-    else // copy group id
+    else // set group id
     {
-      md->setGroupId(root->mGrpId);
+      //md->setMemberGroup(memberGroupDict[root->mGrpId]);
+      if (cd)
+        cd->addMemberToGroup(md,root->mGrpId);
+      else if (nd)
+        nd->addMemberToGroup(md,root->mGrpId);
+      else
+      {
+        bool ambig;
+        FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig);
+        if (fd)
+        {
+          fd->addMemberToGroup(md,root->mGrpId);
+        }
+      }
     }
   }
 }
@@ -2350,7 +2386,8 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
   parseFuncDecl(funcDecl,scopeName,classTempList,funcType,funcName,
                 funcArgs,funcTempList,exceptions
                );
-  //printf("scopeName=`%s'\n",scopeName.data());
+  //printf("scopeName=`%s' funcType=`%s' funcName=`%s'\n",
+  //    scopeName.data(),funcType.data(),funcName.data());
   
   //bool isSpecialization = !root->scopeSpec.isEmpty() && 
   //                  root->scopeSpec != tempArgListToString(root->tArgList);
@@ -2832,6 +2869,10 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
           md->setDefLine(root->startLine);
           md->setPrototype(root->proto);
           md->addSectionsToDefinition(root->anchors);
+          //if (root->mGrpId!=-1) 
+          //{
+          //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+          //}
           //md->setBody(root->body);
           md->setBodySegment(root->bodyLine,root->endBodyLine);
           bool ambig;
@@ -2839,7 +2880,7 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
           md->setBodyDef(fd);
           md->setInline(root->inLine);
           mn->inSort(md);
-          cd->insertMember(md);
+          cd->insertMember(md,root->mGrpId);
           cd->insertUsedFile(root->fileName);
         }
       }
@@ -2937,6 +2978,10 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
             md->setBodyDef(fd);
           }
 
+          //if (root->mGrpId!=-1) 
+          //{
+          //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+          //}
           md->setMemberClass(cd);
           md->setInline(root->inLine);
           md->setDefinition(funcDecl);
@@ -2947,7 +2992,7 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
           md->setBriefDescription(root->brief);
           md->addSectionsToDefinition(root->anchors);
           mn->inSort(md);
-          cd->insertMember(md);
+          cd->insertMember(md,root->mGrpId);
           cd->insertUsedFile(root->fileName);
           if (newMemberName)
           {
@@ -3026,16 +3071,15 @@ void findMemberDocumentation(Entry *root)
     findMember(root,root->name,root->relates,TRUE,isFunc);
   }
   else if 
-    ((root->section==Entry::FUNCTION_SEC ||   // function
+    ((root->section==Entry::FUNCTION_SEC // function
+      ||   
       (root->section==Entry::VARIABLE_SEC && 
       !root->type.isEmpty() && root->type.left(8)!="typedef " &&
        compoundKeywordDict.find(root->type)==0
-       /*root->type!="class"  && root->type!="interface" && 
-       root->type!="struct" && root->type!="union"*/
       )
      ) && 
      (!root->doc.isEmpty() || !root->brief.isEmpty() || 
-      root->bodyLine!=-1 || root->mGrpId!=-1 /*|| Config::extractAllFlag*/
+      root->bodyLine!=-1 /* || root->mGrpId!=-1 || Config::extractAllFlag*/
       || root->inLine
      )
     )
@@ -3154,23 +3198,28 @@ void findEnums(Entry *root)
       md->setBodySegment(root->bodyLine,root->endBodyLine);
       bool ambig;
       md->setBodyDef(findFileDef(&inputNameDict,root->fileName,ambig));
-      //printf("Enum definition at line %d of %s\n",root->bodyLine,root->fileName.data());
+      //printf("Enum %s definition at line %d of %s: protection=%d\n",
+      //    root->name.data(),root->bodyLine,root->fileName.data(),root->protection);
       md->addSectionsToDefinition(root->anchors);
+      //if (root->mGrpId!=-1) 
+      //{
+      //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+      //}
       if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
       {
         md->setDefinition(nd->name()+"::"+name);  
-        nd->insertMember(md);
+        nd->insertMember(md,root->mGrpId);
         md->setNamespace(nd);
       }
       else if (isGlobal)
       {
         md->setDefinition(name);
-        fd->insertMember(md);
+        fd->insertMember(md,root->mGrpId);
       }
       else if (cd)
       {
         md->setDefinition(cd->name()+"::"+name);
-        cd->insertMember(md);
+        cd->insertMember(md,root->mGrpId);
         cd->insertUsedFile(root->fileName);
       }
       md->setDocumentation(root->doc);
@@ -3306,6 +3355,12 @@ void findEnumDocumentation(Entry *root)
               {
                 md->setBriefDescription(root->brief);
               }
+
+              if (root->mGrpId!=-1 && md->getMemberGroup()==0)
+              {
+                cd->addMemberToGroup(md,root->mGrpId);
+              }
+              
               md->addSectionsToDefinition(root->anchors);
               found=TRUE;
             }
@@ -3457,6 +3512,18 @@ void computeClassImplUsageRelations()
 }
 
 //----------------------------------------------------------------------------
+void computeMemberGroups()
+{
+  ClassDef *cd;
+  ClassListIterator cli(classList);
+  for (;(cd=cli.current());++cli)
+  {
+    cd->computeMemberGroups();
+  }
+}
+
+
+//----------------------------------------------------------------------------
 #if 0
 void computeClassIntfUsageRelations()
 {
@@ -3739,10 +3806,19 @@ void findDefineDocumentation(Entry *root)
             if (md->briefDescription().isEmpty())
               md->setBriefDescription(root->brief);
             md->setBodySegment(root->bodyLine,root->endBodyLine);
+            //if (root->mGrpId!=-1 && md->getMemberGroup()==0) 
+            //{
+            //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+            //}
             bool ambig;
             md->setBodyDef(findFileDef(&inputNameDict,root->fileName,ambig));
             md->addSectionsToDefinition(root->anchors);
             addMemberToGroups(root,md);
+            FileDef *fd=md->getFileDef();
+            if (fd && root->mGrpId!=-1)
+            {
+              fd->addMemberToGroup(md,root->mGrpId);
+            }
           }
           md=mn->next();
         }
@@ -3773,7 +3849,15 @@ void findDefineDocumentation(Entry *root)
               bool ambig;
               md->setBodyDef(findFileDef(&inputNameDict,root->fileName,ambig));
               md->addSectionsToDefinition(root->anchors);
+              //if (root->mGrpId!=-1 && md->getMemberGroup()==0) 
+              //{
+              //  md->setMemberGroup(memberGroupDict[root->mGrpId]);
+              //}
               addMemberToGroups(root,md);
+              if (root->mGrpId!=-1)
+              {
+                fd->addMemberToGroup(md,root->mGrpId);
+              }
             }
           }
           md=mn->next();
@@ -4037,28 +4121,28 @@ void generateGroupDocs()
 // create member group documentation based on the documentation of the
 // group's members.
 
-void computeMemberGroupDocumentation()
-{
-  MemberGroupDictIterator mgdi(memberGroupDict);
-  MemberGroup *mg;
-  for (;(mg=mgdi.current());++mgdi)
-  {
-    mg->addDocumentation(); 
-  }
-}
+//void computeMemberGroupDocumentation()
+//{
+//  MemberGroupDictIterator mgdi(memberGroupDict);
+//  MemberGroup *mg;
+//  for (;(mg=mgdi.current());++mgdi)
+//  {
+//    mg->addDocumentation(); 
+//  }
+//}
 
 //----------------------------------------------------------------------------
 // generate member group pages
 
-void generateMemberGroupDocs()
-{
-  MemberGroupDictIterator mgdi(memberGroupDict);
-  MemberGroup *mg;
-  for (;(mg=mgdi.current());++mgdi)
-  {
-    mg->writeDocumentation(*outputList); 
-  }
-}
+//void generateMemberGroupDocs()
+//{
+//  MemberGroupDictIterator mgdi(memberGroupDict);
+//  MemberGroup *mg;
+//  for (;(mg=mgdi.current());++mgdi)
+//  {
+//    mg->writeDocumentation(*outputList); 
+//  }
+//}
 
 
 //----------------------------------------------------------------------------
@@ -5017,6 +5101,9 @@ int main(int argc,char **argv)
   msg("Determining which enums are documented\n");
   findDocumentedEnumValues();
 
+  msg("Computing member groups...\n");
+  computeMemberGroups();
+
   msg("Computing member references...\n");
   computeMemberReferences(); 
 
@@ -5028,6 +5115,7 @@ int main(int argc,char **argv)
     msg("Computing class implementation usage relations...\n");
     computeClassImplUsageRelations();
   }
+
   
   msg("Building full member lists recursively...\n");
   buildCompleteMemberLists();
@@ -5035,8 +5123,8 @@ int main(int argc,char **argv)
   //msg("Computing class interface usage relations...\n");
   //computeClassIntfUsageRelations();
 
-  msg("Determining member group documentation...\n");
-  computeMemberGroupDocumentation();
+  //msg("Determining member group documentation...\n");
+  //computeMemberGroupDocumentation();
 
   msg("Adding source references...\n");
   addSourceReferences();
@@ -5093,8 +5181,8 @@ int main(int argc,char **argv)
   msg("Generating group documentation...\n");
   generateGroupDocs();
 
-  msg("Generating member group documentation...\n");
-  generateMemberGroupDocs();
+  //msg("Generating member group documentation...\n");
+  //generateMemberGroupDocs();
 
   msg("Generating namespace index...\n");
   generateNamespaceDocs();
diff --git a/src/doxygen.h b/src/doxygen.h
index 6c620a0..52f4995 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
@@ -19,6 +19,7 @@
 #define DOXYGEN_H
 
 #include "qtbc.h"
+#include <qtextstream.h>
 #include "groupdef.h"
 #include "filedef.h"
 #include "classdef.h"
@@ -26,10 +27,11 @@
 #include "classlist.h"
 #include "membername.h"
 #include "filename.h"
-#include "define.h"
+//#include "define.h"
 #include "namespacedef.h"
 #include "formula.h"
 #include "section.h"
+#include "membergroup.h"
 
 struct PageInfo
 {
@@ -117,6 +119,8 @@ extern FormulaDict formulaDict;
 extern FormulaDict formulaNameDict;
 extern PageInfo *mainPage;
 extern StringDict tagDestinationDict; 
+extern QIntDict<QCString> memberHeaderDict; // dictionary of the member groups heading
+extern QIntDict<QCString> memberDocDict;    // dictionary of the member groups heading
 
 extern int annotatedClasses;
 extern int hierarchyClasses;
diff --git a/src/doxygen.pro.in b/src/doxygen.pro.in
index 9bc1d0a..e00f871 100644
--- a/src/doxygen.pro.in
+++ b/src/doxygen.pro.in
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-2000 by Dimitri van Heesch.
 #
diff --git a/src/doxygen.t b/src/doxygen.t
index badf33e..3f688bf 100644
--- a/src/doxygen.t
+++ b/src/doxygen.t
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-1999 by Dimitri van Heesch.
 #
diff --git a/src/doxysearch.cpp b/src/doxysearch.cpp
index 867ef94..57d4093 100644
--- a/src/doxysearch.cpp
+++ b/src/doxysearch.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/doxysearch.pro.in b/src/doxysearch.pro.in
index f96daf9..198a381 100644
--- a/src/doxysearch.pro.in
+++ b/src/doxysearch.pro.in
@@ -1,5 +1,5 @@
 # 
-# $Id$
+# 
 #
 # Copyright (C) 1997-1999 by Dimitri van Heesch.
 # 
diff --git a/src/doxytag.l b/src/doxytag.l
index a72a53b..8d28150 100644
--- a/src/doxytag.l
+++ b/src/doxytag.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/doxytag.pro.in b/src/doxytag.pro.in
index c09cad5..c2a1b67 100644
--- a/src/doxytag.pro.in
+++ b/src/doxytag.pro.in
@@ -1,5 +1,5 @@
 # 
-# $Id$
+# 
 #
 # Copyright (C) 1997-1999 by Dimitri van Heesch.
 # 
diff --git a/src/doxytag.t b/src/doxytag.t
index 1ee8ec5..f507616 100644
--- a/src/doxytag.t
+++ b/src/doxytag.t
@@ -1,5 +1,5 @@
 #
-# $Id$
+# 
 #
 # Copyright (C) 1997-1999 by Dimitri van Heesch.
 #
diff --git a/src/entry.cpp b/src/entry.cpp
index 9a175ef..7012339 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/entry.h b/src/entry.h
index 4d1c1c4..3514e85 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -139,7 +139,8 @@ class Entry
       DEFINE_SEC       = 0x00f00000,
       GROUPDOC_SEC     = 0x01000000,
       USINGDIR_SEC     = 0x01100000,
-      MAINPAGEDOC_SEC  = 0x01200000
+      MAINPAGEDOC_SEC  = 0x01200000,
+      MEMBERGRP_SEC    = 0x01300000
     };
 
     Entry();
diff --git a/src/example.h b/src/example.h
index bd4fa08..d0f8a4b 100644
--- a/src/example.h
+++ b/src/example.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 7d45336..af98024 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -17,7 +17,6 @@
 #include "qtbc.h"
 #include "memberlist.h"
 #include "classlist.h"
-#include "define.h"
 #include "filedef.h"
 #include "scanner.h"
 #include "doxygen.h"
@@ -42,38 +41,39 @@ FileDef::FileDef(const char *p,const char *nm,const char *ref)
   filename=nameToFile(nm);
   diskname=filename.copy();
   setReference(ref);
-  //memList      = new MemberList;
   classList     = new ClassList;
   includeList   = new QList<IncludeInfo>;
   includeList->setAutoDelete(TRUE);
   includeDict   = new QDict<IncludeInfo>(61);
-  defineList    = new DefineList;
   namespaceList = new NamespaceList;
   namespaceDict = new NamespaceDict(7);
   srcDefDict = 0;
   srcAnchorDict = 0;
   usingList = 0;
-  isSource = FALSE; /*Config::extractAllFlag*/;
+  isSource = FALSE; 
   docname = nm;
   if (Config::fullPathNameFlag)
   {
     docname.prepend(stripFromPath(path.copy()));
   }
+  memberGroupList = new MemberGroupList;
+  memberGroupList->setAutoDelete(TRUE);
+  memberGroupDict = new MemberGroupDict(1009);
 }
 
 /*! destroy the file definition */
 FileDef::~FileDef()
 {
-  //delete memList;
   delete classList;
   delete includeDict;
   delete includeList;
-  delete defineList;
   delete namespaceList;
   delete namespaceDict;
   delete srcDefDict;
   delete srcAnchorDict;
   delete usingList;
+  delete memberGroupList;
+  delete memberGroupDict;
 }
 
 /*! Compute the HTML anchor names for all members in the class */ 
@@ -223,7 +223,7 @@ void FileDef::writeDocumentation(OutputList &ol)
           ol.startMemberList();
           found=TRUE;
         }
-        ol.startMemberItem(FALSE,0);
+        ol.startMemberItem(0);
         ol.writeString("namespace ");
         ol.insertMemberAlign();
         if (nd->isLinkable()) 
@@ -240,7 +240,7 @@ void FileDef::writeDocumentation(OutputList &ol)
           ol.docify(nd->name());
           ol.endBold();
         }
-        ol.endMemberItem(FALSE,0,0,FALSE);
+        ol.endMemberItem(FALSE);
       }
       nd=namespaceList->next();
     }
@@ -262,7 +262,7 @@ void FileDef::writeDocumentation(OutputList &ol)
           ol.startMemberList();
           found=TRUE;
         }
-        ol.startMemberItem(FALSE,FALSE);
+        ol.startMemberItem(FALSE);
         switch (cd->compoundType())
         {
           case ClassDef::Class:  ol.writeString("class");  break;
@@ -287,13 +287,21 @@ void FileDef::writeDocumentation(OutputList &ol)
           ol.docify(cd->name());
           ol.endBold();
         }
-        ol.endMemberItem(FALSE,0,0,FALSE);
+        ol.endMemberItem(FALSE);
       }
       cd=classList->next();
     }
     if (found) ol.endMemberList();
   }
   
+  /* write user defined member groups */
+  MemberGroupListIterator mgli(*memberGroupList);
+  MemberGroup *mg;
+  for (;(mg=mgli.current());++mgli)
+  {
+    mg->writeDeclarations(ol,0,0,this,0);
+  }
+
   allMemberList.writeDeclarations(ol,0,0,this,0,0,0);
   ol.endMemberSections();
 
@@ -457,8 +465,31 @@ void FileDef::writeSource(OutputList &ol)
   ol.enableAll();
 }
 
+/*! Adds a member \a md to the member group with id \a groupId.
+ */ 
+void FileDef::addMemberToGroup(MemberDef *md,int groupId)
+{
+  if (groupId!=-1)
+  {
+    QCString *pGrpHeader = memberHeaderDict[groupId];
+    QCString *pDocs      = memberDocDict[groupId];
+    if (pGrpHeader)
+    {
+      MemberGroup *mg = memberGroupDict->find(groupId);
+      if (mg==0)
+      {
+        mg = new MemberGroup(groupId,*pGrpHeader,pDocs ? pDocs->data() : 0);
+        memberGroupDict->insert(groupId,mg);
+        memberGroupList->append(mg);
+      }
+      mg->insertMember(md);
+      md->setMemberGroup(mg);
+    }
+  }
+}
+
 /*! Adds member definition \a md to the list of all members of this file */
-void FileDef::insertMember(MemberDef *md)
+void FileDef::insertMember(MemberDef *md,int groupId)
 {
   allMemberList.append(md); 
   switch(md->memberType())
@@ -473,6 +504,7 @@ void FileDef::insertMember(MemberDef *md)
     default:
        err("FileDef::insertMembers(): unexpected member insert in file!\n");
   }
+  addMemberToGroup(md,groupId);
 }
 
 /*! Adds compound definition \a cd to the list of all compounds of this file */
diff --git a/src/filedef.h b/src/filedef.h
index a129fe6..5a48afc 100644
--- a/src/filedef.h
+++ b/src/filedef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -31,10 +31,11 @@ class ClassList;
 class ClassDef;
 class MemberDef;
 class OutputList;
-class DefineList;
 class NamespaceDef;
 class NamespaceList;
 class NamespaceDict;
+class MemberGroupList;
+class MemberGroupDict;
 
 struct IncludeInfo
 {
@@ -108,7 +109,8 @@ class FileDef : public Definition
     void writeDocumentation(OutputList &ol);
     void writeSource(OutputList &ol);
     friend void generatedFileNames();
-    void insertMember(MemberDef *fd);
+    void insertMember(MemberDef *md,int groupId);
+    void addMemberToGroup(MemberDef *md,int groupId);
     void insertClass(ClassDef *cd);
     void insertNamespace(NamespaceDef *nd);
     void computeAnchors();
@@ -138,7 +140,7 @@ class FileDef : public Definition
     NamespaceDict *namespaceDict;
     NamespaceList *namespaceList;
     NamespaceList *usingList;
-    DefineList *defineList;
+    //DefineList *defineList;
     QCString path;
     QCString filepath;
     QCString diskname;
@@ -148,6 +150,10 @@ class FileDef : public Definition
     QIntDict<Definition> *srcDefDict;
     QIntDict<QCString> *srcAnchorDict;
     bool isSource;
+
+    /* user defined member groups */
+    MemberGroupList *memberGroupList;
+    MemberGroupDict *memberGroupDict;
 };
 
 /*! \class FileList filedef.h
diff --git a/src/filename.cpp b/src/filename.cpp
index 81a37b0..5aa2b04 100644
--- a/src/filename.cpp
+++ b/src/filename.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/filename.h b/src/filename.h
index 8db7a0c..cb4f207 100644
--- a/src/filename.h
+++ b/src/filename.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/formula.cpp b/src/formula.cpp
index 4715f19..cffb87c 100644
--- a/src/formula.cpp
+++ b/src/formula.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/formula.h b/src/formula.h
index 4d59daa..dccf36b 100644
--- a/src/formula.h
+++ b/src/formula.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/gifenc.cpp b/src/gifenc.cpp
index 1d5474b..74d800e 100644
--- a/src/gifenc.cpp
+++ b/src/gifenc.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/gifenc.h b/src/gifenc.h
index 3c4ae33..a4d9c3d 100644
--- a/src/gifenc.h
+++ b/src/gifenc.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/groupdef.cpp b/src/groupdef.cpp
index 925dd78..6c355a4 100644
--- a/src/groupdef.cpp
+++ b/src/groupdef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -27,6 +27,8 @@
 #include "util.h"
 #include "memberlist.h"
 #include "message.h"
+#include "membergroup.h"
+#include "doxygen.h"
 
 GroupDef::GroupDef(const char *na,const char *t) : 
    Definition(na)
@@ -45,13 +47,17 @@ GroupDef::GroupDef(const char *na,const char *t) :
     title.at(0)=toupper(title.at(0));
   }
   fileName = "group_"+nameToFile(na);
+  memberGroupList = new MemberGroupList;
+  memberGroupList->setAutoDelete(TRUE);
+  memberGroupDict = new MemberGroupDict(1009);
 }
 
 GroupDef::~GroupDef()
 {
   delete fileList;
   delete classList;
-//  delete groupList;
+  delete memberGroupList;
+  delete memberGroupDict;
 }
 
 void GroupDef::addFile(const FileDef *def)
@@ -69,7 +75,28 @@ void GroupDef::addNamespace(const NamespaceDef *def)
   namespaceList->append(def);
 }
 
-void GroupDef::addMember(const MemberDef *md)
+void GroupDef::addMemberToGroup(MemberDef *md,int groupId)
+{
+  if (groupId!=-1)
+  {
+    QCString *pGrpHeader = memberHeaderDict[groupId];
+    QCString *pDocs      = memberDocDict[groupId];
+    if (pGrpHeader)
+    {
+      MemberGroup *mg = memberGroupDict->find(groupId);
+      if (mg==0)
+      {
+        mg = new MemberGroup(groupId,*pGrpHeader,pDocs ? pDocs->data() : 0);
+        memberGroupDict->insert(groupId,mg);
+        memberGroupList->append(mg);
+      }
+      mg->insertMember(md);
+      md->setMemberGroup(mg);
+    }
+  }
+}
+
+void GroupDef::insertMember(MemberDef *md,int groupId)
 {
   QCString funcDecl=md->name()+md->argsString();
   if (allMemberDict->find(funcDecl)==0)
@@ -88,6 +115,7 @@ void GroupDef::addMember(const MemberDef *md)
       default:
          err("FileDef::insertMembers(): unexpected member insert in file!\n");
     }
+    addMemberToGroup(md,groupId);
   }
 }
 
@@ -143,11 +171,11 @@ void GroupDef::writeDocumentation(OutputList &ol)
     FileDef *fd=fileList->first();
     while (fd)
     {
-      ol.startMemberItem(FALSE,0);
+      ol.startMemberItem(0);
       ol.docify("file");
       ol.insertMemberAlign();
       ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
-      ol.endMemberItem(FALSE,0,0,FALSE);
+      ol.endMemberItem(FALSE);
       if (!fd->briefDescription().isEmpty() && Config::briefMemDescFlag)
       {
         ol.startMemberDescription();
@@ -182,11 +210,11 @@ void GroupDef::writeDocumentation(OutputList &ol)
         case ClassDef::Interface:  type="interface";  break;
         case ClassDef::Exception:  type="exception";  break;
       }
-      ol.startMemberItem(FALSE,0);
+      ol.startMemberItem(0);
       ol.docify(type);
       ol.insertMemberAlign();
       ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name());
-      ol.endMemberItem(FALSE,0,0,FALSE);
+      ol.endMemberItem(FALSE);
       if (!cd->briefDescription().isEmpty() && Config::briefMemDescFlag)
       {
         ol.startMemberDescription();
@@ -200,6 +228,14 @@ void GroupDef::writeDocumentation(OutputList &ol)
   }
   if (allMemberList->count()>0)
   {
+    /* write user defined member groups */
+    MemberGroupListIterator mgli(*memberGroupList);
+    MemberGroup *mg;
+    for (;(mg=mgli.current());++mgli)
+    {
+      mg->writeDeclarations(ol,0,0,0,this);
+    }
+
     allMemberList->writeDeclarations(ol,0,0,0,this,0,0); 
   }
   ol.endMemberSections();
diff --git a/src/groupdef.h b/src/groupdef.h
index 1032c28..647b10f 100644
--- a/src/groupdef.h
+++ b/src/groupdef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -32,6 +32,8 @@ class NamespaceDef;
 class GroupList;
 class OutputList;
 class NamespaceList;
+class MemberGroupList;
+class MemberGroupDict;
 
 class GroupDef : public Definition
 {
@@ -44,7 +46,8 @@ class GroupDef : public Definition
     void addFile(const FileDef *def); 
     void addClass(const ClassDef *def);
     void addNamespace(const NamespaceDef *def);
-    void addMember(const MemberDef *def);
+    void insertMember(MemberDef *def,int groupId);
+    void addMemberToGroup(MemberDef *def,int groupId);
     void writeDocumentation(OutputList &ol);
     int countMembers() const;
     bool isLinkableInProject()
@@ -74,6 +77,11 @@ class GroupDef : public Definition
     MemberList enumValMembers;
     MemberList funcMembers;
     MemberList varMembers;
+
+    /* user defined member groups */
+    MemberGroupList *memberGroupList;
+    MemberGroupDict *memberGroupDict;
+
 };
 
 class GroupList : public QList<GroupDef>
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 300f75d..5f8863d 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -30,6 +30,9 @@
 
 #define GROUP_COLOR "#ff8080"
 
+//#define DBG_HTML(x) x;
+#define DBG_HTML(x) 
+
 HtmlHelp *HtmlGenerator::htmlHelp = 0;
 
 HtmlGenerator::HtmlGenerator() : OutputGenerator()
@@ -541,9 +544,9 @@ void HtmlGenerator::writeFormula(const char *n,const char *text)
 
 void HtmlGenerator::startMemberList()  
 { 
+  DBG_HTML(t << "<!-- startMemberList -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
-    //t << endl << "<p><table border=0 cellspacing=2 cellpadding=0>" << endl; 
   }
   else
   {
@@ -553,9 +556,9 @@ void HtmlGenerator::startMemberList()
 
 void HtmlGenerator::endMemberList()    
 { 
+  DBG_HTML(t << "<!-- endMemberList -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
-    //t << "</table>" << endl; 
   }
   else
   {
@@ -567,16 +570,17 @@ void HtmlGenerator::endMemberList()
 //  0 = single column right aligned
 //  1 = double column left aligned
 //  2 = single column left aligned
-void HtmlGenerator::startMemberItem(bool inGroup,int annoType) 
+void HtmlGenerator::startMemberItem(int annoType) 
 { 
+  DBG_HTML(t << "<!-- startMemberItem() -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
     t << "<tr>";
-    if (inGroup)
-      t << "<td bgcolor=\"" << GROUP_COLOR << "\">";
-    else
-      t << "<td>";
-    t << "<img src=\"null.gif\"></td><td><img src=\"null.gif\"></td>";
+    //if (inGroup)
+    //  t << "<td bgcolor=\"" << GROUP_COLOR << "\">";
+    //else
+    //t << "<td>";
+    //t << "<img src=\"null.gif\"></td><td><img src=\"null.gif\"></td>";
     switch(annoType)
     {
       case 0:  t << "<td nowrap align=right valign=top>"; break;
@@ -590,26 +594,26 @@ void HtmlGenerator::startMemberItem(bool inGroup,int annoType)
   }
 }
 
-void HtmlGenerator::endMemberItem(bool inGroup,
-                          const char *fileName,const char *headerName,bool) 
+void HtmlGenerator::endMemberItem(bool) 
 { 
+  //DBG_HTML(t << "<!-- endMemberItem(" << (int)inGroup << "," << fileName << "," << headerName << " -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
-    if (inGroup)
-    {
-      t << "&nbsp;</td><td";
-      if (headerName)
-      {
-        t << " align=right valign=top><a class=\"gl\" href=\"" 
-          << fileName << ".html\">&nbsp;" << headerName << "&nbsp;</a>";
-      }
-      else
-      {
-        t << ">";
-      }
-      t << "</td><td bgcolor=\"" << GROUP_COLOR 
-        << "\"><img src=\"null.gif\">";
-    }
+    //if (inGroup)
+    //{
+    //  t << "&nbsp;</td><td";
+    //  if (headerName)
+    //  {
+    //    t << " align=right valign=top><a class=\"gl\" href=\"" 
+    //      << fileName << ".html\">&nbsp;" << headerName << "&nbsp;</a>";
+    //  }
+    //  else
+    //  {
+    //    t << ">";
+    //  }
+    //  t << "</td><td bgcolor=\"" << GROUP_COLOR 
+    //    << "\"><img src=\"null.gif\">";
+    //}
     t << "</td></tr>"; 
   }
   t << endl; 
@@ -617,6 +621,7 @@ void HtmlGenerator::endMemberItem(bool inGroup,
 
 void HtmlGenerator::insertMemberAlign() 
 { 
+  DBG_HTML(t << "<!-- insertMemberAlign -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
     t << "&nbsp;</td><td valign=top>"; 
@@ -625,10 +630,12 @@ void HtmlGenerator::insertMemberAlign()
 
 void HtmlGenerator::startMemberDescription() 
 { 
+  DBG_HTML(t << "<!-- startMemberDescription -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
-    t << "<tr><td><img src=null.gif></td><td><img src=null.gif></td>"
-         "<td></td><td><font size=-1><em>"; 
+    //t << "<tr><td><img src=null.gif></td><td><img src=null.gif></td>"
+    //     "<td></td><td><font size=-1><em>"; 
+    t << "<tr><td>&nbsp;</td><td><font size=-1><em>"; 
   }
   else
   {
@@ -638,6 +645,7 @@ void HtmlGenerator::startMemberDescription()
 
 void HtmlGenerator::endMemberDescription()   
 { 
+  DBG_HTML(t << "<!-- endMemberDescription -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
     t << "</em></font><br><br></td></tr>" << endl; 
@@ -650,6 +658,7 @@ void HtmlGenerator::endMemberDescription()
 
 void HtmlGenerator::startMemberSections()
 {
+  DBG_HTML(t << "<!-- startMemberSections -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
     t << "<table border=0 cellpadding=0 cellspacing=0>" << endl;
@@ -658,6 +667,7 @@ void HtmlGenerator::startMemberSections()
 
 void HtmlGenerator::endMemberSections()
 {
+  DBG_HTML(t << "<!-- endMemberSections -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
     t << "</table>" << endl;
@@ -666,9 +676,10 @@ void HtmlGenerator::endMemberSections()
 
 void HtmlGenerator::startMemberHeader()
 {
+  DBG_HTML(t << "<!-- startMemberHeader -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
-    t << "<tr><td colspan=4><br><h2>";
+    t << "<tr><td colspan=2><br><h2>";
   }
   else
   {
@@ -678,6 +689,7 @@ void HtmlGenerator::startMemberHeader()
 
 void HtmlGenerator::endMemberHeader()
 {
+  DBG_HTML(t << "<!-- endMemberHeader -->" << endl)
   if (Config::htmlAlignMemberFlag)
   {
     t << "</h2></td></tr>" << endl;
@@ -688,39 +700,15 @@ void HtmlGenerator::endMemberHeader()
   }
 }
 
-void HtmlGenerator::memberGroupSpacing(bool inGroup)
-{
-  t << "<tr><td";
-  if (inGroup)
-  {
-         // left vertical table line
-    t << " bgcolor=\"" << GROUP_COLOR << "\" height=1><img src=\"null.gif\">"
-         // white space
-         "</td><td colspan=4></td>"
-         // right vertical table line
-         "<td bgcolor=\"" << GROUP_COLOR << "\"><img src=\"null.gif\">";
-  }
-  else
-  {
-         // one pixel height of whitespace
-    t << " height=1>";
-  }
-  t << "</td></tr>" << endl;
-}
-
-void HtmlGenerator::memberGroupSeparator()
-{
-  t << "<tr><td colspan=6 height=1 bgcolor=\"" << GROUP_COLOR 
-    << "\"><img src=\"null.gif\"></td></tr>" << endl;
-}
-
 void HtmlGenerator::startMemberSubtitle()
 {
-  if (Config::htmlAlignMemberFlag) t << "<tr><td colspan=4>";
+  DBG_HTML(t << "<!-- startMemberSubtitle -->" << endl)
+  if (Config::htmlAlignMemberFlag) t << "<tr><td colspan=2>";
 }
 
 void HtmlGenerator::endMemberSubtitle()
 {
+  DBG_HTML(t << "<!-- endMemberSubtitle -->" << endl)
   if (Config::htmlAlignMemberFlag) t << "<br><br></td></tr>" << endl;
 }
 
@@ -773,7 +761,7 @@ void HtmlGenerator::writeImage(const char *name,const char *,const char *)
 
 void HtmlGenerator::startMemberDoc(const char *,const char *,const char *,const char *) 
 { 
-  t << endl << "<p><table width=100%% cellpadding=2 cellspacing=0 border=0><tr><td class=\"md\"><b>" << endl; 
+  t << endl << "<p><table width=100% cellpadding=2 cellspacing=0 border=0><tr><td class=\"md\"><b>" << endl; 
 }
 
 void HtmlGenerator::endMemberDoc()     
diff --git a/src/htmlgen.h b/src/htmlgen.h
index 24a42fc..d34c712 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -95,11 +95,11 @@ class HtmlGenerator : public OutputGenerator
     void endMemberSubtitle();
     void startMemberList();
     void endMemberList();
-    void startMemberItem(bool,int);
-    void memberGroupSpacing(bool inGroup);
-    void memberGroupSeparator();
+    void startMemberItem(int);
+    //void memberGroupSpacing(bool inGroup);
+    //void memberGroupSeparator();
     void insertMemberAlign();
-    void endMemberItem(bool,const char *,const char *,bool);
+    void endMemberItem(bool);
     void startMemberDescription();
     void endMemberDescription();
 
diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp
index 5da4f2a..66a661b 100644
--- a/src/htmlhelp.cpp
+++ b/src/htmlhelp.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/htmlhelp.h b/src/htmlhelp.h
index 5832f05..e10754a 100644
--- a/src/htmlhelp.h
+++ b/src/htmlhelp.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/image.cpp b/src/image.cpp
index a27447d..4b20aca 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/image.h b/src/image.h
index ae949b6..b78f4af 100644
--- a/src/image.h
+++ b/src/image.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/index.cpp b/src/index.cpp
index 3207d50..b35d2be 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/index.h b/src/index.h
index 4c8be7e..8c54a9b 100644
--- a/src/index.h
+++ b/src/index.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/instdox.cpp b/src/instdox.cpp
index c9ae214..3ab2137 100644
--- a/src/instdox.cpp
+++ b/src/instdox.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/instdox.h b/src/instdox.h
index 7dc29a3..fbb913a 100644
--- a/src/instdox.h
+++ b/src/instdox.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/language.cpp b/src/language.cpp
index 17f0640..39ace77 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/language.h b/src/language.h
index 49dc9fb..8f3bb66 100644
--- a/src/language.h
+++ b/src/language.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 1e36877..5edb999 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -1171,7 +1171,7 @@ void LatexGenerator::writeFormula(const char *,const char *text)
   t << text;
 }
 
-void LatexGenerator::startMemberItem(bool,int annType) 
+void LatexGenerator::startMemberItem(int annType) 
 { 
   if (!insideTabbing)
   {
@@ -1190,7 +1190,7 @@ void LatexGenerator::startMemberItem(bool,int annType)
   }
 }
 
-void LatexGenerator::endMemberItem(bool,const char *,const char *,bool endItem) 
+void LatexGenerator::endMemberItem(bool endItem) 
 {
   if (insideTabbing && endItem)
   {
diff --git a/src/latexgen.h b/src/latexgen.h
index 8aaf8b7..364f86d 100644
--- a/src/latexgen.h
+++ b/src/latexgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -91,10 +91,10 @@ class LatexGenerator : public OutputGenerator
     void endMemberSubtitle() {}
     void startMemberList();
     void endMemberList();
-    void startMemberItem(bool,int);
-    void endMemberItem(bool,const char *,const char *,bool);
-    void memberGroupSpacing(bool) {}
-    void memberGroupSeparator() {}
+    void startMemberItem(int);
+    void endMemberItem(bool);
+    //void memberGroupSpacing(bool) {}
+    //void memberGroupSeparator() {}
     void insertMemberAlign() {}
 
     void writeRuler() { t << endl << endl; /*t << "\\vspace{0.4cm}\\hrule\\vspace{0.2cm}" << endl; */ }
diff --git a/src/logos.cpp b/src/logos.cpp
index 0480d1f..50a5794 100644
--- a/src/logos.cpp
+++ b/src/logos.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/logos.h b/src/logos.h
index 8bfff9f..f6bfd6a 100644
--- a/src/logos.h
+++ b/src/logos.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/mangen.cpp b/src/mangen.cpp
index fbe5a59..e4d155c 100644
--- a/src/mangen.cpp
+++ b/src/mangen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -350,7 +350,7 @@ void ManGenerator::endDescItem()
   firstCol=TRUE;
 }
 
-void ManGenerator::startMemberItem(bool,int annType) 
+void ManGenerator::startMemberItem(int annType) 
 { 
   if (firstCol && !insideTabbing) t << ".in +1c\n";
   t << "\n.ti -1c\n.RI \""; 
@@ -358,7 +358,7 @@ void ManGenerator::startMemberItem(bool,int annType)
   if (annType!=0) insideTabbing=TRUE;
 }
 
-void ManGenerator::endMemberItem(bool,const char *,const char *,bool endItem) 
+void ManGenerator::endMemberItem(bool endItem) 
 { 
   if (endItem)
   {
diff --git a/src/mangen.h b/src/mangen.h
index 610ad9e..7893d2e 100644
--- a/src/mangen.h
+++ b/src/mangen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -91,10 +91,10 @@ class ManGenerator : public OutputGenerator
     void writeListItem();
     void startMemberList();
     void endMemberList();
-    void startMemberItem(bool,int);
-    void endMemberItem(bool,const char *,const char *,bool);
-    void memberGroupSpacing(bool) {}
-    void memberGroupSeparator() {}
+    void startMemberItem(int);
+    void endMemberItem(bool);
+    //void memberGroupSpacing(bool) {}
+    //void memberGroupSeparator() {}
     void writeRuler()    {}
     void writeAnchor(const char *) {}
     void startCodeFragment();
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index b4fdc2d..3c9bcf6 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -253,7 +253,6 @@ MemberDef::MemberDef(const char *t,const char *na,const char *a,const char *e,
   if (type.isNull()) decl=name()+args; else decl=type+" "+name()+args;
   declLine=0;
   defLine=0;
-  grpId=-1;
   memberGroup=0;
   virt=v;
   prot=p;
@@ -435,23 +434,11 @@ void MemberDef::setMemberDefTemplateArguments(ArgumentList *tal)
   }
 }
 
-
-
-void MemberDef::setGroupId(int groupId)
-{ 
-  grpId=groupId; 
-  if (grpId!=-1) 
-  {
-    memberGroup=memberGroupDict[grpId];
-    memberGroup->insertMember(this);
-  }
-}
-
 void MemberDef::writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd,
-                      FileDef *fd,GroupDef *gd,MemberGroup *mg)
+                      FileDef *fd,GroupDef *gd)
 {
   Definition *d;
-  if (mg) d=mg; else if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else if (gd) d=gd;
+  if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else if (gd) d=gd;
   //if (mg)
   //  ol.writeObjectLink(0,mg->getOutputFileBase(),
   //                     anchor(),name());
@@ -471,13 +458,17 @@ void MemberDef::writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd,
 
 void MemberDef::writeDeclaration(OutputList &ol,
                ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
-               int prevGroupId,bool inGroup)
+               bool inGroup
+               )
 {
   int i,l;
   bool hasDocs=hasDocumentation();
   //printf("%s MemberDef::writeDeclaration(): hasDocs %d\n",name().data(),hasDocs);
-  //if (cd) printf("MemberDef: %s in class %s annScope=%d annMemb=%p\n",
+  //if (cd)
+  //{
+  //  printf("MemberDef: %s in class %s annScope=%d annMemb=%p\n",
   //    name().data(),cd->name().data(),annScope,annMemb);
+  //}
 
   // hide members in annonymous scopes 
   // (they are displayed by there parent placeholder)
@@ -492,12 +483,17 @@ void MemberDef::writeDeclaration(OutputList &ol,
   // hide static file & namespace members unless extract private is on
   if (cd==0 && isStatic() && !Config::extractPrivateFlag) return;
 
+  // hide private member that are put into a member group. Non-grouped
+  // members are not rendered anyway.
+  //printf("md->name()=`%s' Protection=%d\n",name().data(),protection());
+  if (inGroup && protection()==Private && !Config::extractPrivateFlag) return;
+
   QCString type=typeString();
   // strip `static' keyword from type
   if (type.left(7)=="static ") type=type.right(type.length()-7);
   // strip `friend' keyword from type
   if (type.left(7)=="friend ") type=type.right(type.length()-7);
-  QRegExp r("@[0-9]+");
+  static QRegExp r("@[0-9]+");
   if ((i=r.match(type,0,&l))==-1 || !enumUsed())
   {
     
@@ -513,34 +509,34 @@ void MemberDef::writeDeclaration(OutputList &ol,
     QCString cname  = d->name();
     QCString cfname = d->getOutputFileBase();
 
-    int gId = inGroup ? -1 : groupId();
-    MemberGroup *mg = (gId!=prevGroupId && gId!=-1) ? memberGroupDict[gId] : 0;
-    const char *gHeader = 0;
-    const char *gFile = 0;
-    if (mg)
-    {
-      gHeader=mg->header();
-      gFile=mg->getOutputFileBase();
-    }
-
-    if (!inGroup)
-    {
-      if (prevGroupId==-1 && gId!=-1)
-      {
-        ol.memberGroupSpacing(FALSE);
-        ol.memberGroupSeparator();
-      }
-      else if (prevGroupId!=-1 && gId==-1)
-      {
-        ol.memberGroupSpacing(TRUE);
-        ol.memberGroupSeparator();
-      }
-      else if (prevGroupId!=-1 && gId!=-1 && prevGroupId!=gId)
-      {
-        ol.memberGroupSpacing(TRUE);
-        ol.memberGroupSeparator();
-      }
-    }
+    //int gId = inGroup ? -1 : groupId();
+    //MemberGroup *mg = (gId!=prevGroupId && gId!=-1) ? memberGroupDict[gId] : 0;
+    //const char *gHeader = 0;
+    //const char *gFile = 0;
+    //if (mg)
+    //{
+    //  gHeader=mg->header();
+    //  gFile=mg->getOutputFileBase();
+    //}
+    //
+    //if (!inGroup)
+    //{
+    //  if (prevGroupId==-1 && gId!=-1)
+    //  {
+    //    ol.memberGroupSpacing(FALSE);
+    //    ol.memberGroupSeparator();
+    //  }
+    //  else if (prevGroupId!=-1 && gId==-1)
+    //  {
+    //    ol.memberGroupSpacing(TRUE);
+    //    ol.memberGroupSeparator();
+    //  }
+    //  else if (prevGroupId!=-1 && gId!=-1 && prevGroupId!=gId)
+    //  {
+    //    ol.memberGroupSpacing(TRUE);
+    //    ol.memberGroupSeparator();
+    //  }
+    //}
     
     HtmlHelp *htmlHelp=0;
     bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag;
@@ -580,7 +576,7 @@ void MemberDef::writeDeclaration(OutputList &ol,
     }
 
     // start a new member declaration
-    ol.startMemberItem(gId!=-1,(annoClassDef || annMemb) ? 1 : 0);
+    ol.startMemberItem(/* gId!=-1,*/(annoClassDef || annMemb) ? 1 : 0);
     
     // If there is no detailed description we need to write the anchor here.
     bool detailsVisible = detailsAreVisible();
@@ -597,14 +593,6 @@ void MemberDef::writeDeclaration(OutputList &ol,
       }
       ol.docify("\n");
     }
-    //else if (!detailsVisible) // when extractAll it true we have to write
-    //                         // a index reference and label in LaTeX because
-    //                         // detailed section not shown in LaTeX
-    //{
-    //  ol.addToIndex(name(),cname);
-    //  ol.addToIndex(cname,name());
-    //  ol.writeLatexLabel(cname,anchor());
-    //}
 
     //printf("member name=%s indDepth=%d\n",name().data(),indDepth);
     if (annoClassDef || annMemb)
@@ -621,16 +609,16 @@ void MemberDef::writeDeclaration(OutputList &ol,
       writeTemplatePrefix(ol,tArgList,FALSE);
     }
     
-    if (i!=-1)
+    if (i!=-1) // render member with annonymous componound as result type.
     {
-      //printf("scopeName=`%s' annonymous=`%s'\n",
-      //    cname.data(),type.mid(i,l).data());
+      //printf("annoClassDef=%p annMemb=%p scopeName=`%s' annonymous=`%s'\n",
+      //    annoClassDef,annMemb,cname.data(),type.mid(i,l).data());
 
       if (annoClassDef)
       {
         //printf("class found!\n");
-        annoClassDef->writeDeclaration(ol,annMemb);
-        ol.startMemberItem(gId!=-1,2);
+        annoClassDef->writeDeclaration(ol,annMemb,inGroup);
+        ol.startMemberItem(2);
         int j;
         for (j=0;j<indDepth;j++) 
         {
@@ -687,19 +675,20 @@ void MemberDef::writeDeclaration(OutputList &ol,
     // write name
     if (!name().isEmpty() && name().at(0)!='@')
     {
-      if (grpId!=-1)
-      {
-        if (annMemb)
-        {
-          //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
-          annMemb->writeLink(ol,cd,nd,fd,gd,inGroup ? memberGroup : 0);
-          annMemb->annUsed=annUsed=TRUE;
-        }
-        else
-          writeLink(ol,0,0,0,0,memberGroup);
-        //ol.writeBoldString(name()); 
-      }
-      else if (isLinkable())
+      //if (grpId!=-1)
+      //{
+      //  if (annMemb)
+      //  {
+      //    //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
+      //    annMemb->writeLink(ol,cd,nd,fd,gd,inGroup ? memberGroup : 0);
+      //    annMemb->annUsed=annUsed=TRUE;
+      //  }
+      //  else
+      //    writeLink(ol,0,0,0,0,memberGroup);
+      //  //ol.writeBoldString(name()); 
+      //}
+      //else 
+      if (isLinkable())
       {
         if (annMemb)
         {
@@ -708,14 +697,13 @@ void MemberDef::writeDeclaration(OutputList &ol,
               annMemb->memberClass(),
               annMemb->getNamespace(),
               annMemb->getFileDef(),
-              annMemb->groupDef(),
-              inGroup ? memberGroup : 0
+              annMemb->groupDef()
                             );
           annMemb->annUsed=annUsed=TRUE;
         }
         else
           //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
-          writeLink(ol,cd,nd,fd,gd,inGroup ? memberGroup : 0);
+          writeLink(ol,cd,nd,fd,gd);
       }
       else // there is a brief member description and brief member 
         // descriptions are enabled or there is no detailed description.
@@ -757,12 +745,11 @@ void MemberDef::writeDeclaration(OutputList &ol,
       ol.endDoxyAnchor();
     }
 
-    ol.endMemberItem(gId!=-1,gFile,gHeader,annoClassDef!=0 && indDepth==0);
+    ol.endMemberItem(annoClassDef!=0 && indDepth==0);
     
     //ol.endMemberItem(gId!=-1,gFile,gHeader,annoClassDef || annMemb);
     // write brief description
-    if (!briefDescription().isEmpty() && Config::briefMemDescFlag && 
-        gId==-1 && !inGroup && !annMemb)
+    if (!briefDescription().isEmpty() && Config::briefMemDescFlag && !annMemb)
     {
       ol.startMemberDescription();
       parseDoc(ol,cname,name(),briefDescription());
@@ -777,8 +764,8 @@ void MemberDef::writeDeclaration(OutputList &ol,
         ol.startEmphasis();
         ol.enableAll();
       }
+      //ol.newParagraph();
       ol.endMemberDescription();
-      ol.newParagraph();
     }
   }
   warnIfUndocumented();
@@ -790,11 +777,11 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
 {
   if (memberClass()==0 && isStatic() && !Config::extractPrivateFlag) return;
   bool hasDocs = detailsAreVisible();
-  //printf("%s MemberDef::writeDocumentation(): hasDocs %d\n",name().data(),hasDocs);
+  //printf("MemberDef::writeDocumentation(): type=`%s' def=`%s'\n",type.data(),definition());
   if (
        (/*memberType()==m &&*/                       // filter member type
-        (Config::extractAllFlag || hasDocs) &&
-        groupId()==-1                                // not in a group
+        (Config::extractAllFlag || hasDocs) 
+        /*&& groupId()==-1 */                        // not in a group
        ) || /* member is part of an annonymous scope that is the type of
              * another member in the list.
              */ 
@@ -819,7 +806,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
     MemberDef *smd;
     if (isEnumValue() && def[0]=='@') def = def.right(def.length()-2);
     int i=0,l,dummy;
-    QRegExp r("@[0-9]+");
+    static QRegExp r("@[0-9]+");
     if (isEnumerate() && r.match(def,0,&l)!=-1) return;
     if (isEnumValue() && (smd = getEnumScope()) 
         && r.match(smd->name(),0,&dummy)==-1) return;
@@ -871,7 +858,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
         ol.docify(def.left(si));
         ol.docify(" { ... } ");
         // last ei characters of def contain pointer/reference specifiers
-        int ni=def.findRev("::");
+        int ni=def.find("::",si);
         if (ni>=ei) ei=ni+2;
         linkifyText(ol,scopeName,name(),def.right(def.length()-ei));
       }
@@ -1209,7 +1196,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
 
         QCString reimplInLine = 
           theTranslator->trReimplementedInList(count);
-        QRegExp marker("@[0-9]+");
+        static QRegExp marker("@[0-9]+");
         int index=0,newIndex,matchLen;
         // now replace all markers in reimplInLine with links to the classes
         while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
@@ -1274,18 +1261,21 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
 
 void MemberDef::warnIfUndocumented()
 {
-  if (memberGroup) return;
+  //if (memberGroup) return;
   ClassDef     *cd = memberClass();
   NamespaceDef *nd = getNamespace();
   FileDef      *fd = getFileDef();
+  GroupDef      *gd = groupDef();
   Definition *d=0;
   const char *t=0;
   if (cd) 
     t="class", d=cd; 
   else if (nd) 
     t="namespace", d=nd; 
-  else 
+  else if (fd)
     t="file", d=fd;
+  else
+    t="group", d=gd;
 
   if (d && d->isLinkable() && !isLinkable() && name().find('@')==-1)
    warn("Warning: Member %s of %s %s is not documented\n",
@@ -1296,10 +1286,11 @@ void MemberDef::warnIfUndocumented()
 bool MemberDef::isLinkableInProject()
 {
   return !name().isEmpty() && name().at(0)!='@' &&
-         ((hasDocumentation() && !isReference()) || 
-          (memberGroup && memberGroup->isLinkableInProject())
+         ((hasDocumentation() && !isReference())  
+          /* || (memberGroup && memberGroup->isLinkableInProject())*/
          ) && 
-         (prot!=Private || Config::extractPrivateFlag || isFriend());
+         (prot!=Private || Config::extractPrivateFlag || isFriend()) && // not a private class member
+         (classDef!=0 || Config::extractPrivateFlag || !isStatic()); // not a private file/namespace member
 }
 
 bool MemberDef::isLinkable()
@@ -1310,7 +1301,7 @@ bool MemberDef::isLinkable()
 bool MemberDef::detailsAreVisible() const          
 { 
   return !documentation().isEmpty() || // has detailed docs
-         (Config::sourceBrowseFlag && startBodyLine!=-1 && bodyDef) ||  // has reference to sources
+         /*(Config::sourceBrowseFlag && startBodyLine!=-1 && bodyDef) ||  // has reference to sources */
          (mtype==Enumeration && docEnumValues) ||  // has enum values
          (mtype==EnumValue && !briefDescription().isEmpty()) || // is doc enum value
          (!briefDescription().isEmpty() && 
@@ -1331,3 +1322,8 @@ bool MemberDef::hasDocumentation()
 { 
   return Definition::hasDocumentation() || (argList!=0 && argList->hasDocumentation()); 
 }
+
+void MemberDef::setMemberGroup(MemberGroup *grp)
+{
+  memberGroup = grp;
+}
diff --git a/src/memberdef.h b/src/memberdef.h
index 928c039..8a7d293 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -65,11 +65,10 @@ class MemberDef : public Definition
    ~MemberDef(); 
     
     void writeLink(OutputList &ol,
-                   ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
-                   MemberGroup *mg);
+                   ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd);
     void writeDeclaration(OutputList &ol,
                    ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
-                   int prevGroupId,bool inGroup); 
+                   bool inGroup); 
     void writeDocumentation(MemberList *ml,OutputList &ol,
                             const char *scopeName/*,MemberType m*/);
     void warnIfUndocumented();
@@ -180,10 +179,8 @@ class MemberDef : public Definition
     NamespaceDef *getNamespace() { return nspace; }
     void setNamespace(NamespaceDef *nd) { nspace=nd; }
 
-    // grouping related members
-    void setGroupId(int groupId);
-    int groupId() const          { return grpId; }
-    QCString groupHeader() const { return grpHeader; }
+    // member group related members
+    void setMemberGroup(MemberGroup *grp);
     MemberGroup *getMemberGroup() const { return memberGroup; }
     
     void setFromAnnonymousScope(bool b) { annScope=b; }    
@@ -237,8 +234,8 @@ class MemberDef : public Definition
     ArgumentList *tArgList;   // template argument list of function template
     ArgumentList *scopeTAL;   // template argument list of class template
     ArgumentList *membTAL;    // template argument list of class template
-    int grpId;                // group id
-    QCString grpHeader;       // group header
+    //int grpId;                // group id
+    //QCString grpHeader;       // group header
     MemberGroup *memberGroup; // group's member definition
 
     GroupDef *group;          // group in which this member is in
diff --git a/src/membergroup.cpp b/src/membergroup.cpp
index 0aa678d..c376632 100644
--- a/src/membergroup.cpp
+++ b/src/membergroup.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -25,19 +25,21 @@
 #include "language.h"
 #include "scanner.h"
 
-static QCString idToName(int id)
-{
-  QCString result;
-  result.sprintf("mgroup_%d",id);
-  return result;
-}
+//static QCString idToName(int id)
+//{
+//  QCString result;
+//  result.sprintf("mgroup_%d",id);
+//  return result;
+//}
 
-MemberGroup::MemberGroup(int id,const char *hdr) : Definition(idToName(id))
+MemberGroup::MemberGroup(int id,const char *hdr,const char *d) /* : Definition(idToName(id)) */
 {
   memberList = new MemberList;
-  grpId = id;
-  grpHeader = hdr;
-  fileName = name();
+  grpId      = id;
+  grpHeader  = hdr;
+  doc        = d;
+  scope      = 0;
+  //printf("Member group docs=`%s'\n",doc.data());
 }
 
 MemberGroup::~MemberGroup()
@@ -45,214 +47,28 @@ MemberGroup::~MemberGroup()
   delete memberList;
 }
 
-void MemberGroup::insertMember(MemberDef *m)
+void MemberGroup::insertMember(MemberDef *md)
 {
-  memberList->append(m);
+  //printf("MemberGroup::insertMember(%s)\n",md->name().data());
+  memberList->append(md);
 }
 
-void MemberGroup::writeDocumentation(OutputList &ol)
-{
-  //printf("Writing documentation for group %s\n",fileName.data());
-
-  if (memberList->count()==0) return; // no member in this group!
-  
-  QCString title = grpHeader.copy();
-  if (title.isEmpty())
-  {
-    title = "Member Group"; // TODO: make translatable.
-  }
-  ol.disable(OutputGenerator::Man);
-  startFile(ol,fileName,title);
-  startTitle(ol,getOutputFileBase());
-  ol.docify(title);
-  endTitle(ol,getOutputFileBase(),name());
-  
-
-  OutputList briefOutput(&ol);
-  if (!briefDescription().isEmpty())
-  {
-    parseDoc(briefOutput,0,0,briefDescription());
-    ol+=briefOutput;
-    ol.writeString(" \n");
-    if (!documentation().isEmpty() || Config::repeatBriefFlag)
-    {
-      //bool htmlEnabled = ol.isEnabled(OutputGenerator::Html);
-      //bool latexEnabled = ol.isEnabled(OutputGenerator::Latex);
-      //if (htmlEnabled) ol.disable(OutputGenerator::Html);
-      //if (latexEnabled) ol.disable(OutputGenerator::Latex);
-      ol.pushGeneratorState();
-      ol.disableAllBut(OutputGenerator::Html);
-      ol.startTextLink(0,"_details");
-      parseText(ol,theTranslator->trMore());
-      ol.endTextLink();
-      ol.popGeneratorState();
-      //if (htmlEnabled) ol.enable(OutputGenerator::Html);
-      //if (latexEnabled) ol.enable(OutputGenerator::Latex);
-    }
-  }
-  // TODO: man page synopsis
-  
-  //if (memberList->count()>0)
-  //{
-  QCString scopeName;
- 
-  MemberDef *md    = memberList->first();
-  ClassDef *cd     = md->memberClass();
-  NamespaceDef *nd = md->getNamespace();
-  FileDef *fd      = md->getFileDef();
-  //printf("member %s brief=`%s' docs=`%s'\n",
-  //     md->name().data(), md->briefDescription().data(),
-  //     md->documentation().data());
-  if (cd)
-  {
-    ol.newParagraph();
-    ol.docify("Inside class ");
-    ol.writeObjectLink(cd->getReference(),
-                       cd->getOutputFileBase(),0,
-                       cd->name()
-                      );
-    scopeName=cd->name().copy();
-  }
-  else if (nd)
-  {
-    ol.newParagraph();
-    ol.docify("Inside namespace ");
-    ol.writeObjectLink(nd->getReference(),
-                       nd->getOutputFileBase(),0,
-                       nd->name()
-                      );
-    scopeName=nd->name().copy();
-  }
-  else if (fd)
-  {
-    ol.newParagraph();
-    ol.docify("#include <");
-    ol.writeObjectLink(fd->getReference(),
-                       fd->getOutputFileBase(),0,
-                       fd->name()
-                      );
-    ol.docify(">");
-  }
-  ol.startMemberSections();
-  memberList->writeDeclarations(ol,cd,nd,fd,0,"Synopsis",0,TRUE);
-  ol.endMemberSections();
-
-  if ((!briefDescription().isEmpty() && Config::repeatBriefFlag) || 
-      !documentation().isEmpty())
-  {
-    ol.writeRuler();
-    //bool latexOn = ol.isEnabled(OutputGenerator::Latex);
-    //if (latexOn) ol.disable(OutputGenerator::Latex);
-    ol.pushGeneratorState();
-    ol.disableAllBut(OutputGenerator::Html);
-    ol.writeAnchor("_details");
-    //if (latexOn) ol.enable(OutputGenerator::Latex);
-    ol.popGeneratorState();
-    ol.startGroupHeader();
-    parseText(ol,theTranslator->trDetailedDescription());
-    ol.endGroupHeader();
 
-    // repeat brief description
-    if (!briefDescription().isEmpty() && Config::repeatBriefFlag)
-    {
-      ol+=briefOutput;
-      ol.newParagraph();
-    }
-    // write documentation
-    if (!documentation().isEmpty())
-    {
-      parseDoc(ol,scopeName,0,documentation()+"\n");
-    }
-  }
-
-//  memberList->countDocMembers(TRUE);
-//   
-//  if ( memberList->defineCount()>0 )
-//  {
-//    ol.writeRuler();
-//    ol.startGroupHeader();
-//    parseText(ol,theTranslator->trDefineDocumentation());
-//    ol.endGroupHeader();
-//    writeMemberDocs(ol,memberList,scopeName,MemberDef::Define);
-//  }
-//  
-//  if ( memberList->protoCount()>0 )
-//  {
-//    ol.writeRuler();
-//    ol.startGroupHeader();
-//    parseText(ol,theTranslator->trFunctionPrototypeDocumentation());
-//    ol.endGroupHeader();
-//    writeMemberDocs(ol,memberList,scopeName,MemberDef::Prototype);
-//  }
-//
-//  if ( memberList->typedefCount()>0 )
-//  {
-//    ol.writeRuler();
-//    ol.startGroupHeader();
-//    parseText(ol,theTranslator->trTypedefDocumentation());
-//    ol.endGroupHeader();
-//    writeMemberDocs(ol,memberList,scopeName,MemberDef::Typedef);
-//  }
-//  
-//  if ( memberList->enumCount()>0 )
-//  {
-//    ol.writeRuler();
-//    ol.startGroupHeader();
-//    parseText(ol,theTranslator->trEnumerationTypeDocumentation());
-//    ol.endGroupHeader();
-//    writeMemberDocs(ol,memberList,scopeName,MemberDef::Enumeration);
-//  }
-//
-//  if ( memberList->enumValueCount()>0 )
-//  {
-//    ol.writeRuler();
-//    ol.startGroupHeader();
-//    parseText(ol,theTranslator->trEnumerationValueDocumentation());
-//    ol.endGroupHeader();
-//    writeMemberDocs(ol,memberList,scopeName,MemberDef::EnumValue);
-//  }
-//
-//  if ( memberList->funcCount()>0 )
-//  {
-//    ol.writeRuler();
-//    ol.startGroupHeader();
-//    parseText(ol,theTranslator->trFunctionDocumentation());
-//    ol.endGroupHeader();
-//    writeMemberDocs(ol,memberList,scopeName,MemberDef::Function);
-//  }
-//  
-//  if ( memberList->varCount()>0 )
-//  {
-//    ol.writeRuler();
-//    ol.startGroupHeader();
-//    parseText(ol,theTranslator->trVariableDocumentation());
-//    ol.endGroupHeader();
-//    writeMemberDocs(ol,memberList,scopeName,MemberDef::Variable);
-//  }
-  
-  endFile(ol); 
-  ol.enable(OutputGenerator::Man);
-}
-
-bool MemberGroup::isLinkableInProject()
+void MemberGroup::setAnchors()
 {
-  return hasDocumentation() && !isReference();
+  ::setAnchors('z',memberList,grpId);
 }
-bool MemberGroup::isLinkable()
+
+void MemberGroup::writeDeclarations(OutputList &ol,
+               ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
 {
-  return isLinkableInProject() || isReference();
+  memberList->writeDeclarations(ol,cd,nd,fd,gd,grpHeader,doc,TRUE);
 }
 
-void MemberGroup::addDocumentation()
+void MemberGroup::writePlainDeclarations(OutputList &ol,
+               ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
 {
-  //printf("adding documentation for membergroup %s\n",name().data());
-  MemberListIterator mli(*memberList);
-  MemberDef *md;
-  for (;(md=mli.current());++mli)
-  {
-    //printf("Adding docs `%s' `%s'\n",md->briefDescription().data(),md->documentation().data());
-    setBriefDescription(briefDescription()+"\n"+md->briefDescription());
-    setDocumentation(documentation()+"\n"+md->documentation()); 
-  }
-  //printf("isLinkable()=%d\n",isLinkable());
+  //printf("MemberGroup::writePlainDeclarations() memberList->count()=%d\n",memberList->count());
+  memberList->writePlainDeclarations(ol,cd,nd,fd,gd,TRUE);
 }
+
diff --git a/src/membergroup.h b/src/membergroup.h
index 8826f1b..d96db26 100644
--- a/src/membergroup.h
+++ b/src/membergroup.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -21,32 +21,41 @@
 #include <qlist.h>
 #include <qintdict.h>
 
-#include "definition.h"
+//#include "definition.h"
+
+#define NOGROUP -1
 
 class MemberDef;
+class ClassDef;
+class NamespaceDef;
+class FileDef;
 class MemberList;
+class GroupDef;
 class OutputList;
+class Definition;
 
-class MemberGroup : public Definition
+class MemberGroup /* : public Definition */
 {
   public:
-    MemberGroup(int id,const char *header);
+    MemberGroup(int id,const char *header,const char *docs);
    ~MemberGroup();
     QCString header() const { return grpHeader; }
-    QCString getOutputFileBase() const { return fileName; }
+    int groupId() const { return grpId; }
     void insertMember(MemberDef *);
-    void writeDocumentation(OutputList &ol);
-    MemberList *members() const { return memberList; } 
-    void addDocumentation();
-
-    bool isLinkableInProject();
-    bool isLinkable();
+    void setAnchors();
+    void writePlainDeclarations(OutputList &ol,
+               ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd);
+    void writeDeclarations(OutputList &ol,
+               ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd);
+    QCString documentation() { return doc; }
 
   private: 
-    MemberList *memberList;             // list of all members in the group
+    MemberList     *memberList;      // list of all members in the group
     int grpId;
     QCString grpHeader;
     QCString fileName;                   // base name of the generated file
+    Definition *scope;
+    QCString doc;
 };
 
 class MemberGroupList : public QList<MemberGroup>
@@ -67,4 +76,12 @@ class MemberGroupDict : public QIntDict<MemberGroup>
    ~MemberGroupDict() {}
 };
 
+class MemberGroupDictIterator : public QIntDictIterator<MemberGroup>
+{
+  public:
+    MemberGroupDictIterator(const MemberGroupDict &d) : 
+      QIntDictIterator<MemberGroup>(d) {}
+   ~MemberGroupDictIterator() {}
+};
+
 #endif
diff --git a/src/memberlist.cpp b/src/memberlist.cpp
index 1e3057f..6e05bff 100644
--- a/src/memberlist.cpp
+++ b/src/memberlist.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -41,7 +41,7 @@ int MemberList::compareItems(GCI item1, GCI item2)
   return strcmp(c1->name(),c2->name());
 }
 
-void MemberList::countDecMembers()
+void MemberList::countDecMembers(bool inGroup)
 {
   varCnt=funcCnt=enumCnt=enumValCnt=typeCnt=protoCnt=defCnt=friendCnt=0;
   m_count=0;
@@ -57,7 +57,8 @@ void MemberList::countDecMembers()
          (md->isEnumerate() &&
           md->hasDocumentedEnumValues()
          )
-        )
+        ) && inGroup==(md->getMemberGroup()!=0) &&
+        !(inGroup && md->protection()==Private && !Config::extractPrivateFlag)
        )
     {
       switch(md->memberType())
@@ -84,9 +85,10 @@ void MemberList::countDecMembers()
     }
     md=next();
   }
+  //printf("MemberList::countDecMembers(%d)=%d\n",inGroup,m_count);
 }
 
-void MemberList::countDocMembers(bool inGroup)
+void MemberList::countDocMembers()
 {
   /*varCnt=funcCnt=enumCnt=enumValCnt=typeCnt=protoCnt=defCnt=friendCnt=0;*/
   m_count=0;
@@ -99,8 +101,7 @@ void MemberList::countDocMembers(bool inGroup)
       !(md->memberClass()==0 && md->isStatic() && !Config::extractPrivateFlag);
 
     if (visibleIfStatic && 
-        (Config::extractAllFlag || md->detailsAreVisible()) &&
-        (md->groupId()==-1 || inGroup)
+        (Config::extractAllFlag || md->detailsAreVisible()) 
        )
     {
       static QRegExp r("@[0-9]+");
@@ -191,54 +192,69 @@ MemberListIterator::MemberListIterator(const QList<MemberDef> &l) :
 
 void MemberList::writePlainDeclarations(OutputList &ol,
                        ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
-                       bool inGroup)
+                       bool inGroup
+                      )
 {
-  countDecMembers();
+  countDecMembers(inGroup);
+  //printf("writePlainDeclaration() totalCount()=%d defineCount()=%d\n",totalCount(),defineCount());
   if (totalCount()==0) return; // no members in this list
   
   ol.pushGeneratorState();
 
-  int prevGroupId = -1;
-  bool sectionPerType = fd || nd || gd;
+  //int prevGroupId = -1;
+  bool sectionPerType = !inGroup && (fd || nd || gd);
   if (!sectionPerType) ol.startMemberList();
   MemberDef *md;
 
-  if (sectionPerType && defineCount()>0)
+  if (defineCount()>0)
   {
-    ol.startMemberHeader();
-    parseText(ol,theTranslator->trDefines());
-    ol.endMemberHeader();
-    ol.startMemberList();
+    if (sectionPerType)
+    {
+      ol.startMemberHeader();
+      parseText(ol,theTranslator->trDefines());
+      ol.endMemberHeader();
+      ol.startMemberList();
+    }
     MemberListIterator mli(*this);
     for ( ; (md=mli.current()); ++mli )
     {
+      //printf("md->isDefined()=%d inGroup=%d md->getMemberGroup()=%p\n",
+      //   md->isDefine(),inGroup,md->getMemberGroup());
       if (md->isDefine() && 
-          (md->argsString() || md->hasDocumentation() || Config::extractAllFlag)
+          (md->argsString() || md->hasDocumentation() || Config::extractAllFlag) &&
+          inGroup==(md->getMemberGroup()!=0)          
          ) 
       {
-        md->writeDeclaration(ol,cd,nd,fd,gd,prevGroupId,inGroup);
-        prevGroupId = md->groupId();
+        md->writeDeclaration(ol,cd,nd,fd,gd,inGroup);
       }
     }
-    ol.endMemberList();
+    if (sectionPerType)
+    {
+      ol.endMemberList();
+    }
   }
   
-  if (sectionPerType && protoCount()>0)
+  if (protoCount()>0)
   {
-    ol.startMemberHeader();
-    parseText(ol,theTranslator->trFuncProtos());
-    ol.endMemberHeader();
-    ol.startMemberList();
+    if (sectionPerType)
+    {
+      ol.startMemberHeader();
+      parseText(ol,theTranslator->trFuncProtos());
+      ol.endMemberHeader();
+      ol.startMemberList();
+    }
     MemberListIterator mli(*this);
     for ( ; (md=mli.current()); ++mli )
     {
-      if (md->isPrototype()) 
+      if (md->isPrototype() && inGroup==(md->getMemberGroup()!=0)) 
       {
-        md->writeDeclaration(ol,cd,nd,fd,gd,prevGroupId,inGroup);
-        prevGroupId = md->groupId();
+        md->writeDeclaration(ol,cd,nd,fd,gd,inGroup);
       }
     }
-    ol.endMemberList();
+    if (sectionPerType)
+    {
+      ol.endMemberList();
+    }
   }
   
   if (typedefCount()>0)
@@ -254,10 +270,9 @@ void MemberList::writePlainDeclarations(OutputList &ol,
     MemberListIterator mli(*this);
     for ( ; (md=mli.current()) ; ++mli )
     {
-      if (md->isTypedef()) 
+      if (md->isTypedef() && inGroup==(md->getMemberGroup()!=0)) 
       {
-        md->writeDeclaration(ol,cd,nd,fd,gd,prevGroupId,inGroup);
-        prevGroupId = md->groupId();
+        md->writeDeclaration(ol,cd,nd,fd,gd,inGroup);
       }
     }
     if (sectionPerType) ol.endMemberList();
@@ -276,10 +291,11 @@ void MemberList::writePlainDeclarations(OutputList &ol,
     MemberListIterator mli(*this);
     for ( ; (md=mli.current()) ; ++mli )
     {
+      if (md->protection()==Private && !Config::extractPrivateFlag) continue;
       /*bool hasDocs=md->hasDocumentation();*/
       QCString type=md->typeString();
       type=type.stripWhiteSpace();
-      if (md->isEnumerate() /*&& (hasDocs || !Config::hideMemberFlag)*/) 
+      if (md->isEnumerate() && inGroup==(md->getMemberGroup()!=0) /*&& (hasDocs || !Config::hideMemberFlag)*/) 
       {
         if (!Config::hideMemberFlag ||                // do not hide undocumented members or
             !md->documentation().isEmpty() || // member has detailed descr. or
@@ -308,7 +324,7 @@ void MemberList::writePlainDeclarations(OutputList &ol,
               if (!Config::genTagFile.isEmpty())
                 tagFile << md->name() << " " << md->anchor() 
                   << " \"\"" << endl;
-              md->writeLink(typeDecl,cd,nd,fd,gd,0);
+              md->writeLink(typeDecl,cd,nd,fd,gd);
             }
             else
             {
@@ -329,7 +345,7 @@ void MemberList::writePlainDeclarations(OutputList &ol,
                 if (!Config::genTagFile.isEmpty())
                   tagFile << fmd->name() << " " << fmd->anchor() 
                     << " \"" << fmd->argsString() << "\"";
-                fmd->writeLink(typeDecl,cd,nd,fd,gd,0);
+                fmd->writeLink(typeDecl,cd,nd,fd,gd);
               }
               else // no docs for this enum value
               {
@@ -363,18 +379,14 @@ void MemberList::writePlainDeclarations(OutputList &ol,
           }
           if (enumVars==0) // no variable of this enum type
           {
-            int gId = md->groupId();
-            const char *gHeader = (gId!=prevGroupId && gId!=-1) ? 
-                            memberGroupDict[gId]->header().data() : 0;
-            ol.startMemberItem(gId!=-1,0);
+            ol.startMemberItem(0);
             ol.writeString("enum ");
             ol.insertMemberAlign();
             ol+=typeDecl;
-            ol.endMemberItem(gId!=-1,md->anchor(),gHeader,FALSE);
+            ol.endMemberItem(FALSE);
             //QCString brief=md->briefDescription();
             //brief=brief.stripWhiteSpace();
-            if (!md->briefDescription().isEmpty() && Config::briefMemDescFlag
-                && gId==-1 && !inGroup)
+            if (!md->briefDescription().isEmpty() && Config::briefMemDescFlag)
             {
               ol.startMemberDescription();
               parseDoc(ol,cd?cd->name().data():0,
@@ -391,13 +403,12 @@ void MemberList::writePlainDeclarations(OutputList &ol,
                 ol.enableAll();
               }
               ol.endMemberDescription();
-              ol.disable(OutputGenerator::Man);
-              ol.newParagraph();
-              ol.enable(OutputGenerator::Man);
+              //ol.disable(OutputGenerator::Man);
+              //ol.newParagraph();
+              //ol.enable(OutputGenerator::Man);
             }
           }
           md->warnIfUndocumented();
-          prevGroupId = md->groupId();
         }
       } // md->isEnumerate()
     } // enum loop
@@ -419,11 +430,11 @@ void MemberList::writePlainDeclarations(OutputList &ol,
     {
       if (
           ( md->isFunction() || md->isSignal() || md->isSlot()) &&
-          ( !md->isRelated() || md->memberClass() )
+          ( !md->isRelated() || md->memberClass() ) &&
+          inGroup==(md->getMemberGroup()!=0)
          ) 
       {
-        md->writeDeclaration(ol,cd,nd,fd,gd,prevGroupId,inGroup);
-        prevGroupId = md->groupId();
+        md->writeDeclaration(ol,cd,nd,fd,gd,inGroup);
       }
     }
     if (sectionPerType) ol.endMemberList();
@@ -434,48 +445,41 @@ void MemberList::writePlainDeclarations(OutputList &ol,
     MemberListIterator mli(*this);
     for ( ; (md=mli.current()) ; ++mli )
     {
-      if (md->isFriend()) 
+      if (md->isFriend() && inGroup==(md->getMemberGroup()!=0)) 
       {
         QCString type=md->typeString();
         //printf("Friend: type=%s name=%s\n",type.data(),md->name().data());
         if (md->hasDocumentation() && type!="friend class")
         {
-          md->writeDeclaration(ol,cd,nd,fd,gd,prevGroupId,inGroup);
-          prevGroupId = md->groupId();
+          md->writeDeclaration(ol,cd,nd,fd,gd,inGroup);
         }
         else // friend is undocumented as a member but it is a class, 
              // so generate a link to the class if that is documented.
         {
-          int gId = md->groupId();
-          const char *gHeader = (gId!=prevGroupId && gId!=-1) ? 
-                          memberGroupDict[gId]->header().data() : 0;
           ClassDef *cd=getClass(md->name());
           if (md->hasDocumentation()) // friend is documented
           {
-            ol.startMemberItem(gId!=-1,0);
+            ol.startMemberItem(0);
             ol.docify("class ");
             ol.insertMemberAlign();
             ol.writeObjectLink(0,0,md->anchor(),md->name());
-            ol.endMemberItem(gId!=-1,md->anchor(),gHeader,FALSE);
-            prevGroupId = md->groupId();
+            ol.endMemberItem(FALSE);
           }
           else if (cd && cd->isLinkable()) // class is documented
           {
-            ol.startMemberItem(gId!=-1,0);
+            ol.startMemberItem(0);
             ol.docify("class ");
             ol.insertMemberAlign();
             ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name());
-            ol.endMemberItem(gId!=-1,md->anchor(),gHeader,FALSE);
-            prevGroupId = md->groupId();
+            ol.endMemberItem(FALSE);
           }
           else if (!Config::hideMemberFlag) // no documentation
           {
-            ol.startMemberItem(gId!=-1,0);
+            ol.startMemberItem(0);
             ol.docify("class ");
             ol.insertMemberAlign();
             ol.writeBoldString(md->name());
-            ol.endMemberItem(gId!=-1,md->anchor(),gHeader,FALSE);
-            prevGroupId = md->groupId();
+            ol.endMemberItem(FALSE);
           }
         }
       }
@@ -495,10 +499,9 @@ void MemberList::writePlainDeclarations(OutputList &ol,
     MemberListIterator mli(*this);
     for ( ; (md=mli.current()) ; ++mli )
     {
-      if (md->isVariable()) 
+      if (md->isVariable() && inGroup==(md->getMemberGroup()!=0)) 
       {
-        md->writeDeclaration(ol,cd,nd,fd,gd,prevGroupId,inGroup);
-        prevGroupId = md->groupId();
+        md->writeDeclaration(ol,cd,nd,fd,gd,inGroup);
       }
     }
     if (sectionPerType) ol.endMemberList();
@@ -511,23 +514,18 @@ void MemberList::writePlainDeclarations(OutputList &ol,
     MemberListIterator mli(*this);
     for  ( ; (md=mli.current()) ; ++mli )
     {
-      if (md->fromAnnonymousScope() && !md->annonymousDeclShown())
+      if (md->fromAnnonymousScope() && !md->annonymousDeclShown()
+          && inGroup==(md->getMemberGroup()!=0))
       {
         md->setFromAnnonymousScope(FALSE);
-        md->writeDeclaration(ol,cd,nd,fd,gd,prevGroupId,inGroup);
+        md->writeDeclaration(ol,cd,nd,fd,gd,inGroup);
         md->setFromAnnonymousScope(TRUE);
-        prevGroupId = md->groupId();
       }
     }
   }
  
   if (!sectionPerType) { ol.endMemberList(); /*ol.writeChar('\n');*/ }
 
-  if (prevGroupId!=-1 && !inGroup)
-  {
-    ol.memberGroupSpacing(TRUE);
-    ol.memberGroupSeparator();
-  }
   ol.popGeneratorState();
 }
 
@@ -535,7 +533,7 @@ void MemberList::writeDeclarations(OutputList &ol,
              ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
              const char *title,const char *subtitle,bool inGroup)
 {
-  countDecMembers();
+  countDecMembers(inGroup);
   if (totalCount()==0) return;
   if (title) 
   {
@@ -543,10 +541,14 @@ void MemberList::writeDeclarations(OutputList &ol,
     parseText(ol,title);
     ol.endMemberHeader();
   }
-  if (subtitle) 
+  if (subtitle && subtitle[0]!=0) 
   {
+    //printf("subtitle=`%s'\n",subtitle);
     ol.startMemberSubtitle();
-    parseText(ol,subtitle);
+    if (inGroup)
+      parseDoc(ol,0,0,subtitle);
+    else
+      parseText(ol,subtitle);
     ol.endMemberSubtitle();
   }
 
diff --git a/src/memberlist.h b/src/memberlist.h
index 049c2d4..b20a510 100644
--- a/src/memberlist.h
+++ b/src/memberlist.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -38,8 +38,8 @@ class MemberList : public QList<MemberDef>
     int protoCount() const     { return protoCnt;   }
     int defineCount() const    { return defCnt;     }
     int friendCount() const    { return friendCnt;  }
-    void countDecMembers();
-    void countDocMembers(bool inGroup=FALSE);
+    void countDecMembers(bool inGroup);
+    void countDocMembers();
     int totalCount() const 
          { return //varCnt+funcCnt+enumCnt+enumValCnt+typeCnt+
                   //protoCnt+defCnt+friendCnt; 
diff --git a/src/membername.cpp b/src/membername.cpp
index 676f149..39c1b8d 100644
--- a/src/membername.cpp
+++ b/src/membername.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/membername.h b/src/membername.h
index 3491de3..6a66a31 100644
--- a/src/membername.h
+++ b/src/membername.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/message.cpp b/src/message.cpp
index f7c8654..50e8adb 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/message.h b/src/message.h
index a053ff8..638fe58 100644
--- a/src/message.h
+++ b/src/message.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index 3360eee..d9da522 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -33,13 +33,17 @@ NamespaceDef::NamespaceDef(const char *name,const char *ref) : Definition(name)
   //memList = new MemberList;
   usingList = 0;
   setReference(ref);
+  memberGroupList = new MemberGroupList;
+  memberGroupList->setAutoDelete(TRUE);
+  memberGroupDict = new MemberGroupDict(1009);
 }
 
 NamespaceDef::~NamespaceDef()
 {
   delete classList;
-  //delete memList;
   delete usingList;
+  delete memberGroupList;
+  delete memberGroupDict;
 }
 
 void NamespaceDef::insertUsedFile(const char *f)
@@ -52,7 +56,28 @@ void NamespaceDef::insertClass(ClassDef *cd)
   classList->append(cd);
 }
 
-void NamespaceDef::insertMember(MemberDef *md)
+void NamespaceDef::addMemberToGroup(MemberDef *md,int groupId)
+{
+  if (groupId!=-1)
+  {
+    QCString *pGrpHeader = memberHeaderDict[groupId];
+    QCString *pDocs      = memberDocDict[groupId];
+    if (pGrpHeader)
+    {
+      MemberGroup *mg = memberGroupDict->find(groupId);
+      if (mg==0)
+      {
+        mg = new MemberGroup(groupId,*pGrpHeader,pDocs ? pDocs->data() : 0);
+        memberGroupDict->insert(groupId,mg);
+        memberGroupList->append(mg);
+      }
+      mg->insertMember(md);
+      md->setMemberGroup(mg);
+    }
+  }
+}
+
+void NamespaceDef::insertMember(MemberDef *md,int groupId)
 {
   //memList->append(md);
   allMemberList.append(md); 
@@ -66,13 +91,20 @@ void NamespaceDef::insertMember(MemberDef *md)
     case MemberDef::Prototype:    protoMembers.inSort(md); break;
     case MemberDef::Define:       defineMembers.inSort(md); break;
     default:
-       err("NamespaceDef::insertMembers(): unexpected member insert in file!\n");
+       err("NamespaceDef::insertMembers(): unexpected member inserted in namespace!\n");
   }
+  addMemberToGroup(md,groupId);
 }
 
 void NamespaceDef::computeAnchors()
 {
   setAnchors('a',&allMemberList);
+  //MemberGroupListIterator mgli(*memberGroupList);
+  //MemberGroup *mg;
+  //for (;(mg=mgli.current());++mgli)
+  //{
+  //  mg->setAnchors();
+  //}
 }
 
 void NamespaceDef::writeDocumentation(OutputList &ol)
@@ -131,7 +163,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol)
           clName = clName.right(clName.length()-name().length()-2);
         }
         
-        ol.startMemberItem(FALSE,0);
+        ol.startMemberItem(0);
         switch (cd->compoundType())
         {
           case ClassDef::Class:      ol.writeString("class");      break;
@@ -156,12 +188,20 @@ void NamespaceDef::writeDocumentation(OutputList &ol)
           ol.docify(clName);
           ol.endBold();
         }
-        ol.endMemberItem(FALSE,0,0,FALSE);
+        ol.endMemberItem(FALSE);
       }
       cd=classList->next();
     }
     if (found) ol.endMemberList();
   }
+
+  /* write user defined member groups */
+  MemberGroupListIterator mgli(*memberGroupList);
+  MemberGroup *mg;
+  for (;(mg=mgli.current());++mgli)
+  {
+    mg->writeDeclarations(ol,0,this,0,0);
+  }
   
   allMemberList.writeDeclarations(ol,0,this,0,0,0,0);
   ol.endMemberSections();
diff --git a/src/namespacedef.h b/src/namespacedef.h
index f3df7d5..ddf9fa8 100644
--- a/src/namespacedef.h
+++ b/src/namespacedef.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -28,6 +28,8 @@ class OutputList;
 class ClassList;
 class MemberDef;
 class NamespaceList;
+class MemberGroupDict;
+class MemberGroupList;
 
 class NamespaceDef : public Definition
 {
@@ -39,7 +41,8 @@ class NamespaceDef : public Definition
     void insertUsedFile(const char *fname);
     void writeDocumentation(OutputList &ol);
     void insertClass(ClassDef *cd);
-    void insertMember(MemberDef *md);
+    void insertMember(MemberDef *md,int groupId);
+    void addMemberToGroup(MemberDef *md,int groupId);
     void computeAnchors();
     int countMembers();
     void addUsingDirective(NamespaceDef *nd);
@@ -83,6 +86,10 @@ class NamespaceDef : public Definition
     MemberList enumValMembers;
     MemberList funcMembers;
     MemberList varMembers;
+
+    /* user defined member groups */
+    MemberGroupList    *memberGroupList;
+    MemberGroupDict    *memberGroupDict;
 };
 
 class NamespaceList : public QList<NamespaceDef>
diff --git a/src/outputgen.cpp b/src/outputgen.cpp
index 5e176b8..851a670 100644
--- a/src/outputgen.cpp
+++ b/src/outputgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/outputgen.h b/src/outputgen.h
index 31291b0..36e806d 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -100,10 +100,10 @@ class OutputGenerator
     virtual void endMemberSubtitle() = 0;
     virtual void startMemberList()  = 0;
     virtual void endMemberList()    = 0;
-    virtual void startMemberItem(bool,int) = 0;
-    virtual void endMemberItem(bool,const char *,const char *,bool) = 0;
-    virtual void memberGroupSpacing(bool) = 0;
-    virtual void memberGroupSeparator() = 0;
+    virtual void startMemberItem(int) = 0;
+    virtual void endMemberItem(bool) = 0;
+    //virtual void memberGroupSpacing(bool) = 0;
+    //virtual void memberGroupSeparator() = 0;
     virtual void insertMemberAlign() = 0;
 
     virtual void writeRuler() = 0;
diff --git a/src/outputlist.cpp b/src/outputlist.cpp
index 22a8008..fadc43b 100644
--- a/src/outputlist.cpp
+++ b/src/outputlist.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -272,7 +272,6 @@ FORALL3(const char *a1,const char *a2,const char *a3,a1,a2,a3)
 FORALL3(const char *a1,const char *a2,bool a3,a1,a2,a3)
 FORALL3(uchar a1,uchar a2,uchar a3,a1,a2,a3)
 FORALL4(const char *a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4)
-FORALL4(bool a1,const char *a2,const char *a3,bool a4,a1,a2,a3,a4)
 
 
 //--------------------------------------------------------------------------
diff --git a/src/outputlist.h b/src/outputlist.h
index 71388f4..7357d9f 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -159,14 +159,14 @@ class OutputList
     { forall(&OutputGenerator::startMemberList); }
     void endMemberList() 
     { forall(&OutputGenerator::endMemberList); }
-    void startMemberItem(bool b1,int i1) 
-    { forall(&OutputGenerator::startMemberItem,b1,i1); }
-    void endMemberItem(bool b1,const char *n1,const char *n2,bool b2) 
-    { forall(&OutputGenerator::endMemberItem,b1,n1,n2,b2); }
-    void memberGroupSpacing(bool b) 
-    { forall(&OutputGenerator::memberGroupSpacing,b); }
-    void memberGroupSeparator() 
-    { forall(&OutputGenerator::memberGroupSeparator); }
+    void startMemberItem(int i1) 
+    { forall(&OutputGenerator::startMemberItem,i1); }
+    void endMemberItem(bool b2) 
+    { forall(&OutputGenerator::endMemberItem,b2); }
+    //void memberGroupSpacing(bool b) 
+    //{ forall(&OutputGenerator::memberGroupSpacing,b); }
+    //void memberGroupSeparator() 
+    //{ forall(&OutputGenerator::memberGroupSeparator); }
     void insertMemberAlign() 
     { forall(&OutputGenerator::insertMemberAlign); }
     void writeRuler() 
@@ -381,7 +381,6 @@ class OutputList
     FORALLPROTO3(const char *,const char *,const char *);
     FORALLPROTO3(ClassDiagram &,const char *,const char *);
     FORALLPROTO4(const char *,const char *,const char *,const char *);
-    FORALLPROTO4(bool,const char *,const char *,bool);
   
     OutputList(const OutputList &ol);
     QList<OutputGenerator> *outputs;
diff --git a/src/pre.h b/src/pre.h
index 807c523..42fddbd 100644
--- a/src/pre.h
+++ b/src/pre.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/pre.l b/src/pre.l
index c450d39..3573062 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -777,7 +777,7 @@ void addDefine()
     functionNameDict.insert(g_defName,mn);
   }
   mn->append(md);
-  if (g_yyFileDef) g_yyFileDef->insertMember(md);
+  if (g_yyFileDef) g_yyFileDef->insertMember(md,-1);
   
   //Define *d;
   //if ((d=defineDict[g_defName])==0) defineDict.insert(g_defName,newDefine()); 
diff --git a/src/qtbc.h b/src/qtbc.h
index 90763c8..d5e00f3 100644
--- a/src/qtbc.h
+++ b/src/qtbc.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index c0357b1..a3e3ea6 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Parker Waechter & Dimitri van Heesch.
  *
@@ -1516,35 +1516,20 @@ void RTFGenerator::writeFormula(const char *,const char *text)
   t << text;
 }
 
-void RTFGenerator::startMemberItem(bool,int) 
+void RTFGenerator::startMemberItem(int) 
 { 
   t << Rtf_Style_Reset << Rtf_BList_DepthStyle() << endl; // set style to apropriate depth
 }
 
-void RTFGenerator::endMemberItem(bool,const char *,const char *,bool) 
+void RTFGenerator::endMemberItem(bool) 
 {
   newParagraph();
-
-#ifdef DELETEDCODE
-  if (insideTabbing && endItem)
-  {
-    t << endl << "\\end{tabbing}";
-    //printf("RTFGenerator::endMemberItem() insideTabbing=FALSE\n");
-    insideTabbing=FALSE;
-  }
-  if (insideTabbing)
-  {
-    t << "\\\\";
-  } 
-  t << endl; 
-#endif
 }
 
 void RTFGenerator::writeAnchor(const char *name) 
 { 
   t << "{\\bkmkstart " << formatBmkStr(name) << "}" << endl;
   t << "{\\bkmkend " << formatBmkStr(name) << "}" << endl;
-  //t << "\\label{" << name << "}" << endl; 
 }
 
 void RTFGenerator::WriteRTFReference(const char *label)
diff --git a/src/rtfgen.h b/src/rtfgen.h
index 77e278b..50aa302 100644
--- a/src/rtfgen.h
+++ b/src/rtfgen.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Parker Waechter & Dimitri van Heesch.
  *
@@ -92,10 +92,10 @@ class RTFGenerator : public OutputGenerator
     void endMemberSubtitle(); 
     void startMemberList();
     void endMemberList();
-    void startMemberItem(bool,int);
-    void endMemberItem(bool,const char *,const char *,bool);
-    void memberGroupSpacing(bool) {}
-    void memberGroupSeparator() {}
+    void startMemberItem(int);
+    void endMemberItem(bool);
+    //void memberGroupSpacing(bool) {}
+    //void memberGroupSeparator() {}
     void insertMemberAlign() {}
 
     void writeRuler(){RtfwriteRuler_thin();};
diff --git a/src/scanner.h b/src/scanner.h
index d1c8f98..f37aaba 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -24,11 +24,8 @@
 
 #include "entry.h"
 #include "code.h"
-#include "membergroup.h"
 
 class OutputList;
-//typedef QIntDict<MemberGroup> MemberGroupDict;
-typedef QIntDictIterator<MemberGroup> MemberGroupDictIterator;
 
 extern void parseMain(Entry *);
 extern void parseDoc(OutputList &ol,const char *clName, const char *memName,
@@ -37,6 +34,4 @@ extern void parseExample(OutputList &ol,const QCString &docString,
                            const char *fileName);
 extern void parseText(OutputList &ol,const QCString &txtString);
 
-extern MemberGroupDict memberGroupDict;
-
 #endif
diff --git a/src/scanner.l b/src/scanner.l
index c5dc210..97aa140 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -40,6 +40,7 @@
 #include "defargs.h"
 #include "language.h"
 #include "outputlist.h"
+#include "membergroup.h"
 
 #ifndef WIN32
 #include <unistd.h>
@@ -48,7 +49,6 @@
 #define YY_NEVER_INTERACTIVE 1
   
 
-MemberGroupDict memberGroupDict(1009); // dictionary of the member groups heading
   
 /* -----------------------------------------------------------------
  *
@@ -81,7 +81,6 @@ static int              lastSquareContext;
 static int              lastCodeState;
 static int              lastAfterDocContext;
 static int              lastGroupContext;
-static int              lastMemberGroupContext;
 static int              lastFormulaContext;
 static int              lastAnchorContext;
 static int              lastInitializerContext;
@@ -115,7 +114,9 @@ static QCString         exampleName;
 static QCString         htmlUrl,htmlText;
 static QCString         currentIncludeFile;
 static QCString         msType,msName,msArgs;
-static int              memberGroupId = -1;
+static int              memberGroupId = NOGROUP;
+static QCString         memberGroupHeader;
+static QCString         memberGroupDocs;
 static int              includeFileOffset = 0;
 static int              includeFileLength = 0;
 static bool             firstLine;
@@ -196,7 +197,7 @@ static void initParser()
   roundCount = 0;
   curlyCount = 0;
   ifCount = 0;
-  memberGroupId = -1;
+  memberGroupId = NOGROUP;
   sig = FALSE;
   slot = FALSE;
   gstat = FALSE;
@@ -861,6 +862,7 @@ SCOPEID   {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
 SCOPENAME (({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
 SCOPEMASK {ID}?(("::"|"#")?(~)?{ID})+
 URLMASK   [a-z_A-Z0-9\~\:\@\#\.\-\+\/]+
+WORD      ([a-z_A-Z0-9]+([^\n ]*[a-z_A_Z0-9])?)|("\""[^\n\"]"\"")
 ATTR      ({B}+[^>\n]*)?
 A         [aA]
 BOLD	  [bB]
@@ -972,6 +974,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 %x	GroupDocArg2
 %x	GroupName
 %x	GroupHeader
+%x	StoreGroupDocs
 %x	AfterDoc
 %x	AfterDocBrief
 %x	AfterDocLine
@@ -1061,10 +1064,10 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 %%
 
 <*>\x06[^\x06]*\x06			{ // new file
-  					  if (memberGroupId!=-1)
+  					  if (memberGroupId!=NOGROUP)
 					  {
-					    warn("Warning: Missing \\endmgroup in file %s\n",yyFileName);
-					    memberGroupId=-1;
+					    warn("Warning: Missing //@} in file %s\n",yyFileName);
+					    memberGroupId=NOGROUP;
 					  }
   					  yyLineNr= 0 ; // there is always an extra newline at the start of the file
 					  int i; 
@@ -1756,18 +1759,18 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
   					  warn("Warning: \\endcode without <PRE> or \\code "
     					       "in the documentation of %s\n",refName.data()); 
 					}
-<DocScan>{SCOPEMASK}"("[a-z_A-Z,:\<\> \t\*\&]+")"	{
+<DocScan>{SCOPEMASK}"("[a-z_A-Z0-9,:\<\> \t\*\&]+")"	{
   					  generateRef(*outDoc,className,yytext,inSeeBlock);
   					}
 <DocScan>{SCOPEMASK}(("()")?)          	{ 
 					  generateRef(*outDoc,className,yytext,inSeeBlock);
 					} 
-<DocScan>({SCOPEMASK}"::")?"operator()("[a-z_A-Z,\<\> \t\*\&]*")"	{ 
+<DocScan>({SCOPEMASK}"::")?"operator()("[a-z_A-Z0-9,\<\> \t\*\&]*")"	{ 
 				          QCString oName=yytext;
 					  generateRef(*outDoc,className,
 					              removeRedundantWhiteSpace(oName),inSeeBlock);
 					}
-<DocScan>({SCOPEMASK}"::")?"operator"[^(\r\n.,]*"("[a-z_A-Z,\<\> \t\*\&]*")"	{ 
+<DocScan>({SCOPEMASK}"::")?"operator"[^(\r\n.,]+"("[a-z_A-Z0-9,\<\> \t\*\&]*")"	{ 
     					  QCString oName=yytext;
 					  generateRef(*outDoc,className,
 					              removeRedundantWhiteSpace(oName),inSeeBlock);
@@ -1984,7 +1987,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 <DocScan>"%"[a-zA-Z_0-9\-]+		{
   					  outDoc->docify(yytext+1);
   					}
-<DocEmphasis>[a-z_A-Z][a-z_A-Z:0-9<>]*	{ 
+<DocEmphasis>{WORD}			{ 
   					  outDoc->startEmphasis();
   					  linkifyText(*outDoc,className,0,yytext);
 					  outDoc->endEmphasis();
@@ -1996,7 +1999,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					  outDoc->endEmphasis();
 					  BEGIN( DocScan );
   					}
-<DocBold>[a-z_A-Z][a-z_A-Z:0-9<>]*	{ 
+<DocBold>{WORD}				{ 
   					  outDoc->startBold();
   					  linkifyText(*outDoc,className,0,yytext);
 					  outDoc->endBold();
@@ -2008,7 +2011,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					  outDoc->endBold();
 					  BEGIN( DocScan );
   					}
-<DocCode>[a-z_A-Z][a-z_A-Z:0-9<>]*	{ 
+<DocCode>{WORD}				{ 
   					  outDoc->startTypewriter();
   					  linkifyText(*outDoc,className,0,yytext);
 					  outDoc->endTypewriter();
@@ -2380,6 +2383,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					  current->virt       = virt;
 					  current->stat       = gstat;
 					  current->slot       = slot;
+					  current->mGrpId     = memberGroupId;
 					  BEGIN(Using);
   					}
 <FindMembers>{SCOPENAME}{BN}*"<>"	{ // guided template decl
@@ -2552,6 +2556,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					  current->virt       = virt;
 					  current->stat       = gstat;
 					  current->slot       = slot;
+					  current->mGrpId     = memberGroupId;
 					  BEGIN(FindMembers);
   					}
 <DefineEnd>\\[\r]?\n			{
@@ -2636,6 +2641,46 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					    BEGIN(AfterDoc);
 					  }
   					}
+<FindMembers>"//@{"|"/*@{*/"		{
+					  if (memberGroupId!=NOGROUP)
+					  {
+  					    warn("Warning: ignoring nested member group "
+					         "at line %d of %s. Previous command was found at line %d\n",
+						 yyLineNr,yyFileName,lastMemberGroupLine);
+					  }
+					  else if (memberGroupHeader.isEmpty())
+					  {
+					    warn("Warning: member group has empty header "
+						 "at line %d of %s.\n",yyLineNr,yyFileName);
+					    memberGroupHeader="[No header specified!]";
+					  }
+					  else
+					  {
+					    memberGroupId = newMemberGroupId();
+					    current->mGrpId = memberGroupId;
+					    lastMemberGroupLine = yyLineNr;
+					  }
+  					}
+<FindMembers>"//@}"|"/*@}*/"		{
+					  if (memberGroupId==NOGROUP)
+					  {
+					    warn("Warning: end of member group without matching begin "
+						 "at line %d of %s.\n",yyLineNr,yyFileName);
+					  }
+					  else
+					  {
+  					    memberHeaderDict.insert(memberGroupId,
+					                            new QCString(memberGroupHeader.stripWhiteSpace())
+					  			  );
+					    memberDocDict.insert(memberGroupId,
+					      	               new QCString(memberGroupDocs)
+							      );
+					    memberGroupId=NOGROUP;
+					    current->mGrpId=NOGROUP;
+					    memberGroupHeader.resize(0);
+					    memberGroupDocs.resize(0);
+					  }
+  					}
 <FindMembers>"="			{
   					  current->bodyLine = yyLineNr;
 					  lastInitializerContext = YY_START;
@@ -2773,6 +2818,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					    current->section = Entry::VARIABLE_SEC ;
 					    current->fileName = yyFileName;
 					    current->startLine = yyLineNr;
+					    //printf("New variable type=`%s' name=`%s' groupId=%d\n",current->type.data(),current->name.data(),current->mGrpId);
 					    current_root->addSubEntry( current ) ;
 					    current = new Entry ;
 					    // variable found 
@@ -2782,6 +2828,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					    current->sig = sig = FALSE;
 					    current->virt = Normal; 
 					    current->stat = gstat;
+					    current->mGrpId = memberGroupId;
 					  }
 					  // skip expression or bitfield if needed
 					  if ( *yytext == ':') 
@@ -2856,9 +2903,9 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
   					  BEGIN(ReadInitializer);
   					}
 <FindFields>","				{
-					  //printf("adding `%s' `%s' `%s' to enum `%s'\n",
+					  //printf("adding `%s' `%s' `%s' to enum `%s' (mGrpId=%d)\n",
 					  //     current->type.data(), current->name.data(),
-					  //     current->args.data(), current_root->name.data());
+					  //     current->args.data(), current_root->name.data(),current->mGrpId);
 					  current->fileName   = yyFileName;
 					  current->startLine  = yyLineNr;
 					  current->type       = "@"; // enum marker
@@ -2876,6 +2923,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					  current->virt       = virt;
 					  current->stat       = gstat;
 					  current->slot       = slot;
+					  current->mGrpId     = memberGroupId;
   					}
   /*
 <FindFieldArg>","			{ unput(*yytext); BEGIN(FindFields); }
@@ -2944,6 +2992,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 						current->virt = virt;
 						current->stat = gstat;
 						current->slot = slot;
+						current->mGrpId = memberGroupId;
 						BEGIN( FindMembers ) ;
 					      }
 					      else
@@ -2971,6 +3020,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					  current->virt = virt;
 					  current->stat = gstat;
 					  current->slot = slot;
+					  current->mGrpId = memberGroupId;
   					  BEGIN(MemberSpecSkip); 
   					}
 <MemberSpec>([*&]*{BN}*)*{ID}("["[a-z_A-Z0-9]*"]")* { // the [] part could be improved.
@@ -3036,6 +3086,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					    varEntry->startLine = yyLineNr;
 					    varEntry->doc = current->doc.copy();
 					    varEntry->brief = current->brief.copy();
+					    varEntry->mGrpId = current->mGrpId;
 					    //printf("Add: type=`%s',name=`%s',args=`%s'\n",
 					    //      varEntry->type.data(),varEntry->name.data(),varEntry->args.data());
 					    current_root->addSubEntry(varEntry);
@@ -3052,6 +3103,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					    current->virt = virt;
 					    current->stat = gstat;
 					    current->slot = slot;
+					    current->mGrpId = memberGroupId;
 					    BEGIN( FindMembers );
 					  }
   					}					
@@ -3900,6 +3952,15 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
   					  current->doc+=yytext;
 					  BEGIN( tmpDocType );
   					}
+<JavaDoc>"<"{TABLE}{ATTR}">"		{ 
+  					  current->doc+=yytext;
+					  int i;
+					  for (i=yyleng-1;i>=0;i--)
+					  {
+					    unput(yytext[i]);
+					  }
+					  BEGIN( tmpDocType );
+  					}
 <Doc,JavaDoc>{B}*{CMD}("fn"|"var"|"typedef"){B}*	{
 					  current->section = Entry::MEMBERDOC_SEC;
 					  current->fileName = yyFileName;
@@ -4009,6 +4070,17 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					  current->startLine = yyLineNr;
  					  BEGIN( ExampleDocArg1 );
 					}
+<Doc,JavaDoc>{CMD}"name"{B}+ 		{
+  					  //printf("--> mgroup found!\n");
+					  current->section = Entry::MEMBERGRP_SEC;
+					  current->fileName = yyFileName;
+					  current->startLine = yyLineNr;
+  					  //lastMemberGroupContext = lastDocContext;
+					  //lastDocContext = StoreGroupDocs;
+					  memberGroupHeader.resize(0);
+					  memberGroupDocs.resize(0);
+					  BEGIN(GroupHeader);
+  					}
 <ExampleDocArg1>{FILE}			{
 				          current->name = stripQuotes(yytext);	
 					  BEGIN( ExampleDoc );
@@ -4070,12 +4142,18 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					  yyLineNr++;
 					  BEGIN( Doc );
   					}
-<GroupDocArg2>.*			{
-					  current->type = yytext;
+<GroupDocArg2>[^\n\*]+			{
+					  current->type += yytext;
 					  current->type = current->type.stripWhiteSpace();
-					  newDocState();
+  					}
+<GroupDocArg2>.				{
+					  current->type += yytext;
   					}
 <GroupDocArg2>"\\"{B}*"\n"		{ yyLineNr++; }
+<GroupDocArg2>"*/"			{ 
+  					  unput('/');unput('*');
+ 					  newDocState();
+  					}
 <GroupDocArg2>"\n"			{
  					  newDocState();
   					}
@@ -4149,34 +4227,27 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
   					  sectionType=SectionInfo::Subsection;
   					  BEGIN(SectionLabel);
   					}
-<Doc,PageDoc,JavaDoc,ClassDoc>{CMD}"mgroup"{B}+ {
-  					  //printf("--> mgroup found!\n");
-  					  lastMemberGroupContext = YY_START;
-					  if (memberGroupId!=-1)
-					  {
-  					    warn("Warning: ignoring nested mgroup command "
-					         "at line %d of %s. Previous command was found at line %d\n",
-						 yyLineNr,yyFileName,lastMemberGroupLine);
-					  }
-					  else
-					  {
-					    memberGroupId   = newMemberGroupId();
-					    current->mGrpId = memberGroupId;
-					    lastMemberGroupLine = yyLineNr;
-					  }
-					  BEGIN(GroupHeader);
+<GroupHeader>.				{ memberGroupHeader+=*yytext; }
+<GroupHeader>"*/"			{
+  					  unput('/');unput('*');
+					  //printf("Found memberGroup=`%s'\n",memberGroupHeader.data());
+					  newDocState();
   					}
-<Doc,PageDoc,JavaDoc,ClassDoc>{CMD}"endmgroup"/[^a-z_A-Z0-9] {
-  					  //printf("--> endmgroup found!\n");
-  					  memberGroupId = -1;
-					  current->mGrpId = -1;
+<GroupHeader>\n				{
+  					  yyLineNr++;
+					  //printf("Found memberGroup=`%s'\n",memberGroupHeader.data());
+					  newDocState();
   					}
-<GroupHeader>[^\n]*/"\n"		{
-					  QCString header = ((QCString)yytext).stripWhiteSpace();
-  					  memberGroupDict.insert(memberGroupId,
-					                         new MemberGroup(memberGroupId,header)
-								);
-  					  BEGIN(lastMemberGroupContext);
+<StoreGroupDocs>"$"			{
+  					  //printf("StoreGroupDocs memberGroupId=%d brief=`%s' doc=`%s'!\n",memberGroupId,current->brief.data(),current->doc.data());
+					  memberGroupDocs=current->brief.stripWhiteSpace();
+					  current->doc = current->doc.stripWhiteSpace();
+					  if (!memberGroupDocs.isEmpty() && !current->doc.isEmpty())
+					  {
+					    memberGroupDocs+="\n\n";
+					  }
+					  memberGroupDocs+=current->doc;
+					  BEGIN(lastDocContext);
   					}
 <ExampleDoc,Doc,PageDoc,JavaDoc,ClassDoc>{CMD}"anchor"{B}+ {
   					  lastAnchorContext = YY_START;
@@ -4326,6 +4397,7 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 <ReadFormulaLong,ReadFormulaShort>.                     { formulaText+=*yytext; }
 <ExampleDoc,PageDoc,ClassDocBrief,SkipCode,ClassDoc>{B}*"*/"  	{
   					  checkDocs();
+					  //printf("current->section=%x\n",current->section);
 					  if (YY_START==SkipCode) // premature end of code block
 					  {
 					    err("Error: comment block ended inside \\code ... \\endcode block at line %d in %s!\n",
@@ -4339,6 +4411,11 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
   					    current->doc += "\n\n";
   					    BEGIN( lastDocContext ); 
 					  }
+					  else if (current->section==Entry::MEMBERGRP_SEC)
+					  {
+					    unput('$');
+					    BEGIN( StoreGroupDocs );
+					  }
 					  else
 					  {
   					    current->doc += "\n\n";
@@ -4350,8 +4427,9 @@ DOCPARAM  ([a-z_A-Z0-9:\.\-]+)|("\"".*"\"")
 					    current->virt = virt;
 					    current->stat = gstat;
 					    current->slot = slot;
+					    current->mGrpId = memberGroupId;
+					    BEGIN( FindMembers );
 					  }
-					  BEGIN( FindMembers );
 					}
 <PageDoc>"<"{TITLE}">"			{ 
   					  current->args.resize(0); 
@@ -4682,6 +4760,7 @@ void parseCompounds(Entry *rt)
       slot = FALSE;
       gstat = FALSE;
       virt = Normal;
+      current->mGrpId = memberGroupId = ce->mGrpId;
       scanYYlex() ;
       delete current; current=0;
       ce->program.resize(0);
@@ -4805,11 +4884,6 @@ void parseText(OutputList &ol,const QCString &txtString)
   scanYYrestart( scanYYin ); 
   BEGIN( Text );
   scanYYlex();
-  if (memberGroupId!=-1)
-  {
-    warn("Warning: Missing \\endmgroup in file %s\n",yyFileName);
-    memberGroupId=-1;
-  }
   ol+=*outDoc;
   delete outDoc; outDoc=0;
   return;
diff --git a/src/searchindex.cpp b/src/searchindex.cpp
index 8aaa7c7..5d420d3 100644
--- a/src/searchindex.cpp
+++ b/src/searchindex.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/searchindex.h b/src/searchindex.h
index 54b9794..d8f343c 100644
--- a/src/searchindex.h
+++ b/src/searchindex.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/section.h b/src/section.h
index 81f5ed5..fd7ce60 100644
--- a/src/section.h
+++ b/src/section.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
diff --git a/src/suffixtree.cpp b/src/suffixtree.cpp
index 9bb6be5..3d7d8ec 100644
--- a/src/suffixtree.cpp
+++ b/src/suffixtree.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/suffixtree.h b/src/suffixtree.h
index b0149a7..b7a0958 100644
--- a/src/suffixtree.h
+++ b/src/suffixtree.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/tag.h b/src/tag.h
index ecbac49..829c1ed 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/tag.l b/src/tag.l
index 06b5fb3..9c6ac18 100644
--- a/src/tag.l
+++ b/src/tag.l
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -117,21 +117,21 @@ static void addMember(const char *name,const char *anchor,const char *args)
     if (cd) // member of a class
     {
       md->setMemberClass(cd);
-      cd->insertMember(md); 
+      cd->insertMember(md,-1); /* TODO: store group info */
       mnd=&memberNameDict;
       mnl=&memberNameList;
     }
     else if (nd) // member of a namespace
     {
       md->setNamespace(nd);
-      nd->insertMember(md);
+      nd->insertMember(md,-1); /* TODO: store group info */
       mnd=&functionNameDict;
       mnl=&functionNameList;
     }
     else // member of a file
     {
       md->setFileDef(fd);
-      fd->insertMember(md);
+      fd->insertMember(md,-1); /* TODO: store group info */
       mnd=&functionNameDict;
       mnl=&functionNameList;
     }
diff --git a/src/translator.h b/src/translator.h
index ce81a7b..77d6bbd 100644
--- a/src/translator.h
+++ b/src/translator.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -737,7 +737,7 @@ class Translator
     }
 
 //////////////////////////////////////////////////////////////////////////
-// new since 1.0.0
+// new since 0.49-991205
 //////////////////////////////////////////////////////////////////////////
 
     virtual QCString trDeprecated()
@@ -746,7 +746,7 @@ class Translator
     }
 
 //////////////////////////////////////////////////////////////////////////
-// new since 1.1.0
+// new since 1.0.0
 //////////////////////////////////////////////////////////////////////////
 
     /*! this text is put before a collaboration diagram */
@@ -815,11 +815,15 @@ class Translator
     {
       return "Page Index";
     }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+    
     virtual QCString trNote()
     {
       return "Note";
     }
-
     virtual QCString trPublicTypes()
     {
       return "Public Types";
@@ -856,6 +860,11 @@ class Translator
     {
       return "Static Private Attributes";
     }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.1
+//////////////////////////////////////////////////////////////////////////
+
 };
 
 #endif
diff --git a/src/translator_cz.h b/src/translator_cz.h
index 468b34c..43613cd 100644
--- a/src/translator_cz.h
+++ b/src/translator_cz.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/translator_de.h b/src/translator_de.h
index d39b07c..6142793 100644
--- a/src/translator_de.h
+++ b/src/translator_de.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -42,8 +42,6 @@ class TranslatorGerman : public Translator
     { return "erneute Implementation in"; }
     QCString trIncludeFile()
     { return "Include-Datei"; }
-	QCString trNamespaces()
-	{ return "Namensbereiche"; }
     // end of obsolete functions
     //--------------------------------------------------------------------
 
@@ -402,7 +400,7 @@ class TranslatorGerman : public Translator
 
     QCString trNamespaceList()
       // used as the title of page containing all the index of all namespaces.
-    { return "Liste der Namensbereiche"; }
+    { return ""; }
     QCString trNamespaceListDescription(bool extractAll)
       // used as an introduction to the namespace list
     {
@@ -555,7 +553,217 @@ class TranslatorGerman : public Translator
       // This is used in LaTeX as the title of the chapter containing
       // the documentation of all namespaces.
     { return "Dokumentation der Namensbereiche"; }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+    /*! This is used in the documentation before the list of all
+     *  namespaces in a file.
+     */
+    virtual QCString trNamespaces()
+    { return "Namensbereiche"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+    /*! This is put at the bottom of a class documentation page and is
+     *  followed by a list of files that were used to generate the page.
+     */
+    virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+        bool single)
+    { // here s is one of " Class", " Struct" or " Union"
+      // single is true implies a single file
+      QCString result=(QCString)"Die Dokumentation für diese";
+      switch(compType)
+      {
+        case ClassDef::Class:      result+=" Klasse"; break;
+        case ClassDef::Struct:     result+=" Struktur"; break;
+        case ClassDef::Union:      result+=" Variante"; break;
+        case ClassDef::Interface:  result+="s Interface"; break;
+        case ClassDef::Exception:  result+=" Ausnahme"; break;
+      }
+      result+=" wurde erzeugt aufgrund der Datei";
+      if (single) result+=":"; else result+="en:";
+      return result;
+    }
+
+    /*! This is in the (quick) index as a link to the alphabetical compound
+     * list.
+     */
+    virtual QCString trAlphabeticalList()
+    { return "Alphabetische Liste"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+    /*! This is used as the heading text for the retval command. */
+    virtual QCString trReturnValues()
+    { return "R&uuml;ckgabewerte"; }
+
+    /*! This is in the (quick) index as a link to the main page (index.html)
+     */
+    virtual QCString trMainPage()
+    { return "Hauptseite"; }
+
+    /*! This is used in references to page that are put in the LaTeX 
+     *  documentation. It should be an abbreviation of the word page.
+     */
+    virtual QCString trPageAbbreviation()
+    { return "S."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+    virtual QCString trSources()
+    {
+      return "Quellen";
+    }
+    virtual QCString trDefinedAtLineInSourceFile()
+    {
+      return "Definiert in Zeile @0 der Datei @1.";
+    }
+    virtual QCString trDefinedInSourceFile()
+    {
+      return "Definiert in Datei @0.";
+    }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+    virtual QCString trDeprecated()
+    {
+      return "Veraltet";
+    }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+    /*! this text is put before a collaboration diagram */
+    virtual QCString trCollaborationDiagram(const char *clName)
+    {
+      return (QCString)"Zusammengeh&ouml;rigkeiten von "+clName+":";
+    }
+    /*! this text is put before an include dependency graph */
+    virtual QCString trInclDepGraph(const char *fName)
+    {
+      return (QCString)"Include-Abhängikeitsdiagramm f&uuml;r "+fName+":";
+    }
+    /*! header that is put before the list of constructor/destructors. */
+    virtual QCString trConstructorDocumentation()
+    {
+      return "Beschreibung der Konstruktoren und Destruktoren"; 
+    }
+    /*! Used in the file documentation to point to the corresponding sources. */
+    virtual QCString trGotoSourceCode()
+    {
+      return "gehe zum Quellcode dieser Datei";
+    }
+    /*! Used in the file sources to point to the corresponding documentation. */
+    virtual QCString trGotoDocumentation()
+    {
+      return "gehe zur Dokumentation dieser Datei";
+    }
+    /*! Text for the \pre command */
+    virtual QCString trPrecondition()
+    {
+      return "Vorbedingung";
+    }
+    /*! Text for the \post command */
+    virtual QCString trPostcondition()
+    {
+      return "Nachbedingung";
+    }
+    /*! Text for the \invariant command */
+    virtual QCString trInvariant()
+    {
+      return "Invariant";
+    }
+    /*! Text shown before a multi-line variable/enum initialization */
+    virtual QCString trInitialValue()
+    {
+      return "Initialisierung:";
+    }
+    /*! Text used the source code in the file index */
+    virtual QCString trCode()
+    {
+      return "code";
+    }
+    virtual QCString trGraphicalHierarchy()
+    {
+      return "Grafische Darstellung der Klassenhierarchie";
+    }
+    virtual QCString trGotoGraphicalHierarchy()
+    {
+      return "gehe zur grafischen Darstellung der Klassenhierarchie";
+    }
+    virtual QCString trGotoTextualHierarchy()
+    {
+      return "gehe zur textbasierten Darstellung der Klassenhierarchie";
+    }
+    virtual QCString trPageIndex()
+    {
+      return "Seitenindex";
+    }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+    virtual QCString trNote()
+    {
+      return "Bemerkung";
+    }
+
+    virtual QCString trPublicTypes()
+    {
+      return "&Ouml;ffentliche Typen";
+    }
+    virtual QCString trPublicAttribs()
+    {
+      return "&Ouml;ffentliche Attribute";
+    }
+    virtual QCString trStaticPublicAttribs()
+    {
+      return "Statische &ouml;ffentliche Attribute";
+    }
+    virtual QCString trProtectedTypes()
+    {
+      return "Gesch&uuml;tzte Typen";
+    }
+    virtual QCString trProtectedAttribs()
+    {
+      return "Gesch&uuml;tzte Attribute";
+    }
+    virtual QCString trStaticProtectedAttribs()
+    {
+      return "Statische gesch&uuml;tzte Attribute";
+    }
+    virtual QCString trPrivateTypes()
+    {
+      return "Private Typen";
+    }
+    virtual QCString trPrivateAttribs()
+    {
+      return "Private Attribute";
+    }
+    virtual QCString trStaticPrivateAttribs()
+    {
+      return "Statische private Attribute";
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+    // new since 1.1.1
+    //////////////////////////////////////////////////////////////////////////
+
 };
 
+
 #endif
 
diff --git a/src/translator_es.h b/src/translator_es.h
index 66f4afb..43e8630 100644
--- a/src/translator_es.h
+++ b/src/translator_es.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -14,19 +14,11 @@
  *
  */
 
-
 /**
- * translator_es.h modified by Francisco Oltra 
- * Some notes: 
- * - Computer related use of the spanish language differs from
- * country to country, so some words might not sound so good
- * to some people (but it does to me, *grin* ). A good example
- * is the spanish for File: i use "Archivo", others may prefer
- * "Fichero".
- * - Some words were not translated for understandability, since
- * we are talking about a  computer program here!
- * - Some of the functions are called in some order coherent with
- * the english grammar, this results in some ugly constructs.
+ * translator_es.h modified by Lucas Cruz
+ * Some notes:
+ * - I only use upper case in the first letter of the title, because
+ * the aspect of the document is more pleasing to the eye.
  */
 
 #ifndef TRANSLATOR_ES_H
@@ -37,303 +29,561 @@
 class TranslatorSpanish : public Translator
 {
   public:
-    QCString latexBabelPackage()
-    { return "spanish"; }
-    QCString trRelatedFunctions()
-    { return "Funciones Relacionadas"; }
-    QCString trRelatedSubscript()
-    { return "(Note que estos no son funciones miembro.)"; }
-    QCString trDetailedDescription()
-    { return "Descripción Detallada"; }
-    QCString trMemberTypedefDocumentation()
-    { return "Documentación de Miembros Typedef"; }
-    QCString trMemberEnumerationDocumentation()
-    { return "Documentación de Miembros de Enumeración"; }
-    QCString trEnumerationValueDocumentation()
-    { return "Documentación de los Valores de Enumeración"; }
-    QCString trMemberFunctionDocumentation()
-    { return "Documentación de Funciones Miembro"; }
-    QCString trMemberDataDocumentation()
-    { return "Documentación de Datos Miembro"; }
-    QCString trGeneratedFrom(const char *s,bool single)
+    //--------------------------------------------------------------------
+    // NOTICE:
+    // the following functions are now obsolete: these are no longer used and 
+    // will disappear in future versions. You do not have to translate them!
+    virtual QCString trInherits() 
+    { return "Inherits"; }
+    virtual QCString trAnd() 
+    { return "y"; }
+    virtual QCString trInheritedBy() 
+    { return "Inherited By"; }
+    virtual QCString trReference() 
+    { return "Referencia"; }
+    virtual QCString trReimplementedFrom()
+    { return "Reimplementado de"; }
+    virtual QCString trReimplementedIn()
+    { return "Reimplementado en"; }
+    virtual QCString trIncludeFile()
+    { return "Include File"; }
+    virtual QCString trGeneratedFrom(const char *s,bool single)
     { 
-      QCString result=(QCString)"La documentación para esta"+s+
-                     " fue generada del siguiente archivo";
-      if (single) result+=":";   else result+="s:";
+      QCString result=(QCString)"The documentation for this"+s+
+                     " was generated from the following file";
+      if (single) result+=":"; else result+="s:";
       return result;
     }
-    QCString trMore()
+    // end of obsolete functions 
+    //--------------------------------------------------------------------
+
+    /*! returns the name of the package that is included by LaTeX */
+    virtual QCString latexBabelPackage() 
+    { return ""; }
+
+    /*! used in the compound documentation before a list of related functions. */
+    virtual QCString trRelatedFunctions()
+    { return "Funciones Relacionadas"; }
+
+    /*! subscript for the related functions. */
+    virtual QCString trRelatedSubscript()
+    { return "(Observa que estas no son funciones miembro.)"; }
+
+    /*! header that is put before the detailed description of files, classes and namespaces. */
+    virtual QCString trDetailedDescription()
+    { return "Descripción Detallada"; }
+
+    /*! header that is put before the list of typedefs. */
+    virtual QCString trMemberTypedefDocumentation()
+    { return "Documentación de los 'Tipos Definidos' Miembros de la Clase"; }
+    
+    /*! header that is put before the list of enumerations. */
+    virtual QCString trMemberEnumerationDocumentation()
+    { return "Documentación de las Enumeraciones Miembro de la Clase"; }
+    
+    /*! header that is put before the list of member functions. */
+    virtual QCString trMemberFunctionDocumentation()
+    { return "Documentación de las Funciones Miembro"; }
+    
+    /*! header that is put before the list of member attributes. */
+    virtual QCString trMemberDataDocumentation()
+    { return "Documentación de los Datos Miembro"; }
+
+    /*! this is the text of a link put after brief descriptions. */
+    virtual QCString trMore() 
     { return "Más..."; }
-    QCString trListOfAllMembers()
+
+    /*! put in the class documentation */
+    virtual QCString trListOfAllMembers()
     { return "Lista de todos los miembros."; }
-    QCString trMemberList()
-    { return "Lista de Miembros"; }
-    QCString trThisIsTheListOfAllMembers()
+
+    /*! used as the title of the "list of all members" page of a class */
+    virtual QCString trMemberList()
+    { return "Lista de los Miembros"; }
+
+    /*! this is the first part of a sentence that is followed by a class name */
+    virtual QCString trThisIsTheListOfAllMembers()
     { return "Esta es la lista completa de miembros para "; }
-    QCString trIncludingInheritedMembers()
+
+    /*! this is the remainder of the sentence after the class name */
+    virtual QCString trIncludingInheritedMembers()
     { return ", incluyendo todos los miembros heredados."; }
-    QCString trGeneratedAutomatically(const char *s)
-    { QCString result="Generado automáticamente por Doxygen"; 
+    
+    /*! this is put at the author sections at the bottom of man pages.
+     *  parameter s is name of the project name.
+     */
+    virtual QCString trGeneratedAutomatically(const char *s)
+    { QCString result="Generado automáticamente por Doxygen";
       if (s) result+=(QCString)" para "+s;
-      result+=" desde el código fuente."; 
+      result+=" del código fuente."; 
       return result;
     }
-    QCString trEnumName()
-    { return "nombre de enum"; }
-    QCString trEnumValue()
-    { return "valor de enum"; }
-    QCString trDefinedIn()
+
+    /*! put after an enum name in the list of all members */
+    virtual QCString trEnumName()
+    { return "nombre de la enumeración"; }
+    
+    /*! put after an enum value in the list of all members */
+    virtual QCString trEnumValue()
+    { return "valor enumerado"; }
+    
+    /*! put after an undocumented member in the list of all members */
+    virtual QCString trDefinedIn()
     { return "definido en"; }
-    QCString trVerbatimText(const char *f)
-    { return (QCString)"Esto es texto verbatim del archivo incluído "+f+"."; }
-    QCString trModules()
-    { return "Modulos"; }
-    QCString trClassHierarchy()
-    { return "Jerarquía de la clase"; }
-    QCString trCompoundList()
-    { return "Lista de Tipos Compuestos"; }
-    QCString trFileList()
+
+    /*! put as in introduction in the verbatim header file of a class.
+     *  parameter f is the name of the include file.
+     */
+    virtual QCString trVerbatimText(const char *f)
+    { return (QCString)"Este es el texto al pie de la letra del "+f+" archivo adjunto."; }
+    
+    // quick reference sections
+
+    /*! This is put above each page as a link to the list of all groups of 
+     *  compounds or files (see the \group command).
+     */
+    virtual QCString trModules()
+    { return "Módulos"; }
+    
+    /*! This is put above each page as a link to the class hierarchy */
+    virtual QCString trClassHierarchy()
+    { return "Jerarquía de la Clase"; }
+    
+    /*! This is put above each page as a link to the list of annotated classes */
+    virtual QCString trCompoundList()
+    { return "Lista de Componentes"; }
+    
+    /*! This is put above each page as a link to the list of documented files */
+    virtual QCString trFileList()
     { return "Lista de Archivos"; }
-    QCString trHeaderFiles()
-    { return "Archivos de Cabecera"; }
-    QCString trCompoundMembers()
-    { return "Miembros de Compuestos"; }
-    QCString trFileMembers()
-    { return "Miembros de los Archivos"; }
-    QCString trRelatedPages()
+
+    /*! This is put above each page as a link to the list of all verbatim headers */
+    virtual QCString trHeaderFiles()
+    { return "Archivos Cabecera"; }
+
+    /*! This is put above each page as a link to all members of compounds. */
+    virtual QCString trCompoundMembers()
+    { return "Miembros de las Clases"; }
+
+    /*! This is put above each page as a link to all members of files. */
+    virtual QCString trFileMembers()
+    { return "Archivos de los Miembros"; }
+
+    /*! This is put above each page as a link to all related pages. */
+    virtual QCString trRelatedPages()
     { return "Páginas Relacionadas"; }
-    QCString trExamples()
+
+    /*! This is put above each page as a link to all examples. */
+    virtual QCString trExamples()
     { return "Ejemplos"; }
-    QCString trSearch()
+
+    /*! This is put above each page as a link to the search engine. */
+    virtual QCString trSearch()
     { return "Buscar"; }
-    QCString trClassHierarchyDescription()
-    { return "Esta lista de herencia está ordenada alfabéticamente, "
-             "pero no completamente:";
+
+    /*! This is an introduction to the class hierarchy. */
+    virtual QCString trClassHierarchyDescription()
+    { return "Esta lista de herencias esta ordenada rigurosamente, "
+             "pero no completa, por orden alfabético:";
     }
-    QCString trFileListDescription(bool extractAll)
+
+    /*! This is an introduction to the list with all files. */
+    virtual QCString trFileListDescription(bool extractAll)
     {
-      QCString result="Esta es una lista de todos ";
-      result+="los archivos ";
-      if (!extractAll) result+="documentados ";
-      result+="con breves descripciones:";
+      QCString result="Lista de todos los archivos ";
+      if (!extractAll) result+="documentados y";
+      result+=" con descripciones breves:";
       return result;
     }
-    QCString trCompoundListDescription()
-    { return "Aquí estan las clases, estructuras y "
-             "uniones con descripciones breves:"; 
+
+    /*! This is an introduction to the annotated compound list. */
+    virtual QCString trCompoundListDescription()
+    { return "Lista de las clases, estructuras, "
+             "uniones e interfaces con una breve descripción:"; 
     }
-    QCString trCompoundMembersDescription(bool extractAll)
+
+    /*! This is an introduction to the page with all class members. */
+    virtual QCString trCompoundMembersDescription(bool extractAll)
     {
-      QCString result="Esta es una lista de todos ";
-      result+="miembros de clases ";
-      if (!extractAll) result+="documentados ";
-      result+="con enlaces a ";
-      if (extractAll) result+="la documentación de clase para cada miembro:";
-      else result+="las clases a que pertenecen:";
+      QCString result="Lista de";
+      if (!extractAll) result+=" toda la documentación de";
+      result+=" los miembros de la clase con enlaces a ";
+      if (extractAll) 
+        result+=" la documentación de cada clase:";
+      else 
+        result+="la clase de la que forman parte:";
       return result;
     }
-    QCString trFileMembersDescription(bool extractAll)
+
+    /*! This is an introduction to the page with all file members. */
+    virtual QCString trFileMembersDescription(bool extractAll)
     {
-      QCString result="Esta es una lista de todos los miembros de los archivos ";
-      if (!extractAll) result+="documentados ";
-      result+="con enlaces a ";
-      if (extractAll) result+="la documentación de archivo para cada miembro:";
-      else result+="los archivos a que pertenecen:";
+      QCString result="Lista de ";
+      if (!extractAll) result+="toda la documentación de ";
+      result+="los miembros con enlaces a ";
+      if (extractAll) 
+        result+="los documentos de cada archivo a los que pertenecen:";
+      else 
+        result+="los archivos de los que forman parte:";
       return result;
     }
-    QCString trHeaderFilesDescription()
-    { return "Aquí estan los archivos de cabecera que forman el API:"; }
-    QCString trExamplesDescription()
-    { return "Esta es la lista de todos los ejemplos:"; }
-    QCString trRelatedPagesDescription()
-    { return "Esta es una lista de todos las páginas con documentación relacionada:"; }
-    QCString trModulesDescription()
-    { return "Esta es una lista con todos los modulos:"; }
-    QCString trNoDescriptionAvailable()
-    { return "No existe descripción disponible"; }
-
-    QCString trDocumentation()
+
+    /*! This is an introduction to the page with the list of all header files. */
+    virtual QCString trHeaderFilesDescription()
+    { return "Lista de los archivos cabecera que crean el API:"; }
+
+    /*! This is an introduction to the page with the list of all examples */
+    virtual QCString trExamplesDescription()
+    { return "Lista de todos los ejemplos:"; }
+
+    /*! This is an introduction to the page with the list of related pages */
+    virtual QCString trRelatedPagesDescription()
+    { return "Lista de toda la documentación relacionada:"; }
+
+    /*! This is an introduction to the page with the list of class/file groups */
+    virtual QCString trModulesDescription()
+    { return "Lista de todos los módulos:"; }
+
+    /*! This sentences is used in the annotated class/file lists if no brief
+     * description is given. 
+     */
+    virtual QCString trNoDescriptionAvailable()
+    { return "Descripción no disponible"; }
+    
+    // index titles (the project name is prepended for these) 
+
+
+    /*! This is used in HTML as the title of index.html. */
+    virtual QCString trDocumentation()
     { return "Documentación"; }
-    QCString trModuleIndex()
-    { return "Índice de Modulos"; }
-    QCString trHierarchicalIndex()
-    { return "Índice Jerárquico"; }
-    QCString trCompoundIndex()
-    { return "Índice de Tipos Compuestos"; }
-    QCString trFileIndex() 
-    { return "Índice de Archivos"; }
-    QCString trModuleDocumentation()
-    { return "Documentación de los Modulos"; }
-    QCString trClassDocumentation()
-    { return "Documentación de las clases"; }
-    QCString trFileDocumentation()
-    { return "Documentación de los Archivos"; }
-    QCString trExampleDocumentation()
-    { return "Documentación de los Ejemplos"; }
-    QCString trPageDocumentation()
-    { return "Documentación de las Páginas Relacionadas"; }
-    QCString trReferenceManual()
-    { return "Manual de Referencia"; }
 
-    QCString trDefines()
+    /*! This is used in LaTeX as the title of the chapter with the 
+     * index of all groups.
+     */
+    virtual QCString trModuleIndex()
+    { return "Indice de Módulos"; }
+
+    /*! This is used in LaTeX as the title of the chapter with the 
+     * class hierarchy.
+     */
+    virtual QCString trHierarchicalIndex()
+    { return "Indice Jerárquico"; }
+
+    /*! This is used in LaTeX as the title of the chapter with the 
+     * annotated compound index.
+     */
+    virtual QCString trCompoundIndex()
+    { return "Indice de Clases"; }
+
+    /*! This is used in LaTeX as the title of the chapter with the
+     * list of all files.
+     */
+    virtual QCString trFileIndex() 
+    { return "Indice de Archivos"; }
+
+    /*! This is used in LaTeX as the title of the chapter containing
+     *  the documentation of all groups.
+     */
+    virtual QCString trModuleDocumentation()
+    { return "Documentación de Módulos"; }
+
+    /*! This is used in LaTeX as the title of the chapter containing
+     *  the documentation of all classes, structs and unions.
+     */
+    virtual QCString trClassDocumentation()
+    { return "Documentación de Clasee"; }
+
+    /*! This is used in LaTeX as the title of the chapter containing
+     *  the documentation of all files.
+     */
+    virtual QCString trFileDocumentation()
+    { return "Documentación de Archivos"; }
+
+    /*! This is used in LaTeX as the title of the chapter containing
+     *  the documentation of all examples.
+     */
+    virtual QCString trExampleDocumentation()
+    { return "Documentación de Ejemplos"; }
+
+    /*! This is used in LaTeX as the title of the chapter containing
+     *  the documentation of all related pages.
+     */
+    virtual QCString trPageDocumentation()
+    { return "Documentación de Páginas"; }
+
+    /*! This is used in LaTeX as the title of the document */
+    virtual QCString trReferenceManual()
+    { return "Manual de Referencia"; }
+    
+    /*! This is used in the documentation of a file as a header before the 
+     *  list of defines
+     */
+    virtual QCString trDefines()
     { return "Definiciones"; }
-    QCString trFuncProtos()
-    { return "Prototipo de Funciones"; }
-    QCString trTypedefs()
-    { return "Typedefs"; }
-    QCString trEnumerations()
+
+    /*! This is used in the documentation of a file as a header before the 
+     *  list of function prototypes
+     */
+    virtual QCString trFuncProtos()
+    { return "Funciones Prototipo"; }
+
+    /*! This is used in the documentation of a file as a header before the 
+     *  list of typedefs
+     */
+    virtual QCString trTypedefs()
+    { return "Tipos Definidos"; }
+
+    /*! This is used in the documentation of a file as a header before the 
+     *  list of enumerations
+     */
+    virtual QCString trEnumerations()
     { return "Enumeraciones"; }
-    QCString trFunctions()
+
+    /*! This is used in the documentation of a file as a header before the 
+     *  list of (global) functions
+     */
+    virtual QCString trFunctions()
     { return "Funciones"; }
-    QCString trVariables()
+
+    /*! This is used in the documentation of a file as a header before the 
+     *  list of (global) variables
+     */
+    virtual QCString trVariables()
     { return "Variables"; }
-    QCString trEnumerationValues()
-    { return "Valores de Enumeraciones"; }
-    QCString trAuthor()
+
+    /*! This is used in the documentation of a file as a header before the 
+     *  list of (global) variables
+     */
+    virtual QCString trEnumerationValues()
+    { return "Valores de la enumeración"; }
+    
+    /*! This is used in man pages as the author section. */
+    virtual QCString trAuthor()
     { return "Autor"; }
-    QCString trDefineDocumentation()
+
+    /*! This is used in the documentation of a file before the list of
+     *  documentation blocks for defines
+     */
+    virtual QCString trDefineDocumentation()
     { return "Documentación de las Definiciones"; }
-    QCString trFunctionPrototypeDocumentation()
-    { return "Documentación de los Prototipos de Funciones"; }
-    QCString trTypedefDocumentation()
-    { return "Documentación de Typedefs"; }
-    QCString trEnumerationTypeDocumentation()
-    { return "Documentación de Enumeración de tipos"; }
-    QCString trFunctionDocumentation()
-    { return "Documentación de Funciones"; }
-    QCString trVariableDocumentation()
-    { return "Documentación de Variables"; }
-    QCString trCompounds()
-    { return "Tipos Compuestos"; }
-    QCString trFiles()
+
+    /*! This is used in the documentation of a file/namespace before the list 
+     *  of documentation blocks for function prototypes
+     */
+    virtual QCString trFunctionPrototypeDocumentation()
+    { return "Documentación de las funciones prototipo"; }
+
+    /*! This is used in the documentation of a file/namespace before the list 
+     *  of documentation blocks for typedefs
+     */
+    virtual QCString trTypedefDocumentation()
+    { return "Documentación de los Tipos Definidos"; }
+
+    /*! This is used in the documentation of a file/namespace before the list 
+     *  of documentation blocks for enumeration types
+     */
+    virtual QCString trEnumerationTypeDocumentation()
+    { return "Documentación de las Enumeraciones"; }
+
+    /*! This is used in the documentation of a file/namespace before the list 
+     *  of documentation blocks for enumeration values
+     */
+    virtual QCString trEnumerationValueDocumentation()
+    { return "Documentación de los Valores de la Enumeración"; }
+
+    /*! This is used in the documentation of a file/namespace before the list 
+     *  of documentation blocks for functions
+     */
+    virtual QCString trFunctionDocumentation()
+    { return "Documentación de las Funciones"; }
+
+    /*! This is used in the documentation of a file/namespace before the list 
+     *  of documentation blocks for variables
+     */
+    virtual QCString trVariableDocumentation()
+    { return "Documentación de las Variables"; }
+
+    /*! This is used in the documentation of a file/namespace/group before 
+     *  the list of links to documented compounds
+     */
+    virtual QCString trCompounds()
+    { return "Clases"; }
+
+    /*! This is used in the documentation of a group before the list of 
+     *  links to documented files
+     */
+    virtual QCString trFiles()
     { return "Archivos"; }
-    QCString trGeneratedAt(const char *date,const char *projName)
+
+    /*! This is used in the standard footer of each page and indicates when 
+     *  the page was generated 
+     */
+    virtual QCString trGeneratedAt(const char *date,const char *projName)
     { 
       QCString result=(QCString)"Generado el "+date;
       if (projName) result+=(QCString)" para "+projName;
       result+=(QCString)" por";
       return result;
     }
-    QCString trWrittenBy()
+    /*! This is part of the sentence used in the standard footer of each page.
+     */
+    virtual QCString trWrittenBy()
     {
       return "escrito por";
     }
-    QCString trClassDiagram(const char *clName)
+
+    /*! this text is put before a class diagram */
+    virtual QCString trClassDiagram(const char *clName)
     {
-      return (QCString)"Diagrama de clases para "+clName;
+      return (QCString)"Diagrama de herencias de "+clName;
     }
+    
+    /*! this text is generated when the \internal command is used. */
+    virtual QCString trForInternalUseOnly()
+    { return "Para uso interno exclusivamente."; }
 
-    QCString trForInternalUseOnly()
-    { return "Para uso interno solamente."; }
-    QCString trReimplementedForInternalReasons()
-    { return "Reimplementado por razones internas; el API no se ve afectado."; 
-    }
-    QCString trWarning()
+    /*! this text is generated when the \reimp command is used. */
+    virtual QCString trReimplementedForInternalReasons()
+    { return "Reimplementado por razones internas; el API no se ve afectado."; }
+
+    /*! this text is generated when the \warning command is used. */
+    virtual QCString trWarning()
     { return "Atención"; }
-    QCString trBugsAndLimitations()
-    { return "Bugs y Limitaciones"; }
-    QCString trVersion()
+
+    /*! this text is generated when the \bug command is used. */
+    virtual QCString trBugsAndLimitations()
+    { return "Bugs y limitaciones"; }
+
+    /*! this text is generated when the \version command is used. */
+    virtual QCString trVersion()
     { return "Versión"; }
-    QCString trDate()
+
+    /*! this text is generated when the \date command is used. */
+    virtual QCString trDate()
     { return "Fecha"; }
-    QCString trAuthors()
+
+    /*! this text is generated when the \author command is used. */
+    virtual QCString trAuthors()
     { return "Autor(es)"; }
-    QCString trReturns()
+
+    /*! this text is generated when the \return command is used. */
+    virtual QCString trReturns()
     { return "Devuelve"; }
-    QCString trSeeAlso()
+
+    /*! this text is generated when the \sa command is used. */
+    virtual QCString trSeeAlso()
     { return "Ver también"; }
-    QCString trParameters()
+
+    /*! this text is generated when the \param command is used. */
+    virtual QCString trParameters()
     { return "Parámetros"; }
-    QCString trExceptions()
+
+    /*! this text is generated when the \exception command is used. */
+    virtual QCString trExceptions()
     { return "Excepciones"; }
-    QCString trGeneratedBy()
-    { return "Generado por"; }
     
-//////////////////////////////////////////////////////////////////////////
-// new since 0.49-990307 
-//////////////////////////////////////////////////////////////////////////
+    /*! this text is used in the title page of a LaTeX document. */
+    virtual QCString trGeneratedBy()
+    { return "Generado por"; }
+
+    // new since 0.49-990307
     
-    QCString trNamespaceList()
-    { return "Lista de Namespaces"; }
-    QCString trNamespaceListDescription(bool extractAll)
+    /*! used as the title of page containing all the index of all namespaces. */
+    virtual QCString trNamespaceList()
+    { return "Lista de Namespace"; }
+
+    /*! used as an introduction to the namespace list */
+    virtual QCString trNamespaceListDescription(bool extractAll)
     {
-      QCString result="Esta es una lista de los namespaces ";
-      if (!extractAll) result+="documentados ";
-      result+="con descripciones breves:";
+      QCString result="Lista de ";
+      if (!extractAll) result+="toda la documentación de ";
+      result+="los namespaces con una breve descripción:";
       return result;
     }
-    QCString trFriends()
-    { return "Clases Amigas"; }
 
+    /*! used in the class documentation as a header before the list of all
+     *  friends of a class
+     */
+    virtual QCString trFriends()
+    { return "Amigas"; }
+    
 //////////////////////////////////////////////////////////////////////////
 // new since 0.49-990405
 //////////////////////////////////////////////////////////////////////////
     
-    QCString trRelatedFunctionDocumentation()
-    { return "Documentación de Clases Amigas y Funciones Relacionadas"; }
+    /*! used in the class documentation as a header before the list of all
+     * related classes 
+     */
+    virtual QCString trRelatedFunctionDocumentation()
+    { return "Documentación de las Funciones Relacionadas y Clases Amigas"; }
     
 //////////////////////////////////////////////////////////////////////////
 // new since 0.49-990425
 //////////////////////////////////////////////////////////////////////////
 
+    /*! used as the title of the HTML page of a class/struct/union */
     virtual QCString trCompoundReference(const char *clName,
                                     ClassDef::CompoundType compType)
-      // used as the title of the HTML page of a class/struct/union
     {
       QCString result=(QCString)clName+" ";
       switch(compType)
       {
-        case ClassDef::Class:  result+=" Clase"; break;
-        case ClassDef::Struct: result+=" Estructura"; break;
-        case ClassDef::Union:  result+=" Unión"; break;
-        case ClassDef::Interface:  result+=" Interface"; break;
-        case ClassDef::Exception:  result+=" Exception"; break;
+        case ClassDef::Class:      result+=" Clase"; break;
+        case ClassDef::Struct:     result+=" Estructura"; break;
+        case ClassDef::Union:      result+=" Unión"; break;
+        case ClassDef::Interface:  result+=" Interfaz"; break;
+        case ClassDef::Exception:  result+=" Excepción"; break;
       }
       result+=" Referencia";
       return result;
     }
+
+    /*! used as the title of the HTML page of a file */
     virtual QCString trFileReference(const char *fileName)
-      // used as the title of the HTML page of a file
     {
       QCString result=fileName;
-      result+=" Referencia de Archivos"; 
+      result+=" Archivo Referencia"; 
       return result;
     }
+
+    /*! used as the title of the HTML page of a namespace */
     virtual QCString trNamespaceReference(const char *namespaceName)
-      // used as the title of the HTML page of a namespace
     {
       QCString result=namespaceName;
-      result+=" Referencia de Namespace";
+      result+=" Namespace Referencia";
       return result;
     }
     
-    // these are for the member sections of a class, struct or union 
+    /*! \mgroup Class sections
+     *  these are for the member sections of a class, struct or union 
+     */
     virtual QCString trPublicMembers()
-    { return "Miembros Públicos"; }
+    { return "Métodos Públicos"; }
     virtual QCString trPublicSlots()
     { return "Slots Públicos"; }
     virtual QCString trSignals()
     { return "Señales"; }
     virtual QCString trStaticPublicMembers()
-    { return "Miembros Estáticos Públicos"; }
+    { return "Métodos Públicos Estáticos"; }
     virtual QCString trProtectedMembers()
-    { return "Miembros Protegidos"; }
+    { return "Métodos Protegidos"; }
     virtual QCString trProtectedSlots()
     { return "Slots Protegidos"; }
     virtual QCString trStaticProtectedMembers()
-    { return "Miembros Protegidos Estáticos"; }
+    { return "Métodos Protegidos Estáticos"; }
     virtual QCString trPrivateMembers()
-    { return "Miembros Privados"; }
+    { return "Métodos Privados"; }
     virtual QCString trPrivateSlots()
     { return "Slots Privados"; }
     virtual QCString trStaticPrivateMembers()
-    { return "Miembros Estáticos Privados"; }
-    // end of member sections 
+    { return "Métodos Privados Estáticos"; }
+    /*! \endmgroup */ 
     
+    /*! this function is used to produce a comma-separated list of items.
+     *  use generateMarker(i) to indicate where item i should be put.
+     */
     virtual QCString trWriteList(int numEntries)
     {
-      // this function is used to produce a comma-separated list of items.
-      // use generateMarker(i) to indicate where item i should be put.
       QCString result;
       int i;
       // the inherits list contain `numEntries' classes
@@ -348,60 +598,270 @@ class TranslatorSpanish : public Translator
           if (i<numEntries-2) // not the fore last entry 
             result+=", ";
           else                // the fore last entry
-            result+=" y ";
+            result+=", and ";
         }
       }
       return result; 
     }
     
+    /*! used in class documentation to produce a list of base classes,
+     *  if class diagrams are disabled.
+     */
     virtual QCString trInheritsList(int numEntries)
-      // used in class documentation to produce a list of base classes,
-      // if class diagrams are disabled.
     {
-      return "Hereda a "+trWriteList(numEntries)+".";
+      return "Herencias "+trWriteList(numEntries)+".";
     }
+
+    /*! used in class documentation to produce a list of super classes,
+     *  if class diagrams are disabled.
+     */
     virtual QCString trInheritedByList(int numEntries)
-      // used in class documentation to produce a list of super classes,
-      // if class diagrams are disabled.
     {
       return "Heredado por "+trWriteList(numEntries)+".";
     }
+
+    /*! used in member documentation blocks to produce a list of 
+     *  members that are hidden by this one.
+     */
     virtual QCString trReimplementedFromList(int numEntries)
-      // used in member documentation blocks to produce a list of 
-      // members that are hidden by this one.
     {
-      return "Reimplementado por "+trWriteList(numEntries)+".";
+      return "Reimplementado de "+trWriteList(numEntries)+".";
     }
+
+    /*! used in member documentation blocks to produce a list of
+     *  all member that overwrite the implementation of this member.
+     */
     virtual QCString trReimplementedInList(int numEntries)
     {
-      // used in member documentation blocks to produce a list of
-      // all member that overwrite the implementation of this member.
       return "Reimplementado en "+trWriteList(numEntries)+".";
     }
 
+    /*! This is put above each page as a link to all members of namespaces. */
     virtual QCString trNamespaceMembers()
-      // This is put above each page as a link to all members of namespaces.
-    { return "Miembros del Namespace"; }
+    { return "Namespace Miembros"; }
+
+    /*! This is an introduction to the page with all namespace members */
     virtual QCString trNamespaceMemberDescription(bool extractAll)
-      // This is an introduction to the page with all namespace members
     { 
-      QCString result="Esta es una lista de todos los miembros de namespace ";
-      if (!extractAll) result+="documentados ";
-      result+="con enlaces a ";
+      QCString result="Lista de ";
+      if (!extractAll) result+="toda la documentación de ";
+      result+="los namespace miembros con enlace a ";
       if (extractAll) 
-        result+="a la documentación de namespaces para cada miembro:";
+        result+="los namespace de cada miembro:";
       else 
-        result+="los namespaces a los que pertenecen:";
+        result+="la documentación de los namespaces pertenecientes a:";
       return result;
     }
+    /*! This is used in LaTeX as the title of the chapter with the 
+     *  index of all namespaces.
+     */
     virtual QCString trNamespaceIndex()
-      // This is used in LaTeX as the title of the chapter with the 
-      // index of all namespaces.
-    { return "Índice de Namespaces"; }
+    { return "Indice de Namespace"; }
+
+    /*! This is used in LaTeX as the title of the chapter containing
+     *  the documentation of all namespaces.
+     */
     virtual QCString trNamespaceDocumentation()
-      // This is used in LaTeX as the title of the chapter containing
-      // the documentation of all namespaces.
-    { return "Documentación de Namespaces"; }
+    { return "Documentación de Namespace"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990522
+//////////////////////////////////////////////////////////////////////////
+
+    /*! This is used in the documentation before the list of all
+     *  namespaces in a file.
+     */
+    virtual QCString trNamespaces()
+    { return "Namespaces"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+    /*! This is put at the bottom of a class documentation page and is
+     *  followed by a list of files that were used to generate the page.
+     */
+    virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+        bool single)
+    { // here s is one of " Class", " Struct" or " Union"
+      // single is true implies a single file
+      QCString result=(QCString)"La documentación para esta ";
+      switch(compType)
+      {
+        case ClassDef::Class:      result+="clase"; break;
+        case ClassDef::Struct:     result+="estructura"; break;
+        case ClassDef::Union:      result+="unión"; break;
+        case ClassDef::Interface:  result+="interfaz"; break;
+        case ClassDef::Exception:  result+="excepción"; break;
+      }
+      result+=" fué generada a partir ";
+      if (single) result+="del siguiente archivo:"; 
+	else result+="de los siguientes archivos:";
+      return result;
+    }
+
+    /*! This is in the (quick) index as a link to the alphabetical compound
+     * list.
+     */
+    virtual QCString trAlphabeticalList()
+    { return "Lista Alfabética"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+    /*! This is used as the heading text for the retval command. */
+    virtual QCString trReturnValues()
+    { return "Valores devueltos"; }
+
+    /*! This is in the (quick) index as a link to the main page (index.html)
+     */
+    virtual QCString trMainPage()
+    { return "Página Principal"; }
+
+    /*! This is used in references to page that are put in the LaTeX 
+     *  documentation. It should be an abbreviation of the word page.
+     */
+    virtual QCString trPageAbbreviation()
+    { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991003
+//////////////////////////////////////////////////////////////////////////
+
+    virtual QCString trSources()
+    {
+      return "Fuentes";
+    }
+    virtual QCString trDefinedAtLineInSourceFile()
+    {
+      return "Definición en la línea @0 del archivo @1.";
+    }
+    virtual QCString trDefinedInSourceFile()
+    {
+      return "Definición en el archivo @0.";
+    }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+    virtual QCString trDeprecated()
+    {
+      return "Desaprobado";
+    }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+    /*! this text is put before a collaboration diagram */
+    virtual QCString trCollaborationDiagram(const char *clName)
+    {
+      return (QCString)"Diagrama de colaboración para "+clName+":";
+    }
+    /*! this text is put before an include dependency graph */
+    virtual QCString trInclDepGraph(const char *fName)
+    {
+      return (QCString)"Dependencia gráfica adjunta para "+fName+":";
+    }
+    /*! header that is put before the list of constructor/destructors. */
+    virtual QCString trConstructorDocumentation()
+    {
+      return "Documentación del Constructor y Destructor"; 
+    }
+    /*! Used in the file documentation to point to the corresponding sources. */
+    virtual QCString trGotoSourceCode()
+    {
+      return "Ir al código fuente de este archivo.";
+    }
+    /*! Used in the file sources to point to the corresponding documentation. */
+    virtual QCString trGotoDocumentation()
+    {
+      return "Ir a la documentación de este archivo.";
+    }
+    /*! Text for the \pre command */
+    virtual QCString trPrecondition()
+    {
+      return "Precondición";
+    }
+    /*! Text for the \post command */
+    virtual QCString trPostcondition()
+    {
+      return "Postcondicón";
+    }
+    /*! Text for the \invariant command */
+    virtual QCString trInvariant()
+    {
+      return "Invariante";
+    }
+    /*! Text shown before a multi-line variable/enum initialization */
+    virtual QCString trInitialValue()
+    {
+      return "Valor inicial:";
+    }
+    /*! Text used the source code in the file index */
+    virtual QCString trCode()
+    {
+      return "código";
+    }
+    virtual QCString trGraphicalHierarchy()
+    {
+      return "Representación Gráfica de la Clase";
+    }
+    virtual QCString trGotoGraphicalHierarchy()
+    {
+      return "Ir a la representación gráfica de la jerarquía de la clase";
+    }
+    virtual QCString trGotoTextualHierarchy()
+    {
+      return "Ir a la jerarquía textual de la clase";
+    }
+    virtual QCString trPageIndex()
+    {
+      return "Página Indice";
+    }
+    virtual QCString trNote()
+    {
+      return "Nota";
+    }
+
+    virtual QCString trPublicTypes()
+    {
+      return "Tipos Públicos";
+    }
+    virtual QCString trPublicAttribs()
+    {
+      return "Atributos Públicos";
+    }
+    virtual QCString trStaticPublicAttribs()
+    {
+      return "Atributos Públicos Estáticos";
+    }
+    virtual QCString trProtectedTypes()
+    {
+      return "Tipos Protegidos";
+    }
+    virtual QCString trProtectedAttribs()
+    {
+      return "Atributos Protegidos";
+    }
+    virtual QCString trStaticProtectedAttribs()
+    {
+      return "Atributos Protegidos Estáticos";
+    }
+    virtual QCString trPrivateTypes()
+    {
+      return "Tipos Privados";
+    }
+    virtual QCString trPrivateAttribs()
+    {
+      return "Atributos Privados";
+    }
+    virtual QCString trStaticPrivateAttribs()
+    {
+      return "Atributos Privados Estáticos";
+    }
 };
 
 #endif
diff --git a/src/translator_fi.h b/src/translator_fi.h
index a3977ef..3e2ced4 100644
--- a/src/translator_fi.h
+++ b/src/translator_fi.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/translator_fr.h b/src/translator_fr.h
index 3b76c2c..ce4d0b3 100644
--- a/src/translator_fr.h
+++ b/src/translator_fr.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -46,7 +46,7 @@ class TranslatorFrench : public Translator
     
     /*! header that is put before the list of enumerations. */
     QCString trMemberEnumerationDocumentation()
-    { return "Documentation des énumérations imbriqués"; }
+    { return "Documentation des énumérations imbriquées"; }
     
     /*! header that is put before the list of member functions. */
     QCString trMemberFunctionDocumentation()
@@ -54,7 +54,7 @@ class TranslatorFrench : public Translator
     
     /*! header that is put before the list of member attributes. */
     QCString trMemberDataDocumentation()
-    { return "Documentation des données imbriqués"; }
+    { return "Documentation des données imbriquées"; }
 
     /*! this is the text of a link put after brief descriptions. */
     QCString trMore()
@@ -128,7 +128,7 @@ class TranslatorFrench : public Translator
 
     /*! This is put above each page as a link to the list of all verbatim headers */
     QCString trHeaderFiles()
-    { return "Fichiers d'entête"; }
+    { return "Fichiers d'en-tête"; }
 
     /*! This is put above each page as a link to all members of compounds. */
     QCString trCompoundMembers()
@@ -195,7 +195,7 @@ class TranslatorFrench : public Translator
 
     /*! This is an introduction to the page with the list of all header files. */
     QCString trHeaderFilesDescription()
-    { return "Liste de tous les fichiers d'entête constituant "
+    { return "Liste de tous les fichiers d'en-tête constituant "
 	"l'interface de programmation :"; }
 
     /*! This is an introduction to the page with the list of all examples */
@@ -303,7 +303,7 @@ class TranslatorFrench : public Translator
      *  list of enumerations
      */
     QCString trEnumerations()
-    { return "Enumérations"; }
+    { return "Énumérations"; }
 
     /*! This is used in the documentation of a file as a header before the 
      *  list of (global) functions
@@ -321,7 +321,7 @@ class TranslatorFrench : public Translator
      *  list of (global) variables
      */
     QCString trEnumerationValues()
-    { return "Eléments énumérés"; }
+    { return "Éléments énumérés"; }
     
     /*! This is used in man pages as the author section. */
     QCString trAuthor()
@@ -406,7 +406,7 @@ class TranslatorFrench : public Translator
     
     /*! this text is generated when the \internal command is used. */
     QCString trForInternalUseOnly()
-    { return "A usage interne uniquement."; }
+    { return "À usage interne uniquement."; }
 
     /*! this text is generated when the \reimp command is used. */
     QCString trReimplementedForInternalReasons()
@@ -457,7 +457,7 @@ class TranslatorFrench : public Translator
     // new since 0.49-990307
     
     virtual QCString trNamespaceList()
-    { return "Liste des Namespaces"; }
+    { return "Liste des namespaces"; }
 
     /*! used as an introduction to the namespace list */
     virtual QCString trNamespaceListDescription(bool extractAll)
@@ -472,7 +472,7 @@ class TranslatorFrench : public Translator
      *  friends of a class
      */
     virtual QCString trFriends()
-    { return "Friends"; }
+    { return "Amis (friends)"; }
     
 //////////////////////////////////////////////////////////////////////////
 // new since 0.49-990405
@@ -526,13 +526,13 @@ class TranslatorFrench : public Translator
      *  these are for the member sections of a class, struct or union 
      */
     virtual QCString trPublicMembers()
-    { return "Membres publiques"; }
+    { return "Membres publics"; }
     virtual QCString trPublicSlots()
-    { return "Connecteurs publiques"; }
+    { return "Connecteurs publics"; }
     virtual QCString trSignals()
     { return "Signaux"; }
     virtual QCString trStaticPublicMembers()
-    { return "Membres publiques statiques"; }
+    { return "Membres publics statiques"; }
     virtual QCString trProtectedMembers()
     { return "Membres protégés"; }
     virtual QCString trProtectedSlots()
@@ -558,15 +558,15 @@ class TranslatorFrench : public Translator
       for (i=0;i<numEntries;i++) 
       {
         // use generateMarker to generate placeholders for the class links!
-        result+=generateMarker(i); // generate marker for entry i in the list 
+        result+=generateMarker(i); // generate marker for entry i in the list
                                    // (order is left to right)
         
         if (i!=numEntries-1)  // not the last entry, so we need a separator
         {
-          if (i<numEntries-2) // not the fore last entry 
+          if (i<numEntries-2) // not the fore last entry
             result+=", ";
           else                // the fore last entry
-            result+=", and ";
+            result+=", et ";
         }
       }
       return result; 
@@ -606,12 +606,12 @@ class TranslatorFrench : public Translator
 
     /*! This is put above each page as a link to all members of namespaces. */
     virtual QCString trNamespaceMembers()
-    { return "Menbres des namespaces"; }
+    { return "Membres des namespaces"; }
 
     /*! This is an introduction to the page with all namespace members */
     virtual QCString trNamespaceMemberDescription(bool extractAll)
     { 
-      QCString result="Voici une list de tous les membres de namespace";
+      QCString result="Voici une liste de tous les membres de namespace";
       if (!extractAll) result+="documentés ";
       result+=" avec liens vers ";
       if (extractAll) 
@@ -624,13 +624,13 @@ class TranslatorFrench : public Translator
      *  index of all namespaces.
      */
     virtual QCString trNamespaceIndex()
-    { return "Index des Namespaces"; }
+    { return "Index des namespaces"; }
 
     /*! This is used in LaTeX as the title of the chapter containing
      *  the documentation of all namespaces.
      */
     virtual QCString trNamespaceDocumentation()
-    { return "Documentation des Namespaces"; }
+    { return "Documentation des namespaces"; }
 
 //////////////////////////////////////////////////////////////////////////
 // new since 0.49-990522
@@ -640,7 +640,7 @@ class TranslatorFrench : public Translator
      *  namespaces in a file.
      */
     virtual QCString trNamespaces()
-    { return "Namespaces"; }
+    { return "Espaces de nommage (namespaces)"; }
 
 //////////////////////////////////////////////////////////////////////////
 // new since 0.49-990728
@@ -688,13 +688,13 @@ class TranslatorFrench : public Translator
     /*! This is in the (quick) index as a link to the main page (index.html)
      */
     virtual QCString trMainPage()
-    { return "Page Principale"; }
+    { return "Page principale"; }
 
     /*! This is used in references to page that are put in the LaTeX
      *  documentation. It should be an abbreviation of the word page.
      */
     virtual QCString trPageAbbreviation()
-    { return "p "; }
+    { return "p. "; }
 
 //////////////////////////////////////////////////////////////////////////
 // new since 0.49-991003
diff --git a/src/translator_it.h b/src/translator_it.h
index 53fafe8..a533b0c 100644
--- a/src/translator_it.h
+++ b/src/translator_it.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/translator_jp.h b/src/translator_jp.h
index c3d8f9a..a57e12f 100644
--- a/src/translator_jp.h
+++ b/src/translator_jp.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/translator_nl.h b/src/translator_nl.h
index 221cd7f..63fdade 100644
--- a/src/translator_nl.h
+++ b/src/translator_nl.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -454,7 +454,7 @@ class TranslatorDutch : public Translator
     }
 
 //////////////////////////////////////////////////////////////////////////
-// new since 1.0.0
+// new since 0.49-991205
 //////////////////////////////////////////////////////////////////////////
 
     QCString trDeprecated()
@@ -463,7 +463,7 @@ class TranslatorDutch : public Translator
     }
 
 //////////////////////////////////////////////////////////////////////////
-// new since 1.1.0
+// new since 1.0.0
 //////////////////////////////////////////////////////////////////////////
 
     /*! this text is put before a collaboration diagram */
@@ -532,6 +532,56 @@ class TranslatorDutch : public Translator
     {
       return "Pagina Index";
     }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+    
+    QCString trNote()
+    {
+      return "Noot";
+    }
+    QCString trPublicTypes()
+    {
+      return "Public Typen";
+    }
+    QCString trPublicAttribs()
+    {
+      return "Public Attributen";
+    }
+    QCString trStaticPublicAttribs()
+    {
+      return "Static Public Attributen";
+    }
+    QCString trProtectedTypes()
+    {
+      return "Protected Typen";
+    }
+    QCString trProtectedAttribs()
+    {
+      return "Protected Attributen";
+    }
+    QCString trStaticProtectedAttribs()
+    {
+      return "Static Protected Attributen";
+    }
+    QCString trPrivateTypes()
+    {
+      return "Private Typen";
+    }
+    QCString trPrivateAttribs()
+    {
+      return "Private Attributen";
+    }
+    QCString trStaticPrivateAttribs()
+    {
+      return "Static Private Attributen";
+    }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.1
+//////////////////////////////////////////////////////////////////////////
+
 };
 
 #endif
diff --git a/src/translator_ru.h b/src/translator_ru.h
index 92c097c..9273fc7 100644
--- a/src/translator_ru.h
+++ b/src/translator_ru.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-1999 by Dimitri van Heesch.
  *
diff --git a/src/translator_se.h b/src/translator_se.h
index 2236119..853febb 100644
--- a/src/translator_se.h
+++ b/src/translator_se.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
diff --git a/src/util.cpp b/src/util.cpp
index de35573..786f872 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -317,7 +317,8 @@ void linkifyText(OutputList &ol,const char *scName,const char *name,const char *
       //if (!found) printf("Trying to link %s in %s\n",word.data(),scName);
       if (!found && 
           getDefs(scName,word,0,md,cd,fd,nd,gd) && 
-          (md->isTypedef() || md->isEnumerate() || md->isReference()) && 
+          (md->isTypedef() || md->isEnumerate() || 
+           md->isReference() || md->isVariable()) && 
           md->isLinkable() 
          )
       {
@@ -641,14 +642,17 @@ void endFile(OutputList &ol,bool external)
 }
 
 // compute the HTML anchors for a list of members
-void setAnchors(char id,MemberList *ml)
+void setAnchors(char id,MemberList *ml,int groupId)
 {
   int count=0;
   MemberDef *md=ml->first();
   while (md)
   {
     QCString anchor;
-    anchor.sprintf("%c%d",id,count++);
+    if (groupId==-1)
+      anchor.sprintf("%c%d",id,count++);
+    else
+      anchor.sprintf("%c%d_%d",id,groupId,count++);
     //printf("Member %s anchor %s\n",md->name(),anchor.data());
     md->setAnchor(anchor);
     md=ml->next();
@@ -892,7 +896,7 @@ static void trimNamespaceScope(QCString &t1,QCString &t2)
 // stored in the list should be equal.
 
 bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
-                    const char *cl,const char *ns)
+                    const char *cl,const char *ns,bool checkCV)
 {
   QCString className=cl;
   QCString namespaceName=ns;
@@ -904,10 +908,10 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
     className=className.left(til)+className.right(className.length()-tir-1);
   }
 
-  //printf("matchArguments(%s,%s) className=%s namespaceName=%s\n",
+  //printf("matchArguments(%s,%s) className=%s namespaceName=%s checkCV=%d\n",
   //    srcAl ? argListToString(srcAl).data() : "",
   //    dstAl ? argListToString(dstAl).data() : "",
-  //    cl,ns);
+  //    cl,ns,checkCV);
 
   if (srcAl==0 || dstAl==0)
   {
@@ -936,13 +940,17 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
   {
     return FALSE; // different number of arguments -> no match
   }
-  if (srcAl->constSpecifier != dstAl->constSpecifier) 
-  {
-    return FALSE; // one member is const, the other not -> no match
-  }
-  if (srcAl->volatileSpecifier != dstAl->volatileSpecifier)
+
+  if (checkCV)
   {
-    return FALSE; // one member is volatile, the other not -> no match
+    if (srcAl->constSpecifier != dstAl->constSpecifier) 
+    {
+      return FALSE; // one member is const, the other not -> no match
+    }
+    if (srcAl->volatileSpecifier != dstAl->volatileSpecifier)
+    {
+      return FALSE; // one member is volatile, the other not -> no match
+    }
   }
 
   // so far the argument list could match, so we need to compare the types of
@@ -1307,7 +1315,8 @@ bool getDefs(const QCString &scName,const QCString &memberName,
         {
           if (mmd->isLinkable())
           {
-            bool match=args==0 || matchArguments(mmd->argumentList(),argList); 
+            bool match=args==0 || matchArguments(mmd->argumentList(),argList,className,0,FALSE); 
+            //printf("match=%d\n",match);
             if (match)
             {
               ClassDef *mcd=mmd->memberClass();
@@ -1416,7 +1425,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
               {
                 argList=new ArgumentList;
                 stringToArgumentList(args,argList);
-                match=matchArguments(mmd->argumentList(),argList); 
+                match=matchArguments(mmd->argumentList(),argList,0,namespaceName,FALSE); 
               }
               if (match)
               {
@@ -1881,6 +1890,7 @@ QCString convertSlashes(const QCString &s,bool dots)
   QCString result;
   int i,l=s.length();
   for (i=0;i<l;i++)
+  {
     if (s.at(i)!='/' && (!dots || s.at(i)!='.'))
     {
       if (Config::caseSensitiveNames)
@@ -1893,7 +1903,10 @@ QCString convertSlashes(const QCString &s,bool dots)
       }
     }
     else 
+    {
       result+="_";
+    }
+  }
   return result;
 }
 
@@ -2082,3 +2095,31 @@ bool hasVisibleRoot(BaseClassList *bcl)
   return FALSE;
 }
 
+QCString convertNameToFile(const char *name)
+{
+  QCString result;
+  char c;
+  const char *p=name;
+  while ((c=*p++)!=0)
+  {
+    switch(c)
+    {
+      case ':': result+="_"; break;
+      case '<': result+="_lt"; break;
+      case '>': result+="_gt"; break;
+      case '*': result+="_ast"; break;
+      case '&': result+="_amp"; break;
+      case '|': result+="_p_"; break;
+      case '!': result+="_e_"; break;
+      case ',': result+="_x_"; break;
+      case ' ': break;
+      default: 
+        if (Config::caseSensitiveNames)
+          result+=c;
+        else
+          result+=tolower(c); 
+        break;
+    }
+  }
+  return result;
+}
diff --git a/src/util.h b/src/util.h
index d622f84..07fe0e8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
@@ -35,7 +35,7 @@ class ClassList;
 class BaseClassList;
 class GroupDef;
 
-extern void setAnchors(char id,MemberList *ml);
+extern void setAnchors(char id,MemberList *ml,int groupId=-1);
 extern QCString fileToString(const char *name);
 extern QCString dateToString(bool);
 extern void linkifyText(OutputList &ol,const char *clName,const char *name,
@@ -52,7 +52,7 @@ extern bool generateLink(OutputList &ol,const char *,
 extern void generateFileRef(OutputList &ol,const char *,
                              const char *linkTxt=0);
 extern bool matchArguments(ArgumentList *,ArgumentList *,
-                           const char *cl=0,const char *ns=0);
+                           const char *cl=0,const char *ns=0,bool checkCV=TRUE);
 extern void mergeArguments(ArgumentList *,ArgumentList *);
 extern QCString substituteClassNames(const QCString &s);
 extern QCString convertSlashes(const QCString &s,bool dots=FALSE);
@@ -88,5 +88,6 @@ QCString removeAnnonymousScopes(const QCString &s);
 void initClassHierarchy(ClassList *cl);
 bool hasVisibleRoot(BaseClassList *bcl);
 int minClassDistance(ClassDef *cd,ClassDef *bcd,int level=0);
+QCString convertNameToFile(const char *name);
 
 #endif
diff --git a/src/version.h b/src/version.h
index ac91f98..4047126 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * $Id$
+ * 
  *
  * Copyright (C) 1997-2000 by Dimitri van Heesch.
  *
-- 
cgit v0.12

