From a9f41d99f3651cd66850e9020bc3af7cb559306e Mon Sep 17 00:00:00 2001
From: dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>
Date: Wed, 30 Apr 2003 19:40:09 +0000
Subject: Release-1.3-20030430

---
 INSTALL                   |   4 +-
 README                    |   4 +-
 VERSION                   |   2 +-
 doc/config.doc            |   8 ++
 packages/rpm/doxygen.spec |   2 +-
 src/classdef.cpp          |  35 ++++---
 src/classdef.h            |   7 ++
 src/config.l              |   9 ++
 src/docparser.cpp         |  50 +++++-----
 src/docparser.h           |   5 +-
 src/doctokenizer.h        |   3 +-
 src/doctokenizer.l        |  10 +-
 src/dot.cpp               |  38 +++++---
 src/doxygen.cpp           | 238 +++++++++++++++++++++++-----------------------
 src/doxygen.h             |   4 +-
 src/filedef.cpp           |   2 +-
 src/ftvhelp.cpp           |  53 ++++++-----
 src/groupdef.cpp          |  51 ++++++----
 src/groupdef.h            |  12 +--
 src/htmldocvisitor.cpp    |  17 ++--
 src/htmlgen.cpp           |   3 +
 src/index.cpp             | 107 ++++++++++-----------
 src/latexgen.cpp          |  20 ++--
 src/memberdef.cpp         |   2 +-
 src/membergroup.cpp       |   2 +-
 src/namespacedef.cpp      |   2 +-
 src/page.h                |   3 +-
 src/pagedef.cpp           |  13 +++
 src/pagedef.h             |  13 +++
 src/perlmodgen.cpp        |  32 ++++---
 src/pre.l                 |  17 +++-
 src/rtfgen.cpp            |  24 ++---
 src/scanner.l             |   6 +-
 src/util.cpp              | 135 +++++++++++++++-----------
 src/util.h                |  31 +++---
 src/xmlgen.cpp            |  68 +++++++------
 36 files changed, 575 insertions(+), 457 deletions(-)

diff --git a/INSTALL b/INSTALL
index c0d5680..e637c92 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
-DOXYGEN Version 1.3-20030421
+DOXYGEN Version 1.3-20030430
 
 Please read the installation section of the manual 
 (http://www.doxygen.org/install.html) for instructions.
 
 --------
-Dimitri van Heesch (21 April 2003)
+Dimitri van Heesch (30 April 2003)
diff --git a/README b/README
index f91006a..a772eec 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.3_20030421
+DOXYGEN Version 1.3_20030430
 
 Please read INSTALL for compilation instructions.
 
@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
 
 Enjoy,
 
-Dimitri van Heesch (dimitri@stack.nl) (21 April 2003)
+Dimitri van Heesch (dimitri@stack.nl) (30 April 2003)
diff --git a/VERSION b/VERSION
index e2f48aa..b5343c0 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3-20030421
+1.3-20030430
diff --git a/doc/config.doc b/doc/config.doc
index a5f8ae0..3a7c23e 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -203,6 +203,7 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_warn_logfile WARN_LOGFILE
 \refitem cfg_warnings WARNINGS
 \refitem cfg_xml_dtd XML_DTD
+\refitem cfg_xml_output XML_OUTPUT
 \refitem cfg_xml_schema XML_SCHEMA
 \endsecreflist
 
@@ -1200,6 +1201,13 @@ EXTRA_PACKAGES = times
  generate an XML file that captures the structure of
  the code including all documentation. 
 
+\anchor cfg_xml_output
+<dt>\c XML_OUTPUT <dd>
+ \addindex XML_OUTPUT
+ The \c XML_OUTPUT tag is used to specify where the XML pages will be put. 
+ If a relative path is entered the value of \c OUTPUT_DIRECTORY will be 
+ put in front of it. If left blank \c xml will be used as the default path.
+
 \anchor cfg_xml_schema
 <dt>\c XML_SCHEMA <dd>
  \addindex XML_SCHEMA
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index ca0d710..7c70968 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,6 +1,6 @@
 Summary: A documentation system for C/C++.
 Name: doxygen
-Version: 1.3_20030421
+Version: 1.3_20030430
 Release: 1
 Epoch: 1
 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz
diff --git a/src/classdef.cpp b/src/classdef.cpp
index e7ff73d..6766c1f 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -36,15 +36,6 @@
 #include "debug.h"
 #include "docparser.h"
 
-static QCString stripExtension(const char *fName)
-{
-  QCString result=fName;
-  if (result.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
-  {
-    result=result.left(result.length()-Doxygen::htmlFileExtension.length());
-  }
-  return result;
-}
 
 // constructs a new class definition
 ClassDef::ClassDef(
@@ -86,6 +77,7 @@ ClassDef::ClassDef(
   m_nspace=0;
   m_fileDef=0;
   m_usesImplClassDict=0;
+  m_usedByImplClassDict=0;
   m_usesIntfClassDict=0;
   memberGroupSDict = new MemberGroupSDict;
   memberGroupSDict->setAutoDelete(TRUE);
@@ -120,6 +112,7 @@ ClassDef::~ClassDef()
   delete m_allMemberNameInfoSDict;
   delete m_exampleSDict;
   delete m_usesImplClassDict;
+  delete m_usedByImplClassDict;
   delete m_usesIntfClassDict;
   delete m_incInfo;
   delete memberGroupSDict;
@@ -586,7 +579,7 @@ void ClassDef::distributeMemberGroupDocumentation()
 
 void ClassDef::findSectionsInDocumentation()
 {
-  docFindSections(documentation(),0,this,0,docFile());
+  docFindSections(documentation(),this,0,docFile());
   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
   MemberGroup *mg;
   for (;(mg=mgli.current());++mgli)
@@ -2043,17 +2036,35 @@ void ClassDef::addUsedClass(ClassDef *cd,const char *accessName)
     m_usesImplClassDict->setAutoDelete(TRUE);
   }
   UsesClassDef *ucd=m_usesImplClassDict->find(cd->name());
-  if (ucd==0 /*|| ucd->templSpecifiers!=templSpec*/)
+  if (ucd==0)
   {
      ucd = new UsesClassDef(cd);
      m_usesImplClassDict->insert(cd->name(),ucd);
-     //ucd->templSpecifiers = templSpec;
      //printf("Adding used class %s to class %s\n",
      //    cd->name().data(),name().data());
   }
   ucd->addAccessor(accessName);
 }
 
+void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName)
+{
+  if (m_usedByImplClassDict==0) 
+  {
+    m_usedByImplClassDict = new UsesClassDict(17); 
+    m_usedByImplClassDict->setAutoDelete(TRUE);
+  }
+  UsesClassDef *ucd=m_usedByImplClassDict->find(cd->name());
+  if (ucd==0)
+  {
+     ucd = new UsesClassDef(cd);
+     m_usedByImplClassDict->insert(cd->name(),ucd);
+     //printf("Adding used by class %s to class %s\n",
+     //    cd->name().data(),name().data());
+  }
+  ucd->addAccessor(accessName);
+}
+
+
 #if 0
 /*! Builds up a dictionary of all classes that are used by the state of this 
  *  class (the "implementation"). 
diff --git a/src/classdef.h b/src/classdef.h
index 022309d..3259f44 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -164,6 +164,11 @@ class ClassDef : public Definition
       return m_usesImplClassDict; 
     }
 
+    UsesClassDict *usedByImplementationClasses() const 
+    { 
+      return m_usedByImplClassDict; 
+    }
+
     UsesClassDict *usedInterfaceClasses() const
     {
       return m_usesIntfClassDict;
@@ -270,6 +275,7 @@ class ClassDef : public Definition
     void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs);
     void addInnerCompound(Definition *d);
     void addUsedClass(ClassDef *cd,const char *accessName);
+    void addUsedByClass(ClassDef *cd,const char *accessName);
     //void initTemplateMapping();
     //void setTemplateArgumentMapping(const char *formal,const char *actual);
     //QCString getTemplateArgumentMapping(const char *formal) const;
@@ -389,6 +395,7 @@ class ClassDef : public Definition
 
     /* classes for the collaboration diagram */
     UsesClassDict *m_usesImplClassDict;
+    UsesClassDict *m_usedByImplClassDict;
     UsesClassDict *m_usesIntfClassDict;
 
     /*! Template instances that exists of this class, the key in the
diff --git a/src/config.l b/src/config.l
index 875f9e6..7516965 100644
--- a/src/config.l
+++ b/src/config.l
@@ -2226,6 +2226,15 @@ void Config::create()
 		    FALSE
                  );
   cs = addString(
+                    "XML_OUTPUT",
+                    "The XML_OUTPUT tag is used to specify where the XML pages will be put. \n"
+                    "If a relative path is entered the value of OUTPUT_DIRECTORY will be \n"
+                    "put in front of it. If left blank `xml' will be used as the default path. \n"
+                   );
+  cs->setDefaultValue("xml");
+  cs->setWidgetType(ConfigString::Dir);
+  cs->addDependency("GENERATE_XML");
+  cs = addString(
                     "XML_SCHEMA",
 		    "The XML_SCHEMA tag can be used to specify an XML schema, \n"
 		    "which can be used by a validating XML parser to check the \n"
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 27c2d18..d4df2df 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -30,7 +30,7 @@
 #include "doxygen.h"
 #include "debug.h"
 #include "util.h"
-#include "page.h"
+#include "pagedef.h"
 
 #include "docparser.h"
 #include "doctokenizer.h"
@@ -447,7 +447,7 @@ static bool findDocsForMemberOrCompound(const char *commandName,
   FileDef      *fd=0;
   NamespaceDef *nd=0;
   GroupDef     *gd=0;
-  PageInfo     *pi=0;
+  PageDef      *pd=0;
   bool found = getDefs(
       g_context.find('.')==-1?g_context.latin1():"", // `find('.') is a hack to detect files
       name.latin1(),
@@ -494,11 +494,11 @@ static bool findDocsForMemberOrCompound(const char *commandName,
       *pDef=gd;
       return TRUE;
     }
-    pi = Doxygen::pageSDict->find(cmdArg);
-    if (pi) // page
+    pd = Doxygen::pageSDict->find(cmdArg);
+    if (pd) // page
     {
-      *pDoc=pi->doc;
-      *pDef=(Definition *)pi;
+      *pDoc=pd->documentation();
+      *pDef=pd;
       return TRUE;
     }
     bool ambig;
@@ -1624,7 +1624,7 @@ DocRef::DocRef(DocNode *parent,const QString &target) :
    m_parent(parent), m_refToSection(FALSE), m_refToAnchor(FALSE)
 {
   Definition  *compound = 0;
-  PageInfo    *pageInfo = 0;
+  //PageInfo    *pageInfo = 0;
   QCString     anchor;
   ASSERT(!target.isEmpty());
   SectionInfo *sec = Doxygen::sectionDict[target];
@@ -1639,16 +1639,17 @@ DocRef::DocRef(DocNode *parent,const QString &target) :
     m_refToAnchor  = sec->type==SectionInfo::Anchor;
     m_refToSection = sec->type!=SectionInfo::Anchor;
   }
-  else if (resolveLink(g_context,target,TRUE,&compound,&pageInfo,anchor))
+  else if (resolveLink(g_context,target,TRUE,&compound,/*&pageInfo,*/anchor))
   {
     m_text = linkToText(target);
     m_anchor = anchor;
-    if (pageInfo) // ref to page 
-    {
-      m_file   = pageInfo->getOutputFileBase();
-      m_ref    = pageInfo->getReference();
-    }
-    else if (compound) // ref to compound
+    //if (pageInfo) // ref to page 
+    //{
+    //  m_file   = pageInfo->getOutputFileBase();
+    //  m_ref    = pageInfo->getReference();
+    //}
+    //else 
+    if (compound) // ref to compound
     {
       if (anchor.isEmpty() &&                                  /* compound link */
           compound->definitionType()==Definition::TypeGroup && /* is group */
@@ -1713,7 +1714,7 @@ DocLink::DocLink(DocNode *parent,const QString &target) :
       m_parent(parent)
 {
   Definition *compound;
-  PageInfo *page;
+  //PageInfo *page;
   QCString anchor;
   m_refText = target;
   if (!m_refText.isEmpty() && m_refText.at(0)=='#')
@@ -1721,7 +1722,7 @@ DocLink::DocLink(DocNode *parent,const QString &target) :
     m_refText = m_refText.right(m_refText.length()-1);
   }
   if (resolveLink(g_context,stripKnownExtensions(target),g_inSeeBlock,
-                  &compound,&page,anchor))
+                  &compound,/*&page,*/anchor))
   {
     m_anchor = anchor;
     if (compound)
@@ -1729,11 +1730,11 @@ DocLink::DocLink(DocNode *parent,const QString &target) :
       m_file = compound->getOutputFileBase();
       m_ref  = compound->getReference();
     }
-    else if (page)
-    {
-      m_file = page->getOutputFileBase();
-      m_ref  = page->getReference();
-    }
+    //else if (page)
+    //{
+    //  m_file = page->getOutputFileBase();
+    //  m_ref  = page->getReference();
+    //}
   }
   else // oops, bogus target
   {
@@ -4742,8 +4743,11 @@ DocNode *validatingParseText(const char *input)
   return txt;
 }
 
-void docFindSections(const char *input,PageInfo *pi,Definition *d,MemberGroup *mg,const char *fileName)
+void docFindSections(const char *input,
+                     Definition *d,
+                     MemberGroup *mg,
+                     const char *fileName)
 {
-  doctokenizerYYFindSections(input,pi,d,mg,fileName);
+  doctokenizerYYFindSections(input,d,mg,fileName);
 }
 
diff --git a/src/docparser.h b/src/docparser.h
index d413a5a..4afafd8 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -63,7 +63,10 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
 DocNode *validatingParseText(const char *input);
 
 /*! Searches for section and anchor commands in the input */
-void docFindSections(const char *input,PageInfo *pi,Definition *d,MemberGroup *m,const char *fileName);
+void docFindSections(const char *input,
+                     Definition *d,
+                     MemberGroup *m,
+                     const char *fileName);
 
 //---------------------------------------------------------------------------
 
diff --git a/src/doctokenizer.h b/src/doctokenizer.h
index c258ee1..ead3a3f 100644
--- a/src/doctokenizer.h
+++ b/src/doctokenizer.h
@@ -24,7 +24,6 @@
 #include "htmlattrib.h"
 
 class Definition;
-class PageInfo;
 class MemberGroup;
 
 enum Tokens
@@ -110,7 +109,7 @@ extern FILE *doctokenizerYYin;
 const char *tokToString(int token);
 
 // operations on the scanner
-void doctokenizerYYFindSections(const char *input,PageInfo *pi,Definition *d,
+void doctokenizerYYFindSections(const char *input,Definition *d,
                                 MemberGroup *mg,const char *fileName);
 void doctokenizerYYinit(const char *input,const char *fileName);
 void doctokenizerYYcleanup();
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 0ed018d..031d5ec 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -30,7 +30,7 @@
 #include "section.h"
 #include "membergroup.h"
 #include "definition.h"
-#include "page.h"
+#include "doxygen.h"
 
 #define YY_NEVER_INTERACTIVE 1
   
@@ -45,7 +45,6 @@ static QString g_fileName;
 static bool g_insidePre;
 
 // context for section finding phase
-static PageInfo    *g_pageInfo;
 static Definition  *g_definition;
 static MemberGroup *g_memberGroup;
 static QCString     g_secLabel;
@@ -217,10 +216,6 @@ static void processSection()
   {
     file = g_definition->getOutputFileBase();
   }
-  else if (g_pageInfo)
-  {
-    file = g_pageInfo->getOutputFileBase();
-  }
   else
   {
     warn(g_fileName,yylineno,"Found section/anchor %s without context\n",g_secLabel.data()); 
@@ -809,14 +804,13 @@ LABELID   [a-z_A-Z][a-z_A-Z0-9\-]*
 
 //--------------------------------------------------------------------------
 
-void doctokenizerYYFindSections(const char *input,PageInfo *pi,Definition *d,
+void doctokenizerYYFindSections(const char *input,Definition *d,
                                 MemberGroup *mg,const char *fileName)
 {
   if (input==0) return;
   g_inputString = input;
   //printf("parsing --->`%s'<---\n",input);
   g_inputPos    = 0;
-  g_pageInfo    = pi;
   g_definition  = d;
   g_memberGroup = mg;
   g_fileName    = fileName;
diff --git a/src/dot.cpp b/src/dot.cpp
index 32a9841..110a86d 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -1086,31 +1086,47 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot,
 
 void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
 {
+  //printf("DocClassGraph::buildGraph(%s,distance=%d,base=%d)\n",
+  //    cd->name().data(),distance,base);
   // ---- Add inheritance relations
 
-  BaseClassListIterator bcli(base ? *cd->baseClasses() : *cd->subClasses());
-  BaseClassDef *bcd;
-  for ( ; (bcd=bcli.current()) ; ++bcli )
+  if (m_graphType == Inheritance)
   {
-    //printf("-------- inheritance relation %s->%s templ=`%s'\n",
-    //            cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());
-    addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName,
-               bcd->templSpecifiers,base); 
+    BaseClassListIterator bcli(base ? *cd->baseClasses() : *cd->subClasses());
+    BaseClassDef *bcd;
+    for ( ; (bcd=bcli.current()) ; ++bcli )
+    {
+      //printf("-------- inheritance relation %s->%s templ=`%s'\n",
+      //            cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());
+      addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName,
+          bcd->templSpecifiers,base); 
+    }
   }
-  if (m_graphType != Inheritance)
+  else // m_graphType != Inheritance
   {
+    ASSERT(m_graphType==Implementation);
 
     // ---- Add usage relations
     
     UsesClassDict *dict = 
-      m_graphType==Implementation ? cd->usedImplementationClasses() :
-                                    cd->usedInterfaceClasses();
+      base ? cd->usedImplementationClasses() : 
+             cd->usedByImplementationClasses()
+      ;
     if (dict)
     {
       UsesClassDictIterator ucdi(*dict);
       UsesClassDef *ucd;
       for (;(ucd=ucdi.current());++ucdi)
       {
+        //if (base)
+        //{
+        //  printf("%s uses %s\n",cd->name().data(),ucd->classDef->name().data());
+        //}
+        //else
+        //{
+        //  printf("%s is used by %s\n",cd->name().data(),ucd->classDef->name().data());
+        //}
+        //printf("drawing\n");
         QCString label;
         QDictIterator<void> dvi(*ucd->accessors);
         const char *s;
@@ -1128,7 +1144,7 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base)
           }
         }
         addClass(ucd->classDef,n,EdgeInfo::Purple,label,distance,0,
-                 ucd->templSpecifiers,base);
+            ucd->templSpecifiers,base);
       }
     }
   }
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index b3600f7..601ac2d 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -58,8 +58,7 @@
 #include "defgen.h"
 #include "perlmodgen.h"
 #include "reflist.h"
-#include "page.h"
-//#include "packagedef.h"
+#include "pagedef.h"
 #include "bufstr.h"
 #include "commentcnv.h"
 #include "cmdmapper.h"
@@ -83,15 +82,12 @@ MemberNameSDict Doxygen::functionNameSDict(10000);
 FileNameList   Doxygen::inputNameList;           // all input files
 FileNameDict  *Doxygen::inputNameDict;          
 
-//GroupList      Doxygen::groupList;               // all groups
 GroupSDict      Doxygen::groupSDict(17);          
 
 FormulaList    Doxygen::formulaList;             // all formulas
 FormulaDict    Doxygen::formulaDict(1009);       // all formulas
 FormulaDict    Doxygen::formulaNameDict(1009);   // the label name of all formulas
 
-//PackageSDict   Doxygen::packageDict(257);         // java packages
-
 PageSDict      *Doxygen::pageSDict = new PageSDict(1009);          // all doc pages
 PageSDict      *Doxygen::exampleSDict = new PageSDict(1009);       // all examples
 SectionDict    Doxygen::sectionDict(257);        // all page sections
@@ -107,7 +103,7 @@ QDict<void>    Doxygen::expandAsDefinedDict(257); // all macros that should be e
 
 QIntDict<MemberGroupInfo> Doxygen::memGrpInfoDict(1009); // dictionary of the member groups heading
 
-PageInfo      *Doxygen::mainPage = 0;           
+PageDef       *Doxygen::mainPage = 0;           
 bool           Doxygen::insideMainPage = FALSE; // are we generating docs for the main page?
 QTextStream    Doxygen::tagFile;
 NamespaceDef  *Doxygen::globalScope = new NamespaceDef("<globalScope>",1,"<globalScope>");
@@ -200,12 +196,12 @@ static void addRelatedPage(Entry *root)
     if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict[g->groupname])) break;
   }
   //printf("addRelatedPage() %s gd=%p\n",root->name.data(),gd);
-  PageInfo *pi = addRelatedPage(root->name,root->args,root->doc,root->anchors,
+  PageDef *pd = addRelatedPage(root->name,root->args,root->doc,root->anchors,
       root->fileName,root->startLine,
       root->sli,
       gd,root->tagInfo
      );
-  if (pi)
+  if (pd)
   {
     // see if the function is inside a namespace
     Definition *ctx = 0;
@@ -230,7 +226,9 @@ static void addRelatedPage(Entry *root)
       bool ambig;
       ctx=findFileDef(Doxygen::inputNameDict,root->fileName,ambig);
     }
-    pi->context = ctx;
+    pd->setOuterScope(ctx);
+    pd->addSectionsToDefinition(root->anchors);
+    //pi->context = ctx;
   }
 }
 
@@ -277,11 +275,15 @@ static void buildGroupListFiltered(Entry *root,bool additional)
       }
       else
       {
-        gd = new GroupDef(root->fileName,root->startLine,root->name,root->type);
         if (root->tagInfo)
         {
+          gd = new GroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo->fileName);
           gd->setReference(root->tagInfo->tagName);
         }
+        else
+        {
+          gd = new GroupDef(root->fileName,root->startLine,root->name,root->type);
+        }
         gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
         gd->setDocumentation(root->doc,root->docFile,root->docLine);
         gd->addSectionsToDefinition(root->anchors);
@@ -798,21 +800,6 @@ static void addClassToContext(Entry *root)
     //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data());
     Doxygen::classSDict.append(fullName,cd);
 
-    // also add class to the correct structural context 
-    //Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName);
-    //if (d==0)
-    //{
-    //  warn(root->fileName,root->startLine,
-    //       "Warning: Internal inconsistency: scope for class %s not "
-    //       "found!\n",fullName.data()
-    //      );
-    //}
-    //else
-    //{
-    //  //printf("****** adding %s to scope %s\n",cd->name().data(),d->name().data());
-    //  d->addInnerCompound(cd);
-    //  cd->setOuterScope(d);
-    //}
   }
 }
             
@@ -853,6 +840,9 @@ static void buildClassDocList(Entry *root)
 
 static void resolveClassNestingRelations()
 {
+  ClassSDict::Iterator cli(Doxygen::classSDict);
+  for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
+
   int nestingLevel=0;
   bool done=FALSE;
   while (!done)
@@ -864,10 +854,11 @@ static void resolveClassNestingRelations()
     ClassDef *cd=0;
     for (cli.toFirst();(cd=cli.current());++cli)
     {
+      //printf("nested relation for class %s\n",cd->name().data());
       if (cd->name().contains("::")==nestingLevel)
       {
+        cd->visited=TRUE;
         //printf("Level=%d processing=%s\n",nestingLevel,cd->name().data());
-        done=FALSE;
         // also add class to the correct structural context 
         Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,cd->name());
         if (d==0)
@@ -884,8 +875,10 @@ static void resolveClassNestingRelations()
           cd->setOuterScope(d);
         }
       }
+      if (!cd->visited) done=FALSE;
     }
     nestingLevel++;
+    //printf("nestingLevel=%d\n",nestingLevel);
   }
 }
 
@@ -2774,21 +2767,6 @@ static void transferRelatedFunctionDocumentation()
 }
 
 //----------------------------------------------------------------------
-static void replaceNamespaceAliases(QCString &scope,int i)
-{
-  //printf("replaceNamespaceAliases(%s,%d)\n",scope.data(),i);
-  while (i>0)
-  {
-    QCString *s = Doxygen::namespaceAliasDict[scope.left(i)];
-    if (s)
-    {
-      scope=*s+scope.right(scope.length()-i);
-      i=s->length();
-    }
-    i=scope.findRev("::",i-1);
-  }
-  //printf("replaceNamespaceAliases() result=%s\n",scope.data());
-}
 
 /*! make a dictionary of all template arguments of class cd
  * that are part of the base class name. 
@@ -3034,6 +3012,7 @@ static void findUsedClassesForClass(Entry *root,
                   if (isArtificial) usedCd->setClassIsArtificial();
                   Debug::print(Debug::Classes,0,"    Adding used class `%s'\n", usedCd->name().data());
                   instanceCd->addUsedClass(usedCd,md->name());
+                  usedCd->addUsedByClass(instanceCd,md->name());
                 }
               }
             }
@@ -3049,6 +3028,7 @@ static void findUsedClassesForClass(Entry *root,
               found=TRUE;
               Debug::print(Debug::Classes,0,"    Adding used class `%s'\n", usedCd->name().data());
               instanceCd->addUsedClass(usedCd,md->name()); // class exists 
+              usedCd->addUsedByClass(instanceCd,md->name());
             }
           }
           if (delTempNames)
@@ -3077,6 +3057,7 @@ static void findUsedClassesForClass(Entry *root,
             if (isArtificial) usedCd->setClassIsArtificial();
              Debug::print(Debug::Classes,0,"    Adding used class `%s'\n", usedCd->name().data());
             instanceCd->addUsedClass(usedCd,md->name()); 
+            usedCd->addUsedByClass(instanceCd,md->name());
           }
         }
       }
@@ -3740,17 +3721,17 @@ static void addListReferences()
     gd->addListReferences();
   }
   PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
-    QCString name = pi->name;
-    if (pi->getGroupDef())
+    QCString name = pd->name();
+    if (pd->getGroupDef())
     {
-      name = pi->getGroupDef()->getOutputFileBase().copy();
+      name = pd->getGroupDef()->getOutputFileBase().copy();
     }
-    addRefItem(pi->xrefListItems,
+    addRefItem(pd->xrefListItems(),
                theTranslator->trPage(TRUE,TRUE),
-               name,pi->title);
+               name,pd->title());
   }
 }
 
@@ -4026,7 +4007,9 @@ static bool findGlobalMember(Entry *root,
         // the same file. This is needed because static members with the same
         // name can be in different files. Thus it would be wrong to just
         // put the comment block at the first syntactically matching member.
-        if (matching && md->isStatic() && md->getDefFileName()!=root->fileName)
+        if (matching && md->isStatic() && 
+            md->getDefFileName()!=root->fileName && 
+            mn->count()>1)
         {
           matching = FALSE;
         }
@@ -5869,10 +5852,10 @@ static void findSectionsInDocumentation()
   }
   // for each page
   PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
-    pi->findSectionsInDocumentation();
+    pd->findSectionsInDocumentation();
   }
   if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
 }
@@ -6048,17 +6031,18 @@ static void findMainPage(Entry *root)
       //printf("Found main page! \n======\n%s\n=======\n",root->doc.data());
       QCString title=root->args.stripWhiteSpace();
       QCString indexName=Config_getBool("GENERATE_TREEVIEW")?"main":"index";
-      Doxygen::mainPage = new PageInfo(root->fileName,root->startLine,
+      Doxygen::mainPage = new PageDef(root->fileName,root->startLine,
                               indexName, root->doc,title);
       //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
-      Doxygen::mainPage->fileName = indexName;
+      Doxygen::mainPage->setFileName(indexName);
+      Doxygen::mainPage->addSectionsToDefinition(root->anchors);
       //Doxygen::mainPage->addSections(root->anchors);
           
       // a page name is a label as well!
       SectionInfo *si=new SectionInfo(
           indexName,
-          Doxygen::mainPage->name,
-          Doxygen::mainPage->title,
+          Doxygen::mainPage->name(),
+          Doxygen::mainPage->title(),
           SectionInfo::Section);
       Doxygen::sectionDict.insert(indexName,si);
     }
@@ -6089,7 +6073,7 @@ static void resolveUserReferences()
     //printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n",
     //        si->label.data(),si->definition?si->definition->name().data():"<none>",
     //        si->fileName.data());
-    PageInfo *pi=0;
+    PageDef *pd=0;
 
     // hack: the items of a todo/test/bug/deprecated list are all fragments from 
     // different files, so the resulting section's all have the wrong file 
@@ -6115,10 +6099,10 @@ static void resolveUserReferences()
       // if this section is in a page and the page is in a group, then we
       // have to adjust the link file name to point to the group.
       if (!si->fileName.isEmpty() && 
-          (pi=Doxygen::pageSDict->find(si->fileName)) &&
-          pi->getGroupDef())
+          (pd=Doxygen::pageSDict->find(si->fileName)) &&
+          pd->getGroupDef())
       {
-        si->fileName=pi->getGroupDef()->getOutputFileBase().copy();
+        si->fileName=pd->getGroupDef()->getOutputFileBase().copy();
       }
 
       if (si->definition)
@@ -6156,20 +6140,20 @@ static void generatePageDocs()
   //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageSDict->count());
   if (documentedPages==0) return;
   PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
-    if (!pi->getGroupDef() && !pi->isReference())
+    if (!pd->getGroupDef() && !pd->isReference())
     {
-      msg("Generating docs for page %s...\n",pi->name.data());
+      msg("Generating docs for page %s...\n",pd->name().data());
       //outputList->disable(OutputGenerator::Man);
       QCString pageName;
       if (Config_getBool("CASE_SENSE_NAMES"))
-        pageName=pi->name.copy();
+        pageName=pd->name();
       else
-        pageName=pi->name.lower();
+        pageName=pd->name().lower();
 
-      startFile(*outputList,pageName,pageName,pi->title);
+      startFile(*outputList,pageName,pageName,pd->title());
  
       // save old generator state and write title only to Man generator
       outputList->pushGeneratorState();
@@ -6179,8 +6163,8 @@ static void generatePageDocs()
       outputList->popGeneratorState();
       
       SectionInfo *si=0;
-      if (!pi->title.isEmpty() && !pi->name.isEmpty() &&
-          (si=Doxygen::sectionDict.find(pi->name))!=0)
+      if (!pd->title().isEmpty() && !pd->name().isEmpty() &&
+          (si=Doxygen::sectionDict.find(pd->name()))!=0)
       {
         outputList->startSection(si->label,si->title,si->type);
         outputList->docify(si->title);
@@ -6188,27 +6172,46 @@ static void generatePageDocs()
       }
       outputList->startTextBlock();
       QCString scName;
-      if (pi->context && 
-          (pi->context->definitionType()==Definition::TypeClass ||
-           pi->context->definitionType()==Definition::TypeNamespace
+      if (pd->getOuterScope() && 
+          (pd->getOuterScope()->definitionType()==Definition::TypeClass ||
+           pd->getOuterScope()->definitionType()==Definition::TypeNamespace
           )
          )
       {
-        scName=pi->context->name();
+        scName=pd->getOuterScope()->name();
       }
-      outputList->parseDoc(pi->defFileName,pi->defLine,scName,0,pi->doc,FALSE,pi->sectionDict);
+      outputList->parseDoc(pd->docFile(),
+                           pd->docLine(),
+                           scName,0,
+                           pd->documentation(),
+                           FALSE
+                           /*,pd->sectionDict*/);
       outputList->endTextBlock();
       endFile(*outputList);
       //outputList->enable(OutputGenerator::Man);
 
-      if (!Config_getString("GENERATE_TAGFILE").isEmpty() && pi->name!="todo" && pi->name!="test")
+      if (!Config_getString("GENERATE_TAGFILE").isEmpty())
       {
-        Doxygen::tagFile << "  <compound kind=\"page\">" << endl;
-        Doxygen::tagFile << "    <name>" << pi->name << "</name>" << endl;
-        Doxygen::tagFile << "    <title>" << pi->title << "</title>" << endl;
-        Doxygen::tagFile << "    <filename>" << pi->name << "</filename>" << endl;
-        pi->writeDocAnchorsToTagFile();
-        Doxygen::tagFile << "  </compound>" << endl;
+        bool found=FALSE;
+        QDictIterator<RefList> rli(*Doxygen::xrefLists);
+        RefList *rl;
+        for (rli.toFirst();(rl=rli.current());++rli)
+        {
+          if (rl->listName()==pd->name())
+          {
+            found=TRUE;
+            break;
+          }
+        }
+        if (!found) // not one of the generated related pages
+        {
+          Doxygen::tagFile << "  <compound kind=\"page\">" << endl;
+          Doxygen::tagFile << "    <name>" << pd->name() << "</name>" << endl;
+          Doxygen::tagFile << "    <title>" << convertToXML(pd->title()) << "</title>" << endl;
+          Doxygen::tagFile << "    <filename>" << pd->getOutputFileBase() << "</filename>" << endl;
+          pd->writeDocAnchorsToTagFile();
+          Doxygen::tagFile << "  </compound>" << endl;
+        }
       }
     }
   }
@@ -6233,13 +6236,14 @@ static void buildExampleList(Entry *root)
       }
       else
       {
-        PageInfo *pi=new PageInfo(root->fileName,root->startLine,
+        PageDef *pd=new PageDef(root->fileName,root->startLine,
                                   root->name,root->doc,root->args);
-        pi->fileName = convertNameToFile(pi->name+"-example");
+        pd->setFileName(convertNameToFile(pd->name()+"-example"));
+        pd->addSectionsToDefinition(root->anchors);
         //pi->addSections(root->anchors);
         
-        Doxygen::exampleSDict->inSort(root->name,pi);
-        addExampleToGroups(root,pi);
+        Doxygen::exampleSDict->inSort(root->name,pd);
+        addExampleToGroups(root,pd);
       }
     }
   }
@@ -6258,20 +6262,20 @@ static void generateExampleDocs()
 {
   outputList->disable(OutputGenerator::Man);
   PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
-    msg("Generating docs for example %s...\n",pi->name.data());
-    QCString n=pi->fileName;
+    msg("Generating docs for example %s...\n",pd->name().data());
+    QCString n=pd->getOutputFileBase();
     startFile(*outputList,n,n,"Example Documentation");
     startTitle(*outputList,n);
-    outputList->docify(pi->name);
+    outputList->docify(pd->name());
     endTitle(*outputList,n,0);
-    outputList->parseDoc(pi->name,                                 // file
-                         pi->defLine,                              // startLine
-                         pi->context?pi->context->name().data():0, // context
+    outputList->parseDoc(pd->docFile(),                            // file
+                         pd->docLine(),                            // startLine
+                         pd->getOuterScope()?pd->getOuterScope()->name().data():0, // context
                          0,                                        // memberDef
-                         pi->doc+"\n\\include "+pi->name,          // docs
+                         pd->documentation()+"\n\\include "+pd->name(),          // docs
                          TRUE                                      // is example
                         );
     endFile(*outputList);
@@ -7520,14 +7524,6 @@ void parseInput()
     s=imagePathList.next(); 
   }
 
-  //QDictIterator<FileName> fndi(*Doxygen::imageNameDict);
-  //FileName *fn;
-  //for (;(fn=fndi.current());++fndi)
-  //{
-  //  printf("File Name %s\n",fn->fileName());
-  //}
-  
-
   msg("Searching for dot files...\n");
   QStrList &dotFileList=Config_getList("DOTFILE_DIRS");
   s=dotFileList.first();
@@ -7735,6 +7731,25 @@ void parseInput()
     exit(1);
   }
   
+  QCString &xmlOutput = Config_getString("XML_OUTPUT");
+  bool &generateXml = Config_getBool("GENERATE_XML");
+  if (xmlOutput.isEmpty() && generateXml)
+  {
+    xmlOutput=outputDirectory+"/xml";
+  }
+  else if (xmlOutput && xmlOutput[0]!='/' && xmlOutput[1]!=':')
+  {
+    xmlOutput.prepend(outputDirectory+'/');
+  }
+  QDir xmlDir(xmlOutput);
+  if (generateXml && !xmlDir.exists() && !xmlDir.mkdir(xmlOutput))
+  {
+    err("Could not create output directory %s\n",xmlOutput.data());
+    delete root;
+    cleanUpDoxygen();
+    exit(1);
+  }
+  
   QCString &latexOutput = Config_getString("LATEX_OUTPUT");
   bool &generateLatex = Config_getBool("GENERATE_LATEX");
   if (latexOutput.isEmpty() && generateLatex)
@@ -7854,12 +7869,6 @@ void parseInput()
   msg("Creating members for template instances...\n");
   createTemplateInstanceMembers();
 
-  //if (Config_getBool("HAVE_DOT") && Config_getBool("COLLABORATION_GRAPH"))
-  //{
-  //  msg("Computing class implementation usage relations...\n");
-  //  computeClassImplUsageRelations();
-  //}
-
   msg("Computing class relations...\n");
   computeTemplateClassRelations(); 
   computeClassRelations();        
@@ -7880,9 +7889,6 @@ void parseInput()
   msg("Building page list...\n");
   buildPageList(root);
 
-  //msg("Building package list...\n");
-  //buildPackageList(root);
-
   msg("Search for main page...\n");
   findMainPage(root);
 
@@ -7898,15 +7904,9 @@ void parseInput()
   msg("Determining which enums are documented\n");
   findDocumentedEnumValues();
 
-  //msg("Computing member references...\n");
-  //computeMemberReferences(); 
-
   msg("Computing member relations...\n");
   computeMemberRelations();
 
-  //msg("Adding classes to their packages...\n");
-  //addClassesToPackages();
-
   msg("Building full member lists recursively...\n");
   buildCompleteMemberLists();
   
@@ -8044,10 +8044,6 @@ void generateOutput()
   msg("Generating group index...\n");
   writeGroupIndex(*outputList);
  
-
-  //msg("Generating package index...\n");
-  //generatePackageDocs();
-
   msg("Generating example index...\n");
   writeExampleIndex(*outputList);
   
diff --git a/src/doxygen.h b/src/doxygen.h
index b35a04b..59c2f05 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -37,7 +37,7 @@
 
 class PageSList;
 class PageSDict;
-class PageInfo;
+class PageDef;
 
 typedef QList<QCString>    StringList;
 typedef QDict<FileDef>     FileDict;
@@ -64,7 +64,7 @@ class Doxygen
     static ClassSDict                hiddenClasses;
     static PageSDict                *exampleSDict;
     static PageSDict                *pageSDict;
-    static PageInfo                 *mainPage;
+    static PageDef                  *mainPage;
     static bool                      insideMainPage;
     static FileNameDict             *includeNameDict;
     static FileNameDict             *exampleNameDict;
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 0849901..78710fc 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -105,7 +105,7 @@ void FileDef::distributeMemberGroupDocumentation()
 
 void FileDef::findSectionsInDocumentation()
 {
-  docFindSections(documentation(),0,this,0,docFile());
+  docFindSections(documentation(),this,0,docFile());
   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
   MemberGroup *mg;
   for (;(mg=mgli.current());++mgli)
diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp
index 605181b..54514e6 100644
--- a/src/ftvhelp.cpp
+++ b/src/ftvhelp.cpp
@@ -5,8 +5,6 @@
  * Modified by Dimitri van Heesch (c) 2003
  *
  * Folder Tree View for offline help on browsers that do not support HTML Help.
- * Uses the FTV structure from: 
- * http://www.geocities.com/Paris/LeftBank/2178/ftexample.html
  */
 
 #include <stdio.h>
@@ -506,30 +504,37 @@ void FTVHelp::generateLink(QTextStream &t,FTVNode *n)
   QCString *dest;
   //printf("FTVHelp::generateLink(ref=%s,file=%s,anchor=%s\n",
   //    n->ref.data(),n->file.data(),n->anchor.data());
-  if (!n->ref.isEmpty()) // link to entity imported via tag file
+  if (n->file.isEmpty()) // no link
   {
-    t << "<a class=\"elRef\" ";
-    t << "doxygen=\"" << n->ref << ":";
-    if ((dest=Doxygen::tagDestinationDict[n->ref])) t << *dest << "/";
-    t << "\" ";
+    t << "<b>" << n->name << "</b>";
   }
-  else // local link
+  else // link into other frame
   {
-    t << "<a class=\"el\" ";
-  }
-  t << "href=\"";
-  if (!n->ref.isEmpty())
-  {
-    if ((dest=Doxygen::tagDestinationDict[n->ref])) t << *dest << "/";
-  }
-  if (!n->file.isEmpty()) t << n->file << Doxygen::htmlFileExtension;
-  if (!n->anchor.isEmpty()) t << "#" << n->anchor;
-  t << "\" target=\"basefrm\">";
-  t << n->name;
-  t << "</a>";
-  if (!n->ref.isEmpty())
-  {
-    t << "&nbsp;[external]";
+    if (!n->ref.isEmpty()) // link to entity imported via tag file
+    {
+      t << "<a class=\"elRef\" ";
+      t << "doxygen=\"" << n->ref << ":";
+      if ((dest=Doxygen::tagDestinationDict[n->ref])) t << *dest << "/";
+      t << "\" ";
+    }
+    else // local link
+    {
+      t << "<a class=\"el\" ";
+    }
+    t << "href=\"";
+    if (!n->ref.isEmpty())
+    {
+      if ((dest=Doxygen::tagDestinationDict[n->ref])) t << *dest << "/";
+    }
+    t << n->file << Doxygen::htmlFileExtension;
+    if (!n->anchor.isEmpty()) t << "#" << n->anchor;
+    t << "\" target=\"basefrm\">";
+    t << n->name;
+    t << "</a>";
+    if (!n->ref.isEmpty())
+    {
+      t << "&nbsp;[external]";
+    }
   }
 }
 
@@ -634,7 +639,7 @@ void FTVHelp::generateTreeView()
       t << cssfi.fileName();
     }
     t << "\">" << endl;
-    t << "    <title>Test</title>\n";
+    t << "    <title>TreeView</title>\n";
     t << "    <style type=\"text/css\">\n";
     t << "    <!--\n";
     t << "    .directory { font-size: 10pt; font-weight: bold; }\n";
diff --git a/src/groupdef.cpp b/src/groupdef.cpp
index 6f47916..38a9392 100644
--- a/src/groupdef.cpp
+++ b/src/groupdef.cpp
@@ -29,10 +29,11 @@
 #include "message.h"
 #include "membergroup.h"
 #include "doxygen.h"
-#include "page.h"
+#include "pagedef.h"
+#include "docparser.h"
 
-GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t) : 
-   Definition(df,dl,na)
+GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t,
+                   const char *refFileName) : Definition(df,dl,na)
 {
   fileList = new FileList;
   classSDict = new ClassSDict(257);
@@ -42,7 +43,14 @@ GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t) :
   exampleDict = new PageSDict(257);
   allMemberList = new MemberList;
   allMemberNameInfoSDict = new MemberNameInfoSDict(17);
-  fileName = (QCString)"group_"+na;
+  if (refFileName)
+  {
+    fileName=stripExtension(refFileName);
+  }
+  else
+  {
+    fileName = (QCString)"group_"+na;
+  }
   setGroupTitle( t );
   memberGroupSDict = new MemberGroupSDict;
   memberGroupSDict->setAutoDelete(TRUE);
@@ -106,7 +114,7 @@ void GroupDef::distributeMemberGroupDocumentation()
 
 void GroupDef::findSectionsInDocumentation()
 {
-  docFindSections(documentation(),0,this,0,docFile());
+  docFindSections(documentation(),this,0,docFile());
   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
   MemberGroup *mg;
   for (;(mg=mgli.current());++mgli)
@@ -145,16 +153,16 @@ void GroupDef::addNamespace(const NamespaceDef *def)
     namespaceList->append(def);
 }
 
-void GroupDef::addPage(PageInfo *def)
+void GroupDef::addPage(PageDef *def)
 {
   //printf("Making page %s part of a group\n",def->name.data());
-  pageDict->append(def->name,def);
+  pageDict->append(def->name(),def);
   def->makePartOfGroup(this);
 }
 
-void GroupDef::addExample(const PageInfo *def)
+void GroupDef::addExample(const PageDef *def)
 {
-  exampleDict->append(def->name,def);
+  exampleDict->append(def->name(),def);
 }
 
 
@@ -555,13 +563,13 @@ void GroupDef::writeDocumentation(OutputList &ol)
     writeDetailedDocumentation(ol);
   }
 
-  PageInfo *pi=0;
+  PageDef *pd=0;
   PageSDict::Iterator pdi(*pageDict);
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
-    if (!pi->isReference())
+    if (!pd->isReference())
     {
-      QCString pageName = pi->getOutputFileBase();
+      QCString pageName = pd->getOutputFileBase();
 
       if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       {
@@ -569,15 +577,15 @@ void GroupDef::writeDocumentation(OutputList &ol)
       }
 
       SectionInfo *si=0;
-      if (!pi->title.isEmpty() && !pi->name.isEmpty() &&
-          (si=Doxygen::sectionDict[pi->name])!=0)
+      if (!pd->title().isEmpty() && !pd->name().isEmpty() &&
+          (si=Doxygen::sectionDict[pd->name()])!=0)
       {
         ol.startSection(si->label,si->title,SectionInfo::Subsection);
         ol.docify(si->title);
         ol.endSection(si->label,SectionInfo::Subsection);
       }
       ol.startTextBlock();
-      ol.parseDoc(pi->defFileName,pi->defLine,0,0,pi->doc,FALSE);
+      ol.parseDoc(pd->docFile(),pd->docLine(),0,0,pd->documentation(),FALSE);
       ol.endTextBlock();
     }
   }
@@ -760,7 +768,7 @@ void addMemberToGroups(Entry *root,MemberDef *md)
 }
 
 
-void addExampleToGroups(Entry *root,PageInfo *eg)
+void addExampleToGroups(Entry *root,PageDef *eg)
 {
   QListIterator<Grouping> gli(*root->groups);
   Grouping *g;
@@ -778,7 +786,14 @@ void addExampleToGroups(Entry *root,PageInfo *eg)
 
 QCString GroupDef::getOutputFileBase() const 
 { 
-  return convertNameToFile(fileName); 
+  if (isReference())
+  {
+    return fileName;
+  }
+  else
+  {
+    return convertNameToFile(fileName); 
+  }
 }
 
 void GroupDef::addListReferences()
diff --git a/src/groupdef.h b/src/groupdef.h
index 79d1c21..08c8124 100644
--- a/src/groupdef.h
+++ b/src/groupdef.h
@@ -36,12 +36,12 @@ class NamespaceList;
 class MemberGroupSDict;
 class MemberNameInfoSDict;
 class PageSDict;
-class PageInfo;
+class PageDef;
 
 class GroupDef : public Definition
 {
   public:
-    GroupDef(const char *fileName,int line,const char *name,const char *title);
+    GroupDef(const char *fileName,int line,const char *name,const char *title,const char *refFileName=0);
    ~GroupDef();
     DefType definitionType() { return TypeGroup; }
     QCString getOutputFileBase() const;
@@ -53,8 +53,8 @@ class GroupDef : public Definition
     void addNamespace(const NamespaceDef *def);
     void addGroup(const GroupDef *def);
     void addParentGroup(const GroupDef *def);
-    void addPage(PageInfo *def);                // pages in this group
-    void addExample(const PageInfo *def);       // examples in this group
+    void addPage(PageDef *def);                // pages in this group
+    void addExample(const PageDef *def);       // examples in this group
     bool insertMember(MemberDef *def,bool docOnly=FALSE);
     void removeMember(MemberDef *md);
     bool containsGroup(const GroupDef *def);    // true if def is already a subgroup
@@ -152,8 +152,8 @@ void addClassToGroups(Entry *root,ClassDef *cd);
 void addNamespaceToGroups(Entry *root,NamespaceDef *nd);
 void addGroupToGroups(Entry *root,GroupDef *subGroup);
 void addMemberToGroups(Entry *root,MemberDef *md);
-void addPageToGroups(Entry *root,PageInfo *pi);
-void addExampleToGroups(Entry *root,PageInfo *eg);
+void addPageToGroups(Entry *root,PageDef *pd);
+void addExampleToGroups(Entry *root,PageDef *eg);
 
 #endif
 
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 353194b..c234a8a 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -263,23 +263,18 @@ void HtmlDocVisitor::visit(DocIncOperator *op)
 void HtmlDocVisitor::visit(DocFormula *f)
 {
   if (m_hide) return;
-  if (f->text().at(0)=='\\') m_t << "<p><center>" << endl;
-  m_t << "<img align=";
-#if !defined(_WIN32)
-  m_t << "\"top\"";     // assume Unix users use Netscape 4.x which does
-  // not seem to support align == "middle" :-((
-#else
-  m_t << "\"middle\"";  // assume Windows users use IE or HtmlHelp which on
-  // displays formulas nicely with align == "middle" 
-#endif
+  bool bDisplay = f->text().at(0)=='\\';
+  if (bDisplay) m_t << "<p class=formulaDsp>" << endl;
+  m_t << "<img class=formula"
+      << (bDisplay ? "Dsp" : "Inl");
   m_t << " alt=\"";
   filterQuotedCdataAttr(f->text());
   m_t << "\"";
   /// @todo cache image dimensions on formula generation and give height/width
   /// for faster preloading and better rendering of the page
   m_t << " src=\"" << f->name() << ".png\">";
-  if (f->text().at(0)=='\\') 
-    m_t << endl << "</center><p>" << endl;
+  if (bDisplay)
+    m_t << endl << "<p>" << endl;
   else
     m_t << " ";
 }
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index f33357e..a32f592 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -88,6 +88,9 @@ static const char *defaultStyleSheet =
 "   margin-top     : 2px; \n"
 "   margin-bottom  : 2px  \n"
 "}\n"
+"p.formulaDsp { text-align: center; }\n"
+"img.formulaDsp { }\n"
+"img.formulaInl { vertical-align: middle; }\n"
 "span.keyword       { color: #008000 }\n"
 "span.keywordtype   { color: #604020 }\n"
 "span.keywordflow   { color: #e08000 }\n"
diff --git a/src/index.cpp b/src/index.cpp
index c24714b..faa4091 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -34,7 +34,7 @@
 #include "htmlhelp.h"
 #include "ftvhelp.h"
 #include "dot.h"
-#include "page.h"
+#include "pagedef.h"
 //#include "packagedef.h"
 
 int annotatedClasses;
@@ -2080,22 +2080,22 @@ void writeExampleIndex(OutputList &ol)
   ol.endTextBlock();
   ol.startItemList();
   PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
     ol.writeListItem();
-    QCString n=pi->getOutputFileBase();
-    if (!pi->title.isEmpty())
+    QCString n=pd->getOutputFileBase();
+    if (!pd->title().isEmpty())
     {
-      ol.writeObjectLink(0,n,0,pi->title);
-      if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pi->title,n);
-      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pi->getReference(),n,0,pi->title);
+      ol.writeObjectLink(0,n,0,pd->title());
+      if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pd->title(),n);
+      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pd->getReference(),n,0,pd->title());
     }
     else
     {
-      ol.writeObjectLink(0,n,0,pi->name);
-      if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pi->name,n);
-      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pi->getReference(),n,0,pi->name);
+      ol.writeObjectLink(0,n,0,pd->name());
+      if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pd->name(),n);
+      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pd->getReference(),n,0,pd->name());
     }
     ol.writeString("\n");
   }
@@ -2118,13 +2118,13 @@ void countRelatedPages(int &docPages,int &indexPages)
 {
   docPages=indexPages=0;
   PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
-    if (!pi->getGroupDef() && (!pi->isReference() || Config_getBool("ALLEXTERNALS")))
+    if (!pd->getGroupDef() && (!pd->isReference() || Config_getBool("ALLEXTERNALS")))
     {
       indexPages++;
-      if (!pi->isReference()) docPages++;
+      if (!pd->isReference()) docPages++;
     }
   }
 }
@@ -2183,33 +2183,28 @@ void writePageIndex(OutputList &ol)
   ol.endTextBlock();
   startIndexHierarchy(ol,0);
   PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
-    if (!pi->getGroupDef() && (!pi->isReference() || Config_getBool("ALLEXTERNALS")))
+    if (!pd->getGroupDef() && (!pd->isReference() || Config_getBool("ALLEXTERNALS")))
     {
-      QCString pageName,pageTitle;
+      QCString pageTitle;
 
-      if (Config_getBool("CASE_SENSE_NAMES"))
-        pageName=pi->name.copy();
+      if (pd->title().isEmpty())
+        pageTitle=pd->name();
       else
-        pageName=pi->name.lower();
+        pageTitle=pd->title();
 
-      if (pi->title.isEmpty())
-        pageTitle=pi->name;
-      else
-        pageTitle=pi->title;
-
-      ol.writeIndexItem(pi->getReference(),pi->getOutputFileBase(),pageTitle);
-      if (pi->isReference()) 
+      ol.writeIndexItem(pd->getReference(),pd->getOutputFileBase(),pageTitle);
+      if (pd->isReference()) 
       { 
         ol.startTypewriter(); 
         ol.docify(" [external]");
         ol.endTypewriter();
       }
       ol.writeString("\n");
-      if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pageTitle,pageName);
-      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pi->getReference(),pi->getOutputFileBase(),0,pageTitle);
+      if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pageTitle,pd->getOutputFileBase());
+      if (hasFtvHelp)  ftvHelp->addContentsItem(FALSE,pd->getReference(),pd->getOutputFileBase(),0,pageTitle);
     }
   }
   endIndexHierarchy(ol,0);
@@ -2344,13 +2339,13 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level)
 
     // write pages
     PageSDict::Iterator pli(*gd->pageDict);
-    PageInfo *pi = 0;
-    for (pli.toFirst();(pi=pli.current());++pli)
+    PageDef *pd = 0;
+    for (pli.toFirst();(pd=pli.current());++pli)
     {
       SectionInfo *si=0;
-      if (!pi->name.isEmpty()) si=Doxygen::sectionDict[pi->name];
+      if (!pd->name().isEmpty()) si=Doxygen::sectionDict[pd->name()];
       if(htmlHelp) htmlHelp->addContentsItem(FALSE,
-                                   convertToHtml(pi->title),
+                                   convertToHtml(pd->title()),
                                    gd->getOutputFileBase(),
                                    si ? si->label.data() : 0
                                   ); 
@@ -2358,7 +2353,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level)
                                    gd->getReference(),
                                    gd->getOutputFileBase(),
                                    si ? si->label.data() : 0,
-                                   convertToHtml(pi->title)
+                                   convertToHtml(pd->title())
                                   ); 
     }
 
@@ -2549,18 +2544,18 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level)
         }
 
         PageSDict::Iterator eli(*(gd->exampleDict));
-        PageInfo *pi=eli.toFirst();
-        while (pi)
+        PageDef *pd=eli.toFirst();
+        while (pd)
         {
           if(htmlHelp)
           {
-            htmlHelp->addContentsItem(FALSE,pi->getReference(),pi->getOutputFileBase()); 
+            htmlHelp->addContentsItem(FALSE,pd->getReference(),pd->getOutputFileBase()); 
           }
           if(ftvHelp)
           {
-            ftvHelp->addContentsItem(FALSE,pi->getReference(),pi->getOutputFileBase(),0,pi->name); 
+            ftvHelp->addContentsItem(FALSE,pd->getReference(),pd->getOutputFileBase(),0,pd->name()); 
           }
-          pi=++eli;
+          pd=++eli;
         }
 
         if (htmlHelp) htmlHelp->decContentsDepth();
@@ -2710,18 +2705,18 @@ void writeIndex(OutputList &ol)
   ol.disableAllBut(OutputGenerator::Html);
 
   QCString defFileName = 
-    Doxygen::mainPage ? Doxygen::mainPage->defFileName.data() : "<generated>";
+    Doxygen::mainPage ? Doxygen::mainPage->getDefFileName().data() : "<generated>";
   int defLine =
-    Doxygen::mainPage ? Doxygen::mainPage->defLine : 1;
+    Doxygen::mainPage ? Doxygen::mainPage->getDefLine() : 1;
 
   QCString title;
-  if (!Doxygen::mainPage || Doxygen::mainPage->title.isEmpty())
+  if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty())
   {
     title = theTranslator->trMainPage();
   }
   else 
   {
-    title = substitute(Doxygen::mainPage->title,"%","");
+    title = substitute(Doxygen::mainPage->title(),"%","");
   }
 
   QCString indexName="index";
@@ -2742,9 +2737,9 @@ void writeIndex(OutputList &ol)
 
   if (!Config_getBool("DISABLE_INDEX")) writeQuickLinks(ol,TRUE);
   ol.startTitleHead(0);
-  if (Doxygen::mainPage && !Doxygen::mainPage->title.isEmpty())
+  if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
   {
-    ol.parseDoc(defFileName,defLine,0,0,Doxygen::mainPage->title,FALSE);
+    ol.parseDoc(defFileName,defLine,0,0,Doxygen::mainPage->title(),FALSE);
   }
   else
   {
@@ -2764,21 +2759,22 @@ void writeIndex(OutputList &ol)
   {
     Doxygen::insideMainPage=TRUE;
     ol.parseDoc(defFileName,defLine,0,0,
-                Doxygen::mainPage->doc,FALSE,Doxygen::mainPage->sectionDict);
+                Doxygen::mainPage->documentation(),FALSE
+                /*,Doxygen::mainPage->sectionDict*/);
 
     if (!Config_getString("GENERATE_TAGFILE").isEmpty())
     {
        Doxygen::tagFile << "  <compound kind=\"page\">" << endl
                         << "    <filename>"
-                        << convertToXML(Doxygen::mainPage->fileName)
+                        << convertToXML(Doxygen::mainPage->getOutputFileBase())
                         << "</filename>"
                         << endl
                         << "    <title>"
-                        << convertToXML(Doxygen::mainPage->title)
+                        << convertToXML(Doxygen::mainPage->title())
                         << "</title>"
                         << endl
                         << "    <name>"
-                        << convertToXML(Doxygen::mainPage->name)
+                        << convertToXML(Doxygen::mainPage->name())
                         << "</name>"
                         << endl;
 
@@ -2820,9 +2816,9 @@ void writeIndex(OutputList &ol)
   if (Doxygen::mainPage)
   {
     ol.startIndexSection(isMainPage);
-    if (!Doxygen::mainPage->title.isEmpty())
+    if (!Doxygen::mainPage->title().isEmpty())
     {
-      ol.parseDoc(defFileName,defLine,0,0,Doxygen::mainPage->title,FALSE);
+      ol.parseDoc(defFileName,defLine,0,0,Doxygen::mainPage->title(),FALSE);
     }
     else
     {
@@ -2927,7 +2923,7 @@ void writeIndex(OutputList &ol)
   {
     Doxygen::insideMainPage=TRUE;
     ol.disable(OutputGenerator::Man);
-    startFile(ol,Doxygen::mainPage->name,0,Doxygen::mainPage->title);
+    startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
     //SectionInfo *si=0;
     //if (!Doxygen::mainPage->title.isEmpty() && !Doxygen::mainPage->name.isEmpty() &&
     //    (si=Doxygen::sectionDict[Doxygen::mainPage->name])!=0)
@@ -2938,7 +2934,8 @@ void writeIndex(OutputList &ol)
     //}
     ol.startTextBlock();
     ol.parseDoc(defFileName,defLine,0,0,
-                Doxygen::mainPage->doc,FALSE,Doxygen::mainPage->sectionDict);
+                Doxygen::mainPage->documentation(),FALSE
+                /*,Doxygen::mainPage->sectionDict*/);
     ol.endTextBlock();
     endFile(ol);
     ol.enable(OutputGenerator::Man);
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 4fddb41..4612ed4 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -28,7 +28,7 @@
 #include "language.h"
 #include "version.h"
 #include "dot.h"
-#include "page.h"
+#include "pagedef.h"
 #include "docparser.h"
 #include "latexdocvisitor.h"
 
@@ -747,15 +747,15 @@ void LatexGenerator::endIndexSection(IndexSections is)
       {
         t << "}\n";
         PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-        PageInfo *pi=pdi.toFirst();
-        if (pi)
+        PageDef *pd=pdi.toFirst();
+        if (pd)
         {
-          t << "\\input{" << pi->getOutputFileBase() << "}\n";
+          t << "\\input{" << pd->getOutputFileBase() << "}\n";
         }
-        for (++pdi;(pi=pdi.current());++pdi)
+        for (++pdi;(pd=pdi.current());++pdi)
         {
           if (compactLatex) t << "\\input" ; else t << "\\include";
-          t << "{" << pi->getOutputFileBase() << "}\n";
+          t << "{" << pd->getOutputFileBase() << "}\n";
         }
       }
       break;
@@ -763,14 +763,14 @@ void LatexGenerator::endIndexSection(IndexSections is)
       {
         t << "}\n";
         PageSDict::Iterator pdi(*Doxygen::pageSDict);
-        PageInfo *pi=pdi.toFirst();
+        PageDef *pd=pdi.toFirst();
         bool first=TRUE;
-        for (pdi.toFirst();(pi=pdi.current());++pdi)
+        for (pdi.toFirst();(pd=pdi.current());++pdi)
         {
-          if (!pi->getGroupDef() && !pi->isReference())
+          if (!pd->getGroupDef() && !pd->isReference())
           {
             if (compactLatex || first) t << "\\input" ; else t << "\\include";
-            t << "{" << pi->getOutputFileBase() << "}\n";
+            t << "{" << pd->getOutputFileBase() << "}\n";
             first=FALSE;
           }
         }
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index 60a9400..aad22eb 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -1985,6 +1985,6 @@ void MemberDef::setDeclArgumentList(ArgumentList *al)
 
 void MemberDef::findSectionsInDocumentation()
 {
-  docFindSections(documentation(),0,this,0,docFile());  
+  docFindSections(documentation(),this,0,docFile());  
 }
 
diff --git a/src/membergroup.cpp b/src/membergroup.cpp
index d6137f4..7eb708c 100644
--- a/src/membergroup.cpp
+++ b/src/membergroup.cpp
@@ -217,7 +217,7 @@ void MemberGroup::addListReferences(Definition *def)
 
 void MemberGroup::findSectionsInDocumentation()
 {
-  docFindSections(doc,0,0,this,m_docFile);
+  docFindSections(doc,0,this,m_docFile);
   memberList->findSectionsInDocumentation();
 }
 
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index b2948ac..1cb0dca 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -65,7 +65,7 @@ void NamespaceDef::distributeMemberGroupDocumentation()
 
 void NamespaceDef::findSectionsInDocumentation()
 {
-  docFindSections(documentation(),0,this,0,docFile());
+  docFindSections(documentation(),this,0,docFile());
   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
   MemberGroup *mg;
   for (;(mg=mgli.current());++mgli)
diff --git a/src/page.h b/src/page.h
index 44c1d6f..82e5256 100644
--- a/src/page.h
+++ b/src/page.h
@@ -15,6 +15,7 @@
  *
  */
 
+#if 0
 #include "sortdict.h"
 #include "config.h"
 #include "docparser.h"
@@ -127,4 +128,4 @@ class PageSDict : public SDict<PageInfo>
       return stricmp(((PageInfo *)i1)->name,((PageInfo *)i2)->name);
     }
 };
-
+#endif
diff --git a/src/pagedef.cpp b/src/pagedef.cpp
index d1e577f..f53df1f 100644
--- a/src/pagedef.cpp
+++ b/src/pagedef.cpp
@@ -1,4 +1,6 @@
 #include "pagedef.h"
+#include "groupdef.h"
+#include "docparser.h"
 
 
 PageDef::PageDef(const char *f,int l,const char *n,
@@ -12,3 +14,14 @@ PageDef::PageDef(const char *f,int l,const char *n,
 PageDef::~PageDef()
 {
 }
+
+void PageDef::findSectionsInDocumentation()
+{
+  docFindSections(documentation(),this,0,docFile());
+}
+
+GroupDef *PageDef::getGroupDef() const 
+{ 
+  return partOfGroups() ? partOfGroups()->getFirst() : 0; 
+}
+
diff --git a/src/pagedef.h b/src/pagedef.h
index 371c4f7..77b7cee 100644
--- a/src/pagedef.h
+++ b/src/pagedef.h
@@ -29,9 +29,21 @@ class PageDef : public Definition
     PageDef(const char *f,int l,const char *n,const char *d,const char *t);
    ~PageDef();
     DefType definitionType() { return TypePage; }
+    bool isLinkableInProject() const 
+    { 
+      return hasDocumentation() && !isReference();
+    }
+    bool isLinkable() const 
+    {
+      return isLinkableInProject() || isReference();
+    } 
 
     // functions to get a uniform interface with Definitions
     QCString getOutputFileBase() const { return m_fileName; }
+    void findSectionsInDocumentation();
+    QCString title() const { return m_title; }
+    GroupDef *getGroupDef() const;
+    void setFileName(const char *name) { m_fileName = name; }
 #if 0
    
     bool isReference() const { return !reference.isEmpty(); }
@@ -126,6 +138,7 @@ class PageDef : public Definition
   private:
     QCString m_fileName;
     QCString m_title;
+    GroupDef *m_inGroup;
 };
 
 class PageSDict : public SDict<PageDef>
diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp
index d889938..f5b7e1b 100644
--- a/src/perlmodgen.cpp
+++ b/src/perlmodgen.cpp
@@ -23,7 +23,7 @@
 #include "docparser.h"
 #include "message.h"
 #include "doxygen.h"
-#include "page.h"
+#include "pagedef.h"
 
 #include <qdir.h>
 #include <qstack.h>
@@ -1344,7 +1344,7 @@ public:
   void generatePerlModForNamespace(NamespaceDef *nd);
   void generatePerlModForFile(FileDef *fd);
   void generatePerlModForGroup(GroupDef *gd);
-  void generatePerlModForPage(PageInfo *pi);
+  void generatePerlModForPage(PageDef *pi);
   
   bool createOutputFile(QFile &f, const char *s);
   bool createOutputDir(QDir &perlModDir);
@@ -1908,10 +1908,10 @@ void PerlModGenerator::generatePerlModForGroup(GroupDef *gd)
   {
     m_output.openList("pages");
     PageSDict::Iterator pli(*pl);
-    PageInfo *pi;
-    for (pli.toFirst();(pi=pli.current());++pli)
+    PageDef *pd;
+    for (pli.toFirst();(pd=pli.current());++pli)
       m_output.openHash()
-	.addFieldQuotedString("title", pi->title)
+	.addFieldQuotedString("title", pd->title())
 	.closeHash();
     m_output.closeList();
   }
@@ -1947,22 +1947,22 @@ void PerlModGenerator::generatePerlModForGroup(GroupDef *gd)
   m_output.closeHash();
 }
 
-void PerlModGenerator::generatePerlModForPage(PageInfo *pi)
+void PerlModGenerator::generatePerlModForPage(PageDef *pd)
 {
   // + name
   // + title
   // + documentation
 
-  if (pi->isReference()) return;
+  if (pd->isReference()) return;
 
   m_output.openHash()
-    .addFieldQuotedString("name", pi->name);
+    .addFieldQuotedString("name", pd->name());
     
-  SectionInfo *si = Doxygen::sectionDict.find(pi->name);
+  SectionInfo *si = Doxygen::sectionDict.find(pd->name());
   if (si)
     m_output.addFieldQuotedString("title", si->title);
 
-  addPerlModDocBlock(m_output,"detailed",pi->defFileName,pi->defLine,0,0,pi->doc);
+  addPerlModDocBlock(m_output,"detailed",pd->docFile(),pd->docLine(),0,0,pd->documentation());
   m_output.closeHash();
 }
 
@@ -2007,16 +2007,22 @@ bool PerlModGenerator::generatePerlModOutput()
   GroupSDict::Iterator gli(Doxygen::groupSDict);
   GroupDef *gd;
   for (;(gd=gli.current());++gli)
+  {
     generatePerlModForGroup(gd);
+  }
   m_output.closeList();
 
   m_output.openList("pages");
   PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
-    generatePerlModForPage(pi);
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  {
+    generatePerlModForPage(pd);
+  }
   if (Doxygen::mainPage)
+  {
     generatePerlModForPage(Doxygen::mainPage);
+  }
   m_output.closeList();
 
   m_output.closeHash().add(";\n1;\n");
diff --git a/src/pre.l b/src/pre.l
index 7c85873..667f272 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -560,7 +560,11 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
 	    }
 	    else
 	    {
-	      if (g_nospaces)
+	      if (hash && substArg.isEmpty())
+	      {
+		resExpr+="@E"; // empty argument will be remove later on
+	      }
+	      else if (g_nospaces)
 	      {
 	        resExpr+=substArg;
 	      }
@@ -715,10 +719,9 @@ static void expandExpression(QCString &expr,QCString *rest,int pos)
   }
 }
 
-/*! replaces all occurrences of @@ in \a s by @
+/*! replaces all occurrences of @@@@ in \a s by @@
+ *  and removes all occurrences of @@E.
  *  All identifiers found are replaced by 0L
- *  \par assumption: 
- *   \a s only contains pairs of @@'s.
  */
 QCString removeIdsAndMarkers(const char *s)
 {
@@ -731,12 +734,16 @@ QCString removeIdsAndMarkers(const char *s)
   {
     while ((c=*p))
     {
-      if (c=='@') // replace @@ with @
+      if (c=='@') // replace @@ with @ and remove @E
       {
 	if (*(p+1)=='@')
 	{
 	  result+=c; 
 	}
+	else if (*(p+1)=='E')
+	{
+	  // skip
+	}
 	p+=2;
       }
       else if (isdigit(c)) // number
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index e92eef6..346a8cd 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -32,7 +32,7 @@
 #include "language.h"
 #include "dot.h"
 #include "version.h"
-#include "page.h"
+#include "pagedef.h"
 #include "rtfstyle.h"
 #include "rtfdocvisitor.h"
 #include "docparser.h"
@@ -585,13 +585,13 @@ void RTFGenerator::endIndexSection(IndexSections is)
       break;
     case isMainPage:
       t << "\\par " << rtf_Style_Reset << endl;
-      if (!Doxygen::mainPage || Doxygen::mainPage->title.isEmpty())
+      if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty())
       {
         t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl;
       }
       else
       {
-        t << "{\\tc \\v " << substitute(Doxygen::mainPage->title,"%","") << "}"<< endl;
+        t << "{\\tc \\v " << substitute(Doxygen::mainPage->title(),"%","") << "}"<< endl;
       }
       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
       if (Config_getBool("GENERATE_TREEVIEW")) t << "main"; else t << "index";
@@ -767,20 +767,20 @@ void RTFGenerator::endIndexSection(IndexSections is)
         //t << "}\n";
         t << "{\\tc \\v " << theTranslator->trExampleDocumentation() << "}"<< endl;
         PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-        PageInfo *pi=pdi.toFirst();
-        if (pi)
+        PageDef *pd=pdi.toFirst();
+        if (pd)
         {
           t << "\\par " << rtf_Style_Reset << endl;
           t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
-          t << pi->getOutputFileBase();
+          t << pd->getOutputFileBase();
           t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
         }
-        for (++pdi;(pi=pdi.current());++pdi)
+        for (++pdi;(pd=pdi.current());++pdi)
         {
           t << "\\par " << rtf_Style_Reset << endl;
           beginRTFSection();
           t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
-          t << pi->getOutputFileBase();
+          t << pd->getOutputFileBase();
           t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
         }
       }
@@ -789,15 +789,15 @@ void RTFGenerator::endIndexSection(IndexSections is)
       {
         t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}"<< endl;
         PageSDict::Iterator pdi(*Doxygen::pageSDict);
-        PageInfo *pi=pdi.toFirst();
+        PageDef *pd=pdi.toFirst();
         bool first=TRUE;
-        for (pdi.toFirst();(pi=pdi.current());++pdi)
+        for (pdi.toFirst();(pd=pdi.current());++pdi)
         {
-          if (!pi->getGroupDef() && !pi->isReference())
+          if (!pd->getGroupDef() && !pd->isReference())
           {
             if (first) t << "\\par " << rtf_Style_Reset << endl;
             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
-            t << pi->getOutputFileBase();
+            t << pd->getOutputFileBase();
             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
             first=FALSE;
           }
diff --git a/src/scanner.l b/src/scanner.l
index 62b4c0f..76a726a 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -484,7 +484,7 @@ static int yyread(char *buf,int max_size)
 
        /* start command character */
 CMD	  ("\\"|"@")
-SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"xrefitem"|"ingroup"|"latexonly"|"htmlonly"|"{"|"verbatim"|"dotfile"|"defgroup"|"addtogroup"|"weakgroup")|("<"{PRE}">")
+SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"xrefitem"|"ingroup"|"latexonly"|"htmlonly"|"{"|"verbatim"|"dotfile"|"defgroup"|"addtogroup"|"weakgroup"|"class"|"namespace"|"union"|"struct"|"fn"|"var"|"typedef"|"def"|"overload")|("<"{PRE}">")
 BN        [ \t\n\r]
 BL        [ \t\r]*"\n" 
 B         [ \t]
@@ -1895,11 +1895,11 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
                                           lastStringContext=YY_START;
                                           BEGIN( CopyString );
 					}
-<ReadBody,ReadNSBody>"/*"{B}*			{ current->program += yytext ;
+<ReadBody,ReadNSBody>"/*"{B}*		{ current->program += yytext ;
 					  lastContext = ReadBody ;
 					  BEGIN( Comment ) ;
 					}
-<ReadBody,ReadNSBody>"/*"{BL}				{ current->program += yytext ;
+<ReadBody,ReadNSBody>"/*"{BL}		{ current->program += yytext ;
 					  ++yyLineNr ;
 					  lastContext = ReadBody ;
 					  BEGIN( Comment ) ;
diff --git a/src/util.cpp b/src/util.cpp
index cc4a8aa..d51c449 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -40,7 +40,7 @@
 #include "version.h"
 #include "groupdef.h"
 #include "reflist.h"
-#include "page.h"
+#include "pagedef.h"
 
 #ifndef _WIN32
 #include <unistd.h>
@@ -809,10 +809,10 @@ void linkifyText(const TextGeneratorIntf &out,const char *scName,const char *nam
     //        word.data(),scopeName.data(),searchName.data()
     //      );
     // check if `word' is a documented class name
-    if (!word.isEmpty() && 
-        !(isdigit(word.at(0)) || word.at(0)=='-') && 
-                                // do not try to link digits 
-                                // (saves a lot of time for large arrays)
+    if (//!word.isEmpty() && 
+        //!(isdigit(word.at(0)) || word.at(0)=='-') && 
+        //                        // do not try to link digits 
+        //                        // (saves a lot of time for large arrays)
         !rightScopeMatch(word,searchName) && 
         !rightScopeMatch(scopeName,word)
        )
@@ -822,10 +822,14 @@ void linkifyText(const TextGeneratorIntf &out,const char *scName,const char *nam
       bool found=FALSE;
       do // for each scope (starting with full scope and going to empty scope)
       {
-        QCString fullName = word.copy();
+        QCString fullName = word;
+        replaceNamespaceAliases(fullName,fullName.length());
         if (scopeOffset>0)
         {
-          fullName.prepend(scopeName.left(scopeOffset)+"::");
+
+          QCString prefix = scopeName.left(scopeOffset);
+          replaceNamespaceAliases(prefix,scopeOffset);
+          fullName.prepend(prefix+"::");
         }
         //printf("Trying class %s\n",fullName.data());
 
@@ -1406,6 +1410,7 @@ static void trimNamespaceScope(QCString &t1,QCString &t2,const QCString &nsName)
     if (i1!=-1 && i2==-1) // only t1 has a scope
     {
       QCString scope=t1.left(i1);
+      replaceNamespaceAliases(scope,i1);
       
       int so=nsName.length();
       do
@@ -1432,6 +1437,7 @@ static void trimNamespaceScope(QCString &t1,QCString &t2,const QCString &nsName)
     else if (i1==-1 && i2!=-1) // only t2 has a scope
     {
       QCString scope=t2.left(i2);
+      replaceNamespaceAliases(scope,i2);
 
       int so=nsName.length();
       do
@@ -2644,17 +2650,17 @@ bool resolveLink(/* in */ const char *scName,
                  /* in */ const char *lr,
                  /* in */ bool inSeeBlock,
                  /* out */ Definition **resContext,
-                 /* out */ PageInfo **resPageInfo,
+                 /* out PageInfo **resPageInfo,*/
                  /* out */ QCString &resAnchor
                 )
 {
   *resContext=0;
-  *resPageInfo=0;
+  //*resPageInfo=0;
   
   QCString linkRef=lr;
   FileDef  *fd;
   GroupDef *gd;
-  PageInfo *pi;
+  PageDef  *pd;
   ClassDef *cd;
   NamespaceDef *nd;
   bool ambig;
@@ -2662,25 +2668,25 @@ bool resolveLink(/* in */ const char *scName,
   {
     return FALSE;
   }
-  else if ((pi=Doxygen::pageSDict->find(linkRef))) // link to a page
+  else if ((pd=Doxygen::pageSDict->find(linkRef))) // link to a page
   {
-    GroupDef *gd = pi->getGroupDef();
+    GroupDef *gd = pd->getGroupDef();
     if (gd)
     {
       SectionInfo *si=0;
-      if (!pi->name.isEmpty()) si=Doxygen::sectionDict[pi->name];
+      if (!pd->name().isEmpty()) si=Doxygen::sectionDict[pd->name()];
       *resContext=gd;
       if (si) resAnchor = si->label;
     }
     else
     {
-      *resPageInfo=pi;
+      *resContext=pd;
     }
     return TRUE;
   }
-  else if ((pi=Doxygen::exampleSDict->find(linkRef))) // link to an example
+  else if ((pd=Doxygen::exampleSDict->find(linkRef))) // link to an example
   {
-    *resPageInfo=pi;
+    *resContext=pd;
     return TRUE;
   }
   else if ((gd=Doxygen::groupSDict[linkRef])) // link to a group
@@ -2726,21 +2732,22 @@ bool generateLink(OutputDocInterface &od,const char *clName,
 {
   //printf("generateLink(clName=%s,lr=%s,lr=%s)\n",clName,lr,lt);
   Definition *compound;
-  PageInfo *pageInfo;
+  //PageDef *pageDef=0;
   QCString anchor,linkText=linkToText(lt);
   //printf("generateLink linkText=%s\n",linkText.data());
-  if (resolveLink(clName,lr,inSeeBlock,&compound,&pageInfo,anchor))
+  if (resolveLink(clName,lr,inSeeBlock,&compound,/*&pageInfo,*/anchor))
   {
-    if (pageInfo) // link to page
-    {
-      od.writeObjectLink(pageInfo->getReference(),
-                         pageInfo->getOutputFileBase(),anchor,linkText);
-      if (!pageInfo->isReference())
-      {
-        writePageRef(od,pageInfo->getOutputFileBase(),anchor);
-      }
-    }
-    else if (compound) // link to compound
+    //if (pageInfo) // link to page
+    //{
+    //  od.writeObjectLink(pageInfo->getReference(),
+    //                     pageInfo->getOutputFileBase(),anchor,linkText);
+    //  if (!pageInfo->isReference())
+    //  {
+    //    writePageRef(od,pageInfo->getOutputFileBase(),anchor);
+    //  }
+    //}
+    //else 
+    if (compound) // link to compound
     {
       if (lt==0 && anchor.isEmpty() &&                      /* compound link */
           compound->definitionType()==Definition::TypeGroup /* is group */ 
@@ -3594,7 +3601,7 @@ found:
 
 //----------------------------------------------------------------------------
 
-PageInfo *addRelatedPage(const char *name,const QCString &ptitle,
+PageDef *addRelatedPage(const char *name,const QCString &ptitle,
                            const QCString &doc,
                            QList<QCString> * /*anchors*/,
                            const char *fileName,int startLine,
@@ -3603,12 +3610,12 @@ PageInfo *addRelatedPage(const char *name,const QCString &ptitle,
                            TagInfo *tagInfo
                           )
 {
-  PageInfo *pi=0;
+  PageDef *pd=0;
   //printf("addRelatedPage(name=%s gd=%p)\n",name,gd);
-  if ((pi=Doxygen::pageSDict->find(name)) && !tagInfo)
+  if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo)
   {
     // append documentation block to the page.
-    pi->doc+="\n\n"+doc;
+    pd->setDocumentation(pd->documentation()+"\n\n"+doc,fileName,startLine);
     //printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pi,name);
   }
   else // new page
@@ -3620,43 +3627,30 @@ PageInfo *addRelatedPage(const char *name,const QCString &ptitle,
       baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
     
     QCString title=ptitle.stripWhiteSpace();
-    pi=new PageInfo(fileName,startLine,baseName,doc,title);
+    pd=new PageDef(fileName,startLine,baseName,doc,title);
 
-    if (sli)
-    {
-      if (pi->xrefListItems==0)
-      {
-        pi->xrefListItems=new QList<ListItemInfo>;
-        pi->xrefListItems->setAutoDelete(TRUE);
-      }
-      QListIterator<ListItemInfo> slii(*sli);
-      ListItemInfo *lii;
-      for (slii.toFirst();(lii=slii.current());++slii)
-      {
-        pi->xrefListItems->append(new ListItemInfo(*lii));
-      } 
-    }
+    pd->setRefItems(sli);
 
     if (tagInfo)
     {
-      pi->reference = tagInfo->tagName;
+      pd->setReference(tagInfo->tagName);
     }
 
     QCString pageName;
     if (Config_getBool("CASE_SENSE_NAMES"))
-      pageName=pi->name.copy();
+      pageName=pd->name();
     else
-      pageName=pi->name.lower();
+      pageName=pd->name().lower();
     //setFileNameForSections(anchors,pageName,pi);
-    pi->fileName = pageName;
+    pd->setFileName(pageName);
     //pi->addSections(anchors);
 
     //printf("Appending page `%s'\n",baseName.data());
-    Doxygen::pageSDict->append(baseName,pi);
+    Doxygen::pageSDict->append(baseName,pd);
 
-    if (gd) gd->addPage(pi);
+    if (gd) gd->addPage(pd);
     
-    if (!pi->title.isEmpty())
+    if (!pd->title().isEmpty())
     {
       //outputList->writeTitle(pi->name,pi->title);
 
@@ -3666,16 +3660,16 @@ PageInfo *addRelatedPage(const char *name,const QCString &ptitle,
       {
         file=gd->getOutputFileBase();
       }
-      else if (pi->getGroupDef())
+      else if (pd->getGroupDef())
       {
-        file=pi->getGroupDef()->getOutputFileBase().copy();
+        file=pd->getGroupDef()->getOutputFileBase().copy();
       }
       else
       {
         file=pageName;
       }
       SectionInfo *si=new SectionInfo(
-          file,pi->name,pi->title,SectionInfo::Page,pi->reference);
+          file,pd->name(),pd->title(),SectionInfo::Page,pd->getReference());
       //printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n",
       //      si->label.data(),si->definition?si->definition->name().data():"<none>",
       //      si->fileName.data());
@@ -3684,7 +3678,7 @@ PageInfo *addRelatedPage(const char *name,const QCString &ptitle,
       Doxygen::sectionDict.insert(pageName,si);
     }
   }
-  return pi;
+  return pd;
 }
 
 //----------------------------------------------------------------------------
@@ -4161,5 +4155,30 @@ QCString rtfFormatBmkStr(const char *name)
   return *tag;
 }
 
+QCString stripExtension(const char *fName)
+{
+  QCString result=fName;
+  if (result.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
+  {
+    result=result.left(result.length()-Doxygen::htmlFileExtension.length());
+  }
+  return result;
+}
+
 
+void replaceNamespaceAliases(QCString &scope,int i)
+{
+  //printf("replaceNamespaceAliases(%s,%d)\n",scope.data(),i);
+  while (i>0)
+  {
+    QCString *s = Doxygen::namespaceAliasDict[scope.left(i)];
+    if (s)
+    {
+      scope=*s+scope.right(scope.length()-i);
+      i=s->length();
+    }
+    i=scope.findRev("::",i-1);
+  }
+  //printf("replaceNamespaceAliases() result=%s\n",scope.data());
+}
 
diff --git a/src/util.h b/src/util.h
index f4b9118..5b7cf28 100644
--- a/src/util.h
+++ b/src/util.h
@@ -47,7 +47,7 @@ class Definition;
 struct TagInfo;
 class MemberNameInfoSDict;
 struct ListItemInfo;
-class PageInfo;
+class PageDef;
 
 //--------------------------------------------------------------------
 
@@ -96,19 +96,18 @@ bool getDefs(const QCString &scopeName,
 
 
 bool resolveRef(/* in */  const char *scName,
-                       /* in */  const char *name,
-                       /* in */  bool inSeeBlock,
-                       /* out */ Definition **resContext,
-                       /* out */ MemberDef  **resMember
-                      );
-
-bool resolveLink(/* in */ const char *scName,
-                        /* in */ const char *lr,
-                        /* in */ bool inSeeBlock,
-                        /* out */ Definition **resContext,
-                        /* out */ PageInfo **resPageInfo,
-                        /* out */ QCString &resAnchor
-                       );
+                /* in */  const char *name,
+                /* in */  bool inSeeBlock,
+                /* out */ Definition **resContext,
+                /* out */ MemberDef  **resMember
+               );
+
+bool resolveLink(/* in */  const char *scName,
+                 /* in */  const char *lr,
+                 /* in */  bool inSeeBlock,
+                 /* out */ Definition **resContext,
+                 /* out */ QCString &resAnchor
+                );
 
 bool generateRef(OutputDocInterface &od,const char *,
                         const char *,bool inSeeBlock,const char * =0);
@@ -184,7 +183,7 @@ int getScopeFragment(const QCString &s,int p,int *l);
 int filterCRLF(char *buf,int len);
 void addRefItem(const QList<ListItemInfo> *sli,const char *prefix,
                         const char *name,const char *title,const char *args=0);
-PageInfo *addRelatedPage(const char *name,const QCString &ptitle,
+PageDef *addRelatedPage(const char *name,const QCString &ptitle,
                            const QCString &doc,QList<QCString> *anchors,
                            const char *fileName,int startLine,
                            const QList<ListItemInfo> *sli,
@@ -198,6 +197,8 @@ void filterLatexString(QTextStream &t,const char *str,
                        bool insideItem=FALSE);
 QCString rtfFormatBmkStr(const char *name);
 QCString linkToText(const char *link);
+QCString stripExtension(const char *fName);
+void replaceNamespaceAliases(QCString &scope,int i);
 
 #endif
 
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 8e3cef6..4c6afe8 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -29,7 +29,7 @@
 #include "outputgen.h"
 #include "dot.h"
 #include "code.h"
-#include "page.h"
+#include "pagedef.h"
 #include "filename.h"
 #include "version.h"
 #include "xmldocvisitor.h"
@@ -840,8 +840,8 @@ static void generateXMLForClass(ClassDef *cd,QTextStream &ti)
      << "\" kind=\"" << cd->compoundTypeString()
      << "\"><name>" << convertToXML(cd->name()) << "</name>" << endl;
   
-  QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
-  QCString fileName=outputDirectory+"/xml/"+cd->getOutputFileBase()+".xml";
+  QCString outputDirectory = Config_getString("XML_OUTPUT");
+  QCString fileName=outputDirectory+"/"+cd->getOutputFileBase()+".xml";
   QFile f(fileName);
   if (!f.open(IO_WriteOnly))
   {
@@ -1031,8 +1031,8 @@ static void generateXMLForNamespace(NamespaceDef *nd,QTextStream &ti)
      << "\" kind=\"namespace\"" << "><name>" 
      << convertToXML(nd->name()) << "</name>" << endl;
   
-  QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
-  QCString fileName=outputDirectory+"/xml/"+nd->getOutputFileBase()+".xml";
+  QCString outputDirectory = Config_getString("XML_OUTPUT");
+  QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
   QFile f(fileName);
   if (!f.open(IO_WriteOnly))
   {
@@ -1122,8 +1122,8 @@ static void generateXMLForFile(FileDef *fd,QTextStream &ti)
      << "\" kind=\"file\"><name>" << convertToXML(fd->name()) 
      << "</name>" << endl;
   
-  QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
-  QCString fileName=outputDirectory+"/xml/"+fd->getOutputFileBase()+".xml";
+  QCString outputDirectory = Config_getString("XML_OUTPUT");
+  QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
   QFile f(fileName);
   if (!f.open(IO_WriteOnly))
   {
@@ -1255,8 +1255,8 @@ static void generateXMLForGroup(GroupDef *gd,QTextStream &ti)
   ti << "  <compound refid=\"" << gd->getOutputFileBase() 
      << "\" kind=\"group\"><name>" << convertToXML(gd->name()) << "</name>" << endl;
   
-  QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
-  QCString fileName=outputDirectory+"/xml/"+gd->getOutputFileBase()+".xml";
+  QCString outputDirectory = Config_getString("XML_OUTPUT");
+  QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
   QFile f(fileName);
   if (!f.open(IO_WriteOnly))
   {
@@ -1309,11 +1309,11 @@ static void generateXMLForGroup(GroupDef *gd,QTextStream &ti)
   if (pl)
   {
     PageSDict::Iterator pli(*pl);
-    PageInfo *pi;
-    for (pli.toFirst();(pi=pli.current());++pli)
+    PageDef *pd;
+    for (pli.toFirst();(pd=pli.current());++pli)
     {
-      t << "    <innerpage refid=\"" << pi->getOutputFileBase()
-        << "\">" << convertToXML(pi->title) << "</innerpage>" << endl;
+      t << "    <innerpage refid=\"" << pd->getOutputFileBase()
+        << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
     }
   }
 
@@ -1356,22 +1356,23 @@ static void generateXMLForGroup(GroupDef *gd,QTextStream &ti)
   ti << "  </compound>" << endl;
 }
 
-static void generateXMLForPage(PageInfo *pi,QTextStream &ti)
+static void generateXMLForPage(PageDef *pd,QTextStream &ti)
 {
   // + name
   // + title
   // + documentation
 
-  if (pi->isReference()) return;
+  if (pd->isReference()) return;
   
-  QCString pageName = pi->getOutputFileBase();
+  QCString pageName = pd->getOutputFileBase();
   if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page.
   
   ti << "  <compound refid=\"" << pageName
-     << "\" kind=\"page\"><name>" << convertToXML(pi->name) << "</name>" << endl;
+     << "\" kind=\"page\"><name>" << convertToXML(pd->name()) 
+     << "</name>" << endl;
   
-  QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
-  QCString fileName=outputDirectory+"/xml/"+pageName+".xml";
+  QCString outputDirectory = Config_getString("XML_OUTPUT");
+  QCString fileName=outputDirectory+"/"+pageName+".xml";
   QFile f(fileName);
   if (!f.open(IO_WriteOnly))
   {
@@ -1384,14 +1385,15 @@ static void generateXMLForPage(PageInfo *pi,QTextStream &ti)
   writeXMLHeader(t);
   t << "  <compounddef id=\"" << pageName;
   t << "\" kind=\"page\">" << endl;
-  t << "    <compoundname>" << convertToXML(pi->name) << "</compoundname>" << endl;
-  SectionInfo *si = Doxygen::sectionDict.find(pi->name);
+  t << "    <compoundname>" << convertToXML(pd->name()) 
+    << "</compoundname>" << endl;
+  SectionInfo *si = Doxygen::sectionDict.find(pd->name());
   if (si)
   {
-    t << "    <title>" << si->title << "</title>" << endl;
+    t << "    <title>" << convertToXML(si->title) << "</title>" << endl;
   }
   t << "    <detaileddescription>" << endl;
-  writeXMLDocBlock(t,pi->defFileName,pi->defLine,0,0,pi->doc);
+  writeXMLDocBlock(t,pd->docFile(),pd->docLine(),0,0,pd->documentation());
   t << "    </detaileddescription>" << endl;
   t << "  </compounddef>" << endl;
   t << "</doxygen>" << endl;
@@ -1410,7 +1412,7 @@ void generateXML()
   // + related pages
   // - examples
   
-  QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
+  QCString outputDirectory = Config_getString("XML_OUTPUT");
   if (outputDirectory.isEmpty())
   {
     outputDirectory=QDir::currentDirPath();
@@ -1423,7 +1425,7 @@ void generateXML()
       dir.setPath(QDir::currentDirPath());
       if (!dir.mkdir(outputDirectory))
       {
-        err("Error: tag OUTPUT_DIRECTORY: Output directory `%s' does not "
+        err("Error: tag XML_OUTPUT: Output directory `%s' does not "
             "exist and cannot be created\n",outputDirectory.data());
         exit(1);
       }
@@ -1447,14 +1449,8 @@ void generateXML()
       return;
     }
   }
-  QDir xmlDir(outputDirectory+"/xml");
-  if (!xmlDir.exists() && !xmlDir.mkdir(outputDirectory+"/xml"))
-  {
-    err("Could not create xml directory in %s\n",outputDirectory.data());
-    return;
-  }
-  
-  QCString fileName=outputDirectory+"/xml/index.xml";
+  QDir xmlDir(outputDirectory);
+  QCString fileName=outputDirectory+"/index.xml";
   QFile f(fileName);
   if (!f.open(IO_WriteOnly))
   {
@@ -1494,10 +1490,10 @@ void generateXML()
     generateXMLForGroup(gd,t);
   }
   PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageInfo *pi=0;
-  for (pdi.toFirst();(pi=pdi.current());++pdi)
+  PageDef *pd=0;
+  for (pdi.toFirst();(pd=pdi.current());++pdi)
   {
-    generateXMLForPage(pi,t);
+    generateXMLForPage(pd,t);
   }
   if (Doxygen::mainPage)
   {
-- 
cgit v0.12

