diff --git a/html/inc/LinkDef.h b/html/inc/LinkDef.h
index 86d57fcbc79414f18cdcc4198084d11c8549c914..12c4ef79dd54bde8959fbe3fcecd76f98bd3827a 100644
--- a/html/inc/LinkDef.h
+++ b/html/inc/LinkDef.h
@@ -13,6 +13,7 @@
 #pragma link off all globals;
 #pragma link off all classes;
 #pragma link off all functions;
+#pragma link C++ nestedclasses;
 
 #pragma link C++ global gHtml;
 
@@ -27,4 +28,11 @@
 #pragma link C++ class TClassDocInfo;
 #pragma link C++ class TModuleDocInfo;
 #pragma link C++ class TLibraryDocInfo;
+#pragma link C++ class THtml::THelperBase;
+#pragma link C++ class THtml::TModuleDefinition;
+#pragma link C++ class THtml::TFileDefinition;
+#pragma link C++ class THtml::TPathDefinition;
+#pragma link C++ class THtml::TFileSysEntry;
+#pragma link C++ class THtml::TFileSysDir;
+#pragma link C++ class THtml::TFileSysDB;
 #endif
diff --git a/html/inc/TDocDirective.h b/html/inc/TDocDirective.h
index 42830a7d5a25bbbdf96590f70b8219b6189029ce..212752dbccbfdd0c3dab546e32db6b8771118b05 100644
--- a/html/inc/TDocDirective.h
+++ b/html/inc/TDocDirective.h
@@ -58,6 +58,7 @@ protected:
    void SetParameters(const char* params);
    void SetTag(const char* tag) { SetTitle(tag); }
    void SetCounter(Int_t count) { fCounter = count; }
+   virtual void DeleteOutputFiles(const char* ext) const;
 
 public:
    // get the tag ending this directive
@@ -69,6 +70,9 @@ public:
    // retrieve the result (replacement) of the directive; return false if invalid
    virtual Bool_t GetResult(TString& result) = 0;
 
+   // Delete output for the parser's current class or module.
+   virtual void DeleteOutput() const {}
+
    friend class TDocParser;
 
    ClassDef(TDocDirective, 0); // THtml directive handler
@@ -107,6 +111,8 @@ public:
    virtual void AddLine(const TSubString& line);
    virtual const char* GetEndTag() const { return "end_macro"; }
    virtual Bool_t GetResult(TString& result);
+   // Delete output for the parser's current class or module.
+   virtual void DeleteOutput() const { DeleteOutputFiles(".gif"); }
 
    ClassDef(TDocMacroDirective, 0); // Handler for "Begin_Macro"/"End_Macro" for code that is executed and that can generate an image for documentation
 };
@@ -140,6 +146,8 @@ public:
    TList* GetListOfLines() const;
 
    virtual Bool_t GetResult(TString& result);
+   // Delete output for the parser's current class or module.
+   virtual void DeleteOutput() const { DeleteOutputFiles(".gif"); }
 
    ClassDef(TDocLatexDirective, 0); // Handler for "Begin_Latex"/"End_Latex" to generate an image from latex
 };
diff --git a/html/inc/TDocInfo.h b/html/inc/TDocInfo.h
index d596885f6c5a13d04652d3248cd786a2842c4eca..ca6e2c437d6e469375084884bd720443006a3177 100644
--- a/html/inc/TDocInfo.h
+++ b/html/inc/TDocInfo.h
@@ -12,18 +12,15 @@
 #ifndef ROOT_TDocInfo
 #define ROOT_TDocInfo
 
-#ifndef ROOT_TList
-#include "TList.h"
-#endif
-#ifndef ROOT_TNamed
-#include "TNamed.h"
-#endif
-#ifndef ROOT_TString
-#include "TString.h"
+#ifndef ROOT_THashList
+#include "THashList.h"
 #endif
 #ifndef ROOT_TClassRef
 #include "TClassRef.h"
 #endif
+#ifndef ROOT_TNamed
+#include "TNamed.h"
+#endif
 #include <string>
 #include <set>
 
@@ -37,23 +34,38 @@ class TModuleDocInfo;
 class TClassDocInfo: public TObject {
 public:
    // initialize the object
-   TClassDocInfo(TClass* cl, const char* filename): 
-      fClass(cl), fModule(0), fHtmlFileName(filename),
-      fSelected(kTRUE), fHaveSource(kFALSE) { }
+   TClassDocInfo(TClass* cl,
+      const char* htmlfilename = "",
+      const char* fsdecl = "", const char* fsimpl = "",
+      const char* decl = 0, const char* impl = 0): 
+      fClass(cl), fModule(0), fHtmlFileName(htmlfilename),
+      fDeclFileName(decl ? decl : cl->GetDeclFileName()),
+      fImplFileName(impl ? impl : cl->GetImplFileName()),
+      fDeclFileSysName(fsdecl), fImplFileSysName(fsimpl),
+      fSelected(kTRUE) { }
+
    virtual ~TClassDocInfo() {}
 
            TClass*         GetClass() const { return fClass; }
    virtual const char*     GetName() const;
            const char*     GetHtmlFileName() const { return fHtmlFileName; }
+           const char*     GetDeclFileName() const { return fDeclFileName; }
+           const char*     GetImplFileName() const { return fImplFileName; }
+           const char*     GetDeclFileSysName() const { return fDeclFileSysName; }
+           const char*     GetImplFileSysName() const { return fImplFileSysName; }
 
            void            SetModule(TModuleDocInfo* module) { fModule = module; }
            TModuleDocInfo* GetModule() const { return fModule; }
 
            void            SetSelected(Bool_t sel = kTRUE) { fSelected = sel; }
            Bool_t          IsSelected() const { return fSelected; }
-           Bool_t          HaveSource() const { return fHaveSource; }
+           Bool_t          HaveSource() const { return fImplFileSysName.Length(); }
    
-           void            SetHaveSource(Bool_t have = kTRUE) { fHaveSource = have; }
+           void            SetHtmlFileName(const char* name) { fHtmlFileName = name; }
+           void            SetDeclFileName(const char* name) { fDeclFileName = name; }
+           void            SetImplFileName(const char* name) { fImplFileName = name; }
+           void            SetDeclFileSysName(const char* fsname) { fDeclFileSysName = fsname; }
+           void            SetImplFileSysName(const char* fsname) { fImplFileSysName = fsname; }
 
            ULong_t         Hash() const;
 
@@ -66,8 +78,11 @@ private:
    TClassRef               fClass; // class represented by this info object
    TModuleDocInfo*         fModule; // module this class is in
    TString                 fHtmlFileName; // name of the HTML doc file
+   TString                 fDeclFileName; // header
+   TString                 fImplFileName; // source
+   TString                 fDeclFileSysName; // file system's location of the header
+   TString                 fImplFileSysName; // file system's location of the source
    Bool_t                  fSelected; // selected for doc output
-   Bool_t                  fHaveSource; // whether we can find the source locally
 
    ClassDef(TClassDocInfo,0); // info cache for class documentation
 };
@@ -78,8 +93,10 @@ private:
 //
 class TModuleDocInfo: public TNamed {
 public:
-   TModuleDocInfo(const char* name, const char* doc = ""): 
-      TNamed(name, doc), fSelected(kTRUE) {}
+   TModuleDocInfo(const char* name, TModuleDocInfo* super, const char* doc = ""): 
+      TNamed(name, doc), fSuper(super), fSub(0), fSelected(kTRUE) {
+         if (super) super->GetSub().Add(this);
+      }
    virtual ~TModuleDocInfo() {}
 
    void        SetDoc(const char* doc) { SetTitle(doc); }
@@ -91,12 +108,13 @@ public:
    void        AddClass(TClassDocInfo* cl) { fClasses.Add(cl); }
    TList*      GetClasses() { return &fClasses; }
 
-   const TString& GetSourceDir() const { return fSourceDir; }
-   void        SetSourceDir(const char* dir);
+   TModuleDocInfo* GetSuper() const { return fSuper; }
+   THashList&  GetSub() { return fSub; }
 
 private:
+   TModuleDocInfo* fSuper; // module containing this module
+   THashList   fSub; // modules contained in this module
    TList       fClasses;
-   TString     fSourceDir; // (a) directory containing the modules' sources
    Bool_t      fSelected; // selected for doc output
 
    ClassDef(TModuleDocInfo,0); // documentation for a group of classes
diff --git a/html/inc/TDocOutput.h b/html/inc/TDocOutput.h
index 019d72887004d6c37af696f732e71835300686a8..0266b15db772b312af08f6795efc7613cb097f47 100644
--- a/html/inc/TDocOutput.h
+++ b/html/inc/TDocOutput.h
@@ -35,6 +35,7 @@ class TClass;
 class TDataMember;
 class TDataType;
 class THtml;
+class TModuleDocInfo;
 class TString;
 class TSubString;
 class TVirtualPad;
@@ -62,6 +63,8 @@ protected:
                                   const char *copyright, const char* footer);
    virtual void   WriteSearch(std::ostream& out);
    void           WriteModuleLinks(std::ostream& out);
+   void           WriteModuleLinks(std::ostream& out, TModuleDocInfo* super);
+   void           WriteTopLinks(std::ostream& out, TModuleDocInfo* module, const char* classname = 0);
 
 public:
    enum EFileType { kSource, kInclude, kTree, kDoc };
diff --git a/html/inc/TDocParser.h b/html/inc/TDocParser.h
index 962cccbc5b57b8f3f77a3ef686f12b5d4492a024..2b7c487734b7cab4354eb3a8a52853218ae5399a 100644
--- a/html/inc/TDocParser.h
+++ b/html/inc/TDocParser.h
@@ -57,6 +57,8 @@ public:
       kInfoLastUpdate,
       kInfoAuthor,
       kInfoCopyright,
+      kInfoLastChanged,
+      kInfoLastGenerated,
       kNumSourceInfos
    };
    enum EAccess {
@@ -99,6 +101,7 @@ protected:
    TString        fFirstClassDoc;   // first class-doc found - per file, taken if fLastClassDoc is empty
    TString        fLastClassDoc;    // last class-doc found - becomes class doc at ClassImp or first method
    TClass*        fCurrentClass;    // current class context of sources being parsed
+   TString        fCurrentModule;   // current module context of sources being parsed
    TString        fCurrentMethodTag;// name_idx of the currently parsed method
    Int_t          fDirectiveCount;  // index of directive for current method
    TString        fCurrentFile;     // current source / header file name
@@ -164,12 +167,15 @@ public:
    void          DecrementMethodCount(const char* name);
    virtual void  DecorateKeywords(std::ostream& out, const char* text);
    virtual void  DecorateKeywords(TString& text);
+   virtual void  DeleteDirectiveOutput() const;
    const TList*  GetMethods(EAccess access) const { return &fMethods[access]; }
    TClass*       GetCurrentClass() const { return fCurrentClass; }
+   void          GetCurrentModule(TString& out_module) const;
    TDocOutput*   GetDocOutput() const { return fDocOutput; }
    const TList*  GetDataMembers(EAccess access) const { return &fDataMembers[access]; }
    const TList*  GetEnums(EAccess access) const { return &fDataMembers[access+3]; }
    const char*   GetSourceInfo(ESourceInfo type) const { return fSourceInfo[type]; }
+   void          SetCurrentModule(const char* module) { fCurrentModule = module; }
 
    UInt_t        InContext(Int_t context) const;
    static Bool_t IsName(UChar_t c);
diff --git a/html/inc/THtml.h b/html/inc/THtml.h
index 5b126322d4a66e8b32e4fda788ee8de115a8ce4b..434b757632e68fa64c9d66a49302f0aab975464d 100644
--- a/html/inc/THtml.h
+++ b/html/inc/THtml.h
@@ -26,68 +26,180 @@
 #include "THashList.h"
 #endif
 
+#ifndef ROOT_THashTable
+#include "THashTable.h"
+#endif
+
+#ifndef ROOT_TExMap
+#include "TExMap.h"
+#endif
+
 #include <map>
 
 class TClass;
 class TClassDocInfo;
 class TVirtualMutex;
 
-class THtml : public TObject {
-protected:
-   enum ETraverse {
-      kUp, kDown, kBoth        // direction to traverse class tree in ClassHtmlTree()
+class THtml: public TObject {
+public:
+   //______________________________________________________________
+   // Helper base class.
+   class THelperBase: public TObject {
+   public:
+      THelperBase(): fHtml(0) {}
+      virtual ~THelperBase();
+      void    SetOwner(THtml* html);
+      THtml*  GetOwner() const { return fHtml; }
+   private:
+      THtml*  fHtml; // object owning the helper
+      ClassDef(THelperBase, 0); // a helper object's base class
    };
 
-protected:
-   TString        fXwho;            // URL for name lookup
-   TString        fROOTURL;         // Root URL for ROOT's reference guide for libs that are not in fLibURLs
-   std::map<std::string, TString> fLibURLs; // URL for documentation of external libraries
-   TString        fClassDocTag;     // tag for class documentation
-   TString        fAuthorTag;       // tag for author
-   TString        fLastUpdateTag;   // tag for last update
-   TString        fCopyrightTag;    // tag for copyright
-   TString        fHeader;          // header file name
-   TString        fFooter;          // footerer file name
-   TString        fHomepage;        // URL of homepage
-   TString        fSearchStemURL;   // URL stem used to build search URL
-   TString        fSearchEngine;    // link to search engine
-   TString        fViewCVS;         // link to ViewCVS; %f is replaced by the filename (no %f: it's appended)
-   TString        fWikiURL;         // URL stem of class's wiki page, %c replaced by mangled class name (no %c: appended)
-   TString        fCharset;         // Charset for doc pages
-   TString        fDocStyle;        // doc style (only "Doc++" has special treatment)
-   
-   TString        fSourcePrefix;    // prefix to relative source path
-   TString        fSourceDir;       // source path
-   TString        fIncludePath;     // include path
-   TString        fOutputDir;       // output directory
-   TString        fDotDir;          // directory of GraphViz's dot binary
-   TString        fEtcDir;          // directory containing auxiliary files
-   Int_t          fFoundDot;        // whether dot is accessible (-1 dunno, 1 yes, 0 no)
-   TString        fCounter;         // counter string
-   TString        fCounterFormat;   // counter printf-like format
-   TString        fClassFilter;     // filter used for buidling known classes
-   TString        fProductName;     // name of the product to document
-   TString        fProductDocDir;   // directory containing documentation for the product
-   TString        fMacroPath;       // path for macros run via the Begin/End Macro directive
-   TString        fModuleDocPath;   // path to check for module documentation
-   THashList      fClasses;         // known classes
-   THashList      fModules;         // known modules
-   std::map<TClass*,std::string> fGuessedDeclFileNames; // names of additional decl file names
-   std::map<TClass*,std::string> fGuessedImplFileNames; // names of additional impl file names
-   THashList      fLibDeps;         // Library dependencies
-   TIter         *fThreadedClassIter; // fClasses iterator for MakeClassThreaded
-   Int_t          fThreadedClassCount; // counter of processed classes for MakeClassThreaded
+   //______________________________________________________________
+   // Helper class to translate between classes and their
+   // modules. Can be derived from and thus replaced by
+   // the user; see THtml::SetModuleDefinition().
+   class TModuleDefinition: public THelperBase {
+   public:
+      virtual bool GetModule(TClass* cl, TString& out_modulename) const;
+      ClassDef(TModuleDefinition, 0); // helper class to determine a class's module
+   };
 
-   TVirtualMutex *fMakeClassMutex; // Mutex for MakeClassThreaded
+   //______________________________________________________________
+   // Helper class to translate between classes and their
+   // filenames. Can be derived from and thus replaced by
+   // the user; see THtml::SetFileDefinition().
+   class TFileDefinition: public THelperBase {
+   public:
+      virtual bool GetDeclFileName(const TClass* cl, TString& out_filename, TString& out_fsys) const;
+      virtual bool GetImplFileName(const TClass* cl, TString& out_filename, TString& out_fsys) const;
+   protected:
+      virtual bool GetFileName(const TClass* cl, bool decl, TString& out_filename, TString& out_fsys) const;
 
-   virtual void    CreateJavascript() const;
-   virtual void    CreateStyleSheet() const;
-   void            CreateListOfTypes();
-   void            CreateListOfClasses(const char* filter);
-   void            MakeClass(void* cdi, Bool_t force=kFALSE);
-   TClassDocInfo  *GetNextClass();
+      void SplitClassIntoDirFile(const TString& clname, TString& dir, TString& filename) const;
+      void ExpandSearchPath(TString& path) const;
+      ClassDef(TFileDefinition, 0); // helper class to determine a class's source files
+   };
+
+   //______________________________________________________________
+   // Helper class to translate between file names and their
+   // version used for documentation. Can be derived from and thus
+   // replaced by the user; see THtml::SetPathDefinition().
+   class TPathDefinition: public THelperBase {
+   public:
+      virtual bool GetMacroPath(const TString& module, TString& out_dir) const;
+      virtual bool GetIncludeAs(TClass* cl, TString& out_include_as) const;
+      virtual bool GetFileNameFromInclude(const char* included, TString& out_fsname) const;
+      virtual bool GetDocDir(const TString& module, TString& doc_dir) const;
+   protected:
+      ClassDef(TPathDefinition, 0); // helper class to determine directory layouts
+   };
+
+   class TFileSysDir;
+   class TFileSysDB;
+   //______________________________________________________________
+   // Utility class representing a directory entry
+   class TFileSysEntry: public TObject {
+   public:
+      TFileSysEntry(const char* name, TFileSysDir* parent):
+         fName(name), fParent(parent), fLevel(parent ? parent->GetLevel() + 1 : 0) {}
+      const char* GetName() const { return fName; }
+      virtual ULong_t Hash() const { return fName.Hash(); }
+      void GetFullName(TString& fullname) const {
+         fullname = "";
+         if (fParent) {
+            fParent->GetFullName(fullname);
+            fullname += "/";
+         }
+         fullname += fName;
+      }
+
+      TFileSysDir* GetParent() const { return fParent; }
+      Int_t GetLevel() const { return fLevel; }
+   private:
+      TString      fName; // name of the element
+      TFileSysDir* fParent; // parent directory
+      Int_t        fLevel; // level of directory
+      ClassDef(TFileSysEntry, 0); // an entry of the local file system
+   };
+
+   //______________________________________________________________
+   // Utility class representing a directory
+   class TFileSysDir: public TFileSysEntry {
+   public:
+      TFileSysDir(const char* name, TFileSysDir* parent):
+         TFileSysEntry(name, parent)
+      { fFiles.SetOwner(); fDirs.SetOwner(); }
+      const TList* GetFiles() const { return &fFiles; }
+      const TList* GetSubDirs() const { return &fDirs; }
+
+      void Recurse(TFileSysDB* db, const char* path);
+
+   private:
+      TList fFiles;
+      TList fDirs;
+      ClassDef(TFileSysDir, 0); // an directory if the local file system
+   };
+
+   //______________________________________________________________
+   // Utility class representing a directory
+   class TFileSysDB: public TFileSysDir {
+   public:
+      TFileSysDB(const char* path, const char* ignore, Int_t maxdirlevel):
+         TFileSysDir(path, 0), fIgnorePath(ignore), fMaxLevel(maxdirlevel)
+      { Fill(); }
+
+      TExMap& GetMapIno() { return fMapIno; }
+      THashTable& GetEntries() { return fEntries; }
+      const TString& GetIgnore() const { return fIgnorePath; }
+      Int_t   GetMaxLevel() const { return fMaxLevel; }
+
+   protected:
+      void Fill() { Recurse(this, GetName()); }
+
+   private:
+      TExMap   fMapIno; // inode to TFileSysDir map, to detect softlinks
+      THashTable fEntries; // hash map of all filenames without paths
+      TString  fIgnorePath; // regexp of path to ignore while building entry tree
+      Int_t    fMaxLevel; // maximum level of directory nesting
+      ClassDef(TFileSysDB, 0); // instance of file system data
+   };
+
+
+   //______________________________________________________________
+   // Configuration holder for path related settings
+   struct TPathInfo {
+      enum EDotAccess {
+         kDotUnknown,
+         kDotFound,
+         kDotNotFound
+      };
+
+      TPathInfo():
+         fFoundDot(kDotUnknown),
+#ifdef R__WIN32
+         fInputPath("./;src/;include/"),
+#else
+         fInputPath("./:src/:include/"),
+#endif
+         fIncludePath("include"),
+         // .whatever implicitly ignored, no need to add .svn!
+         fIgnorePath("\\b(include|CVS|test|tutorials|doc|lib|python|demo|freetype-|gdk|libAfterImage|etc|config|build|bin)\\b"),
+         fDocPath("doc"),
+         fMacroPath("macros:."),
+         fOutputDir("htmldoc") {}
+
+      EDotAccess     fFoundDot;        // whether dot is accessible
+      TString        fInputPath;       // directories to look for classes; prepended to Decl/ImplFileName()
+      TString        fIncludePath;     // directory prefixes (":" delimited) to remove when quoting include files
+      TString        fIgnorePath;      // regexp pattern for directories to ignore ("\b(CVS|\.svn)\b") for ROOT
+      TString        fDocPath;         // subdir to check for module documentation ("doc" for ROOT)
+      TString        fMacroPath;       // subdir of fDocPath for macros run via the Begin/End Macro directive; ("macros" for ROOT)
+      TString        fDotDir;          // directory of GraphViz's dot binary
+      TString        fEtcDir;          // directory containing auxiliary files
+      TString        fOutputDir;       // output directory
+   };
 
-   static void    *MakeClassThreaded(void* info);
 
 public:
    THtml();
@@ -106,85 +218,94 @@ public:
    void          MakeTree(const char *className, Bool_t force=kFALSE);
 
    // Configuration setters
+   void          SetModuleDefinition(const TModuleDefinition& md);
+   void          SetFileDefinition(const TFileDefinition& fd);
+   void          SetPathDefinition(const TPathDefinition& pd);
    void          SetProductName(const char* product) { fProductName = product; }
-   void          SetOutputDir(const char *dir) { fOutputDir = dir; }
-   void          SetSourceDir(const char *dir);
-   void          SetIncludePath(const char *path) { fIncludePath = path; }
-   void          SetSourcePrefix(const char *prefix);
-   void          SetEtcDir(const char* dir) { fEtcDir = dir; }
-   void          SetModuleDocPath(const char* path) { fModuleDocPath = path; }
-   void          SetProductDocDir(const char* dir) { fProductDocDir = dir; }
-   void          SetDotDir(const char* dir) { fDotDir = dir; fFoundDot = -1; }
-   void          SetRootURL(const char* url) { fROOTURL = url; }
-   void          SetLibURL(const char* lib, const char* url) { fLibURLs[lib] = url; }
-   void          SetXwho(const char *xwho) { fXwho = xwho; }
-   void          SetMacroPath(const char* path) {fMacroPath = path;}
+   void          SetOutputDir(const char *dir) { fPathInfo.fOutputDir = dir; }
+   void          SetInputDir(const char *dir);
+   void          SetEtcDir(const char* dir) { fPathInfo.fEtcDir = dir; }
+   void          SetDocPath(const char* path) { fPathInfo.fDocPath = path; }
+   void          SetDotDir(const char* dir) { fPathInfo.fDotDir = dir; fPathInfo.fFoundDot = TPathInfo::kDotUnknown; }
+   void          SetRootURL(const char* url) { fLinkInfo.fROOTURL = url; }
+   void          SetLibURL(const char* lib, const char* url) { fLinkInfo.fLibURLs[lib] = url; }
+   void          SetXwho(const char *xwho) { fLinkInfo.fXwho = xwho; }
+   void          SetMacroPath(const char* path) {fPathInfo.fMacroPath = path;}
    void          AddMacroPath(const char* path);
    void          SetCounterFormat(const char* format) { fCounterFormat = format; }
-   void          SetClassDocTag(const char* tag) { fClassDocTag = tag; }
-   void          SetAuthorTag(const char* tag) { fAuthorTag = tag; }
-   void          SetLastUpdateTag(const char* tag) { fLastUpdateTag = tag; }
-   void          SetCopyrightTag(const char* tag) { fCopyrightTag = tag; }
-   void          SetHeader(const char* file) { fHeader = file; }
-   void          SetFooter(const char* file) { fFooter = file; }
-   void          SetHomepage(const char* url) { fHomepage = url; }
-   void          SetSearchStemURL(const char* url) { fSearchStemURL = url; }
-   void          SetSearchEngine(const char* url) { fSearchEngine = url; }
-   void          SetViewCVS(const char* url) { fViewCVS = url; }
-   void          SetWikiURL(const char* url) { fWikiURL = url; }
-   void          SetCharset(const char* charset) { fCharset = charset; }
-   void          SetDocStyle(const char* style) { fDocStyle = style; }
+   void          SetClassDocTag(const char* tag) { fDocSyntax.fClassDocTag = tag; }
+   void          SetAuthorTag(const char* tag) { fDocSyntax.fAuthorTag = tag; }
+   void          SetLastUpdateTag(const char* tag) { fDocSyntax.fLastUpdateTag = tag; }
+   void          SetCopyrightTag(const char* tag) { fDocSyntax.fCopyrightTag = tag; }
+   void          SetHeader(const char* file) { fOutputStyle.fHeader = file; }
+   void          SetFooter(const char* file) { fOutputStyle.fFooter = file; }
+   void          SetHomepage(const char* url) { fLinkInfo.fHomepage = url; }
+   void          SetSearchStemURL(const char* url) { fLinkInfo.fSearchStemURL = url; }
+   void          SetSearchEngine(const char* url) { fLinkInfo.fSearchEngine = url; }
+   void          SetViewCVS(const char* url) { fLinkInfo.fViewCVS = url; }
+   void          SetWikiURL(const char* url) { fLinkInfo.fWikiURL = url; }
+   void          SetCharset(const char* charset) { fOutputStyle.fCharset = charset; }
+   void          SetDocStyle(const char* style) { fDocSyntax.fDocStyle = style; }
 
    // Configuration getters
+   const TModuleDefinition& GetModuleDefinition() const;
+   const TFileDefinition&   GetFileDefinition() const;
+   const TPathDefinition&   GetPathDefinition() const;
    const TString&      GetProductName() const { return fProductName; }
+   const TString&      GetInputPath() const { return fPathInfo.fInputPath; }
    const TString&      GetOutputDir(Bool_t createDir = kTRUE) const;
-   const TString&      GetSourceDir() const { return fSourceDir; }
-   const TString&      GetIncludePath() const { return fIncludePath; }
-   const TString&      GetSourcePrefix() const { return fSourcePrefix; }
    virtual const char* GetEtcDir();
-   const TString&      GetModuleDocPath() const { return fModuleDocPath; }
-   const TString&      GetProductDocDir() const { return fProductDocDir; }
-   const TString&      GetDotDir() const { return fDotDir; }
+   const TString&      GetModuleDocPath() const { return fPathInfo.fDocPath; }
+   const TString&      GetDotDir() const { return fPathInfo.fDotDir; }
    const char*         GetURL(const char* lib = 0) const;
-   const TString&      GetXwho() const { return fXwho; }
-   const TString&      GetMacroPath() const { return fMacroPath; }
+   const TString&      GetXwho() const { return fLinkInfo.fXwho; }
+   const TString&      GetMacroPath() const { return fPathInfo.fMacroPath; }
    const char*         GetCounterFormat() const { return fCounterFormat; }
-   const TString&      GetClassDocTag() const { return fClassDocTag; }
-   const TString&      GetAuthorTag() const { return fAuthorTag; }
-   const TString&      GetLastUpdateTag() const { return fLastUpdateTag; }
-   const TString&      GetCopyrightTag() const { return fCopyrightTag; }
-   const TString&      GetHeader() const { return fHeader; }
-   const TString&      GetFooter() const { return fFooter; }
-   const TString&      GetHomepage() const { return fHomepage; }
-   const TString&      GetSearchStemURL() const { return fSearchStemURL; }
-   const TString&      GetSearchEngine() const { return fSearchEngine; }
-   const TString&      GetViewCVS() const { return fViewCVS; }
-   const TString&      GetWikiURL() const { return fWikiURL; }
-   const TString&      GetCharset() const { return fCharset; }
-   const TString&      GetDocStyle() const { return fDocStyle; }
+   const TString&      GetClassDocTag() const { return fDocSyntax.fClassDocTag; }
+   const TString&      GetAuthorTag() const { return fDocSyntax.fAuthorTag; }
+   const TString&      GetLastUpdateTag() const { return fDocSyntax.fLastUpdateTag; }
+   const TString&      GetCopyrightTag() const { return fDocSyntax.fCopyrightTag; }
+   const TString&      GetHeader() const { return fOutputStyle.fHeader; }
+   const TString&      GetFooter() const { return fOutputStyle.fFooter; }
+   const TString&      GetHomepage() const { return fLinkInfo.fHomepage; }
+   const TString&      GetSearchStemURL() const { return fLinkInfo.fSearchStemURL; }
+   const TString&      GetSearchEngine() const { return fLinkInfo.fSearchEngine; }
+   const TString&      GetViewCVS() const { return fLinkInfo.fViewCVS; }
+   const TString&      GetWikiURL() const { return fLinkInfo.fWikiURL; }
+   const TString&      GetCharset() const { return fOutputStyle.fCharset; }
+   const TString&      GetDocStyle() const { return fDocSyntax.fDocStyle; }
 
    // Functions that should only be used by TDocOutput etc.
    Bool_t              CopyFileFromEtcDir(const char* filename) const;
    virtual void        CreateAuxiliaryFiles() const;
    virtual TClass*     GetClass(const char *name) const;
    const char*         GetCounter() const { return fCounter; }
-   virtual const char* GetDeclFileName(TClass* cl) const;
+   void                GetModuleMacroPath(const TString& module, TString& out_path) const { GetPathDefinition().GetMacroPath(module, out_path); }
+   virtual bool        GetDeclFileName(TClass* cl, Bool_t filesys, TString& out_name) const;
    void                GetDerivedClasses(TClass* cl, std::map<TClass*, Int_t>& derived) const;
-   virtual const char* GetImplFileName(TClass* cl) const;
-   virtual const char* GetFileName(const char *filename) const;
-   virtual void        GetSourceFileName(TString& filename);
+   static const char*  GetDirDelimiter() {
+      // ";" on windows, ":" everywhere else
+#ifdef R__WIN32
+      return ";";
+#else
+      return ":";
+#endif
+   }
+   virtual bool        GetImplFileName(TClass* cl, Bool_t filesys, TString& out_name) const;
    virtual void        GetHtmlFileName(TClass *classPtr, TString& filename) const;
    virtual const char* GetHtmlFileName(const char* classname) const;
-   TCollection*        GetLibraryDependencies() { return &fLibDeps; }
-   const TList*        GetListOfModules() const { return &fModules; }
-   const TList*        GetListOfClasses() const { return &fClasses; }
+   TList*              GetLibraryDependencies() { return &fDocEntityInfo.fLibDeps; }
+   const TList*        GetListOfModules() const { return &fDocEntityInfo.fModules; }
+   const TList*        GetListOfClasses() const { return &fDocEntityInfo.fClasses; }
+   TFileSysDB*         GetLocalFiles() const { if (!fLocalFiles) SetLocalFiles(); return fLocalFiles; }
    TVirtualMutex*      GetMakeClassMutex() const { return  fMakeClassMutex; }
-   virtual void        GetModuleName(TString& module, const char* filename) const;
    virtual void        GetModuleNameForClass(TString& module, TClass* cl) const;
+   const TPathInfo&    GetPathInfo() const { return fPathInfo; }
    Bool_t              HaveDot();
+   void                HelperDeleted(THelperBase* who);
    static Bool_t       IsNamespace(const TClass*cl);
    void                SetDeclFileName(TClass* cl, const char* filename);
-   void                SetFoundDot(Bool_t found = kTRUE) { fFoundDot = found; }
+   void                SetFoundDot(Bool_t found = kTRUE);
    void                SetImplFileName(TClass* cl, const char* filename);
 
    // unused
@@ -193,6 +314,68 @@ public:
             "Removed, call TDocOutput::ReplaceSpecialChars() instead!"); }
    void                SetEscape(char /*esc*/ ='\\') {} // for backward comp
 
+protected:
+   struct TDocSyntax {
+      TString        fClassDocTag;     // tag for class documentation
+      TString        fAuthorTag;       // tag for author
+      TString        fLastUpdateTag;   // tag for last update
+      TString        fCopyrightTag;    // tag for copyright
+      TString        fDocStyle;        // doc style (only "Doc++" has special treatment)
+   };
+
+   struct TLinkInfo {
+      TString        fXwho;            // URL for name lookup
+      TString        fROOTURL;         // Root URL for ROOT's reference guide for libs that are not in fLibURLs
+      std::map<std::string, TString> fLibURLs; // URL for documentation of external libraries
+      TString        fHomepage;        // URL of homepage
+      TString        fSearchStemURL;   // URL stem used to build search URL
+      TString        fSearchEngine;    // link to search engine
+      TString        fViewCVS;         // link to ViewCVS; %f is replaced by the filename (no %f: it's appended)
+      TString        fWikiURL;         // URL stem of class's wiki page, %c replaced by mangled class name (no %c: appended)
+   };
+
+   struct TOutputStyle {
+      TString        fHeader;          // header file name
+      TString        fFooter;          // footerer file name
+      TString        fCharset;         // Charset for doc pages
+   };
+
+   struct TDocEntityInfo {
+      TString        fClassFilter;     // filter used for buidling known classes
+      THashList      fClasses;         // known classes
+      THashList      fModules;         // known modules
+      THashList      fLibDeps;         // Library dependencies
+   };
+
+protected:
+   virtual void    CreateJavascript() const;
+   virtual void    CreateStyleSheet() const;
+   void            CreateListOfTypes();
+   void            CreateListOfClasses(const char* filter);
+   virtual bool    GetDeclImplFileName(TClass* cl, bool filesys, bool decl, TString& out_name) const;
+   void            MakeClass(void* cdi, Bool_t force=kFALSE);
+   TClassDocInfo  *GetNextClass();
+   void            SetLocalFiles() const;
+
+   static void    *MakeClassThreaded(void* info);
+
+protected:   
+   TString        fCounter;         // counter string
+   TString        fCounterFormat;   // counter printf-like format
+   TString        fProductName;     // name of the product to document
+   TIter         *fThreadedClassIter; // fClasses iterator for MakeClassThreaded
+   Int_t          fThreadedClassCount; // counter of processed classes for MakeClassThreaded
+   TVirtualMutex *fMakeClassMutex; // Mutex for MakeClassThreaded
+   TDocSyntax     fDocSyntax;      // doc syntax configuration
+   TLinkInfo      fLinkInfo;       // link (URL) configuration
+   TOutputStyle   fOutputStyle;    // output style configuration
+   TPathInfo      fPathInfo;       // path configuration
+   TDocEntityInfo fDocEntityInfo;  // data for documented entities
+   mutable TPathDefinition *fPathDef; // object translating classes to module names
+   mutable TModuleDefinition *fModuleDef; // object translating classes to module names
+   mutable TFileDefinition* fFileDef; // object translating classes to file names
+   mutable TFileSysDB    *fLocalFiles; // files found locally for a given source path
+
    ClassDef(THtml,0)  //Convert class(es) into HTML file(s)
 };
 
diff --git a/html/src/TClassDocOutput.cxx b/html/src/TClassDocOutput.cxx
index 42bdd8fdedfa7020ee5122a7ad336420db0e899f..f95b7157166166722e185b611124c5c276195790 100644
--- a/html/src/TClassDocOutput.cxx
+++ b/html/src/TClassDocOutput.cxx
@@ -97,9 +97,8 @@ void TClassDocOutput::Class2Html(Bool_t force)
    WriteClassDocHeader(classFile);
 
    // copy .h file to the Html output directory
-   TString declf(fHtml->GetDeclFileName(fCurrentClass));
-   fHtml->GetSourceFileName(declf);
-   if (declf.Length())
+   TString declf;
+   if (fHtml->GetDeclFileName(fCurrentClass, kTRUE, declf))
       CopyHtmlFile(declf);
 
    // process a '.cxx' file
@@ -124,11 +123,13 @@ void TClassDocOutput::ListFunctions(std::ostream& classFile)
       << ":Function_Members\"></a>Function Members (Methods)</h2>" << endl;
 
    const char* tab4nbsp="&nbsp;&nbsp;&nbsp;&nbsp;";
+   TString declFile;
+   fHtml->GetDeclFileName(fCurrentClass, kFALSE, declFile);
    if (fCurrentClass->Property() & kIsAbstract)
       classFile << "&nbsp;<br /><b>"
                 << tab4nbsp << "This is an abstract class, constructors will not be documented.<br />" << endl
                 << tab4nbsp << "Look at the <a href=\""
-                << fHtml->GetFileName(fHtml->GetDeclFileName(fCurrentClass))
+                << gSystem->BaseName(declFile)
                 << "\">header</a> to check for available constructors.</b><br />" << endl;
 
    for (Int_t access = TDocParser::kPublic; access >= 0 && !fHtml->IsNamespace(fCurrentClass); --access) {
@@ -194,6 +195,29 @@ void TClassDocOutput::ListFunctions(std::ostream& classFile)
          classFile << "</a>";
 
          fParser->DecorateKeywords(classFile, const_cast<TMethod*>(method)->GetSignature());
+         bool propSignal = false;
+         bool propMenu   = false;
+         bool propToggle = false;
+         bool propGetter = false;
+         if (method->GetTitle()) {
+            propSignal = (strstr(method->GetTitle(), "*SIGNAL*"));
+            propMenu   = (strstr(method->GetTitle(), "*MENU*"));
+            propToggle = (strstr(method->GetTitle(), "*TOGGLE*"));
+            propGetter = (strstr(method->GetTitle(), "*GETTER"));
+            if (propSignal || propMenu || propToggle || propGetter) {
+               classFile << "<span class=\"funcprop\">";
+               if (propSignal) classFile << "<abbr title=\"emits a signal\"/>SIGNAL</abbr> ";
+               if (propMenu) classFile << "<abbr title=\"has a popup menu entry\"/>MENU</abbr> ";
+               if (propToggle) classFile << "<abbr title=\"toggles a state\"/>TOGGLE</abbr> ";
+               if (propGetter) {
+                  TString getter(method->GetTitle());
+                  Ssiz_t posGetter = getter.Index("*GETTER=");
+                  getter.Remove(0, posGetter + 8);
+                  classFile << "<abbr title=\"use " + getter + "() as getter\"/>GETTER</abbr> ";
+               }
+               classFile << "</span>";
+            }
+         }
          classFile << "</td></tr>" << endl;
       }
       classFile << endl << "</table></div>" << endl;
@@ -715,75 +739,85 @@ Bool_t TClassDocOutput::CreateDotClassChartInhMem(const char* filename) {
       //Bool_t haveMembers = (cl->GetListOfDataMembers() && cl->GetListOfDataMembers()->GetSize());
       Bool_t haveFuncs = cl->GetListOfMethods() && cl->GetListOfMethods()->GetSize();
 
-      // make sure each member name is listed only once
-      // that's useless for data members, but symmetric to what we have for methods
-      std::map<std::string, TDataMember*> dmMap;
-      TIter iDM(cl->GetListOfDataMembers());
-      TDataMember* dm = 0;
-      while ((dm = (TDataMember*) iDM()))
-         dmMap[dm->GetName()] = dm;
-
-      outdot << "subgraph \"clusterData0" << cl->GetName() << "\" {" << endl
-             << "  color=white;" << endl
-             << "  label=\"\";" << endl
-             << "  \"clusterNode0" << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
-      TString prevColumnNode;
-      Int_t pos = dmMap.size();
-      Int_t column = 0;
-      Int_t newColumnEvery = (pos + numColumns - 1) / numColumns;
-      for (std::map<std::string, TDataMember*>::iterator iDM = dmMap.begin();
-         iDM != dmMap.end(); ++iDM, --pos) {
-         TDataMember* dm = iDM->second;
-         TString nodeName(cl->GetName());
-         nodeName += "::";
-         nodeName += dm->GetName();
-         if (iDM == dmMap.begin())
-            prevColumnNode = nodeName;
-
-         outdot << "\"" << nodeName << "\" [label=\""
-            << dm->GetName() << "\"";
-         if (dm->Property() & kIsPrivate)
-            outdot << ",color=\"#FFCCCC\"";
-         else if (dm->Property() & kIsProtected)
-            outdot << ",color=\"#FFFF77\"";
-         else
-            outdot << ",color=\"#CCFFCC\"";
-         outdot << "];" << endl;
-         if (pos % newColumnEvery == 1) {
-            ++column;
-            outdot << "};" << endl // end dataR
-                   << "subgraph \"clusterData" << column << cl->GetName() << "\" {" << endl
-                   << "  color=white;" << endl
-                   << "  label=\"\";" << endl
-                   << "  \"clusterNode" << column << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
-         } else if (iDM != dmMap.begin() && pos % newColumnEvery == 0) {
-            ssDep << "\"" << prevColumnNode
-                  << "\" -> \"" << nodeName << "\""<< " [style=invis,weight=100];" << endl;
-            prevColumnNode = nodeName;
+      // DATA MEMBERS
+      {
+         // make sure each member name is listed only once
+         // that's useless for data members, but symmetric to what we have for methods
+         std::map<std::string, TDataMember*> dmMap;
+
+         {
+            TIter iDM(cl->GetListOfDataMembers());
+            TDataMember* dm = 0;
+            while ((dm = (TDataMember*) iDM()))
+               dmMap[dm->GetName()] = dm;
          }
-      }
 
-      while (column < numColumns - 1) {
-         ++column;
-         outdot << "  \"clusterNode" << column << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
-      }
+         outdot << "subgraph \"clusterData0" << cl->GetName() << "\" {" << endl
+                << "  color=white;" << endl
+                << "  label=\"\";" << endl
+                << "  \"clusterNode0" << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
+         TString prevColumnNode;
+         Int_t pos = dmMap.size();
+         Int_t column = 0;
+         Int_t newColumnEvery = (pos + numColumns - 1) / numColumns;
+         for (std::map<std::string, TDataMember*>::iterator iDM = dmMap.begin();
+              iDM != dmMap.end(); ++iDM, --pos) {
+            TDataMember* dm = iDM->second;
+            TString nodeName(cl->GetName());
+            nodeName += "::";
+            nodeName += dm->GetName();
+            if (iDM == dmMap.begin())
+               prevColumnNode = nodeName;
+
+            outdot << "\"" << nodeName << "\" [label=\""
+                   << dm->GetName() << "\"";
+            if (dm->Property() & kIsPrivate)
+               outdot << ",color=\"#FFCCCC\"";
+            else if (dm->Property() & kIsProtected)
+               outdot << ",color=\"#FFFF77\"";
+            else
+               outdot << ",color=\"#CCFFCC\"";
+            outdot << "];" << endl;
+            if (pos % newColumnEvery == 1) {
+               ++column;
+               outdot << "};" << endl // end dataR
+                      << "subgraph \"clusterData" << column << cl->GetName() << "\" {" << endl
+                      << "  color=white;" << endl
+                      << "  label=\"\";" << endl
+                      << "  \"clusterNode" << column << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
+            } else if (iDM != dmMap.begin() && pos % newColumnEvery == 0) {
+               ssDep << "\"" << prevColumnNode
+                     << "\" -> \"" << nodeName << "\""<< " [style=invis,weight=100];" << endl;
+               prevColumnNode = nodeName;
+            }
+         }
+
+         while (column < numColumns - 1) {
+            ++column;
+            outdot << "  \"clusterNode" << column << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
+         }
 
-      outdot << "};" << endl; // subgraph dataL/R
+         outdot << "};" << endl; // subgraph dataL/R
+      } // DATA MEMBERS
 
+      // FUNCTION MEMBERS
       if (haveFuncs) {
          // make sure each member name is listed only once
          std::map<std::string, TMethod*> methMap;
-         TIter iMeth(cl->GetListOfMethods());
-         TMethod* meth = 0;
-         while ((meth = (TMethod*) iMeth())) 
-            methMap[meth->GetName()] = meth;
+
+         {
+            TIter iMeth(cl->GetListOfMethods());
+            TMethod* meth = 0;
+            while ((meth = (TMethod*) iMeth())) 
+               methMap[meth->GetName()] = meth;
+         }
 
          outdot << "subgraph \"clusterFunc0" << cl->GetName() << "\" {" << endl
                 << "  color=white;" << endl
                 << "  label=\"\";" << endl
                 << "  \"clusterNode0" << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
 
-         TString prevColumnNode;
+         TString prevColumnNodeFunc;
          Int_t pos = methMap.size();
          Int_t column = 0;
          Int_t newColumnEvery = (pos + numColumns - 1) / numColumns;
@@ -794,7 +828,7 @@ Bool_t TClassDocOutput::CreateDotClassChartInhMem(const char* filename) {
             nodeName += "::";
             nodeName += meth->GetName();
             if (iMeth == methMap.begin())
-               prevColumnNode = nodeName;
+               prevColumnNodeFunc = nodeName;
 
             outdot << "\"" << nodeName << "\" [label=\"" << meth->GetName() << "\"";
             if (cl != fCurrentClass && 
@@ -814,9 +848,9 @@ Bool_t TClassDocOutput::CreateDotClassChartInhMem(const char* filename) {
                       << "  color=white;" << endl
                       << "  label=\"\";" << endl;
             } else if (iMeth != methMap.begin() && pos % newColumnEvery == 0) {
-               ssDep << "\"" << prevColumnNode
+               ssDep << "\"" << prevColumnNodeFunc
                      << "\" -> \"" << nodeName << "\""<< " [style=invis,weight=100];" << endl;
-               prevColumnNode = nodeName;
+               prevColumnNodeFunc = nodeName;
             }
          }
          outdot << "};" << endl; // subgraph funcL/R
@@ -860,19 +894,19 @@ Bool_t TClassDocOutput::CreateDotClassChartIncl(const char* filename) {
 
    std::map<std::string, std::string> filesToParse;
    std::list<std::string> listFilesToParse;
-   const char* declFileName = fHtml->GetDeclFileName(fCurrentClass);
-   const char* implFileName = fHtml->GetImplFileName(fCurrentClass);
-   if (declFileName && strlen(declFileName)) {
-      char* real = gSystem->Which(fHtml->GetSourceDir(), declFileName, kReadPermission);
-      if (real) {
-         filesToParse[declFileName] = real;
-         listFilesToParse.push_back(declFileName);
-         delete [] real;
+   TString declFileName;
+   TString implFileName;
+   fHtml->GetImplFileName(fCurrentClass, kFALSE, implFileName);
+   if (fHtml->GetDeclFileName(fCurrentClass, kFALSE, declFileName)) {
+      TString real;
+      if (fHtml->GetDeclFileName(fCurrentClass, kTRUE, real)) {
+         filesToParse[declFileName.Data()] = real.Data();
+         listFilesToParse.push_back(declFileName.Data());
       }
    }
    /* do it only for the header
    if (implFileName && strlen(implFileName)) {
-      char* real = gSystem->Which(fHtml->GetSourceDir(), implFileName, kReadPermission);
+      char* real = gSystem->Which(fHtml->GetInputPath(), implFileName, kReadPermission);
       if (real) {
          filesToParse[implFileName] = real;
          listFilesToParse.push_back(implFileName);
@@ -916,12 +950,12 @@ Bool_t TClassDocOutput::CreateDotClassChartIncl(const char* filename) {
          if (pos == std::string::npos) continue;
          line.erase(pos);
          if (filesToParse.find(line) == filesToParse.end()) {
-            char* filename = gSystem->Which(fHtml->GetSourceDir(), line.c_str(), kReadPermission);
-            if (!filename) continue;
+            TString sysfilename;
+            if (!GetHtml()->GetPathDefinition().GetFileNameFromInclude(line.c_str(), sysfilename))
+               continue;
             listFilesToParse.push_back(line);
-            filesToParse[line] = filename;
-            delete [] filename;
-            if (*iFile == implFileName || *iFile == declFileName)
+            filesToParse[line] = sysfilename;
+            if (*iFile == implFileName.Data() || *iFile == declFileName.Data())
                outdot << "\"" << *iFile << "\" [style=filled,fillcolor=lightgray];" << endl;
          }
          outdot << "\"" << *iFile << "\" -> \"" << line << "\";" << endl;
@@ -961,9 +995,13 @@ Bool_t TClassDocOutput::CreateDotClassChartLib(const char* filename) {
          firstLib.Remove(end, firstLib.Length());
          libs.Remove(0, end + 1);
       } else libs = "";
-      Ssiz_t posExt = firstLib.First(".");
-      if (posExt != kNPOS)
-         firstLib.Remove(posExt, firstLib.Length());
+
+      {
+         Ssiz_t posExt = firstLib.First(".");
+         if (posExt != kNPOS)
+            firstLib.Remove(posExt, firstLib.Length());
+      }
+
       outdot << "\"All Libraries\" -> \"" << firstLib << "\" [style=invis];" << endl;
       outdot << "\"" << firstLib << "\" -> {" << endl;
 
@@ -1373,28 +1411,7 @@ void TClassDocOutput::WriteClassDocHeader(std::ostream& classFile)
    TString sInclude;
    TString sLib;
    const char* lib=fCurrentClass->GetSharedLibs();
-   const char* incl=fHtml->GetDeclFileName(fCurrentClass);
-   if (incl) {
-      TString inclPath(GetHtml()->GetIncludePath());
-      Ssiz_t posDelim = 0;
-      TString inclDir;
-      TString sIncl(incl);
-#ifdef R__WIN32
-      const char* pdelim = ";";
-      static const char ddelim = '\\';
-#else
-      const char* pdelim = ":";
-      static const char ddelim = '/';
-#endif
-      while (inclPath.Tokenize(inclDir, posDelim, pdelim))
-         if (sIncl.BeginsWith(inclDir)) {
-            incl += inclDir.Length();
-            if (incl[0] == ddelim || incl[0] == '/')
-               ++incl;
-            break;
-         }
-      sInclude = incl;
-   }
+   GetHtml()->GetPathDefinition().GetIncludeAs(fCurrentClass, sInclude);
    if (lib) {
       char* libDup=StrDup(lib);
       char* libDupSpace=strchr(libDup,' ');
@@ -1411,40 +1428,10 @@ void TClassDocOutput::WriteClassDocHeader(std::ostream& classFile)
    classFile << "<script type=\"text/javascript\">WriteFollowPageBox('" 
              << sTitle << "','" << sLib << "','" << sInclude << "');</script>" << endl;
 
-   // top links
-   classFile << "<div id=\"toplinks\">" << endl;
-
-   // make a link to the description
-   TString currClassNameMangled(fCurrentClass->GetName());
-   NameSpace2FileName(currClassNameMangled);
-   classFile << "<div class=\"descrhead\">" << endl
-      << "<span class=\"descrtitle\">Location:</span>" << endl;
-   const char *productName = fHtml->GetProductName();
-   classFile << "<a class=\"descrheadentry\" href=\"ClassIndex.html\">" << productName << "</a> &#187; " << endl;
-
-   TString module;
-   fHtml->GetModuleNameForClass(module, fCurrentClass);
-   if (module.Length())
-      classFile << "<a class=\"descrheadentry\" href=\"./" << module << "_Index.html\">" << module << "</a> &#187; " << endl;
-
-   classFile << "<a class=\"descrheadentry\" href=\"#TopOfPage\">";
-   ReplaceSpecialChars(classFile, fCurrentClass->GetName());
-   classFile << "</a>" << endl
-      << "</div>" << endl;
-
-   classFile << "<div class=\"descrhead\">" << endl
-      << "<span class=\"descrtitle\">Quick Links:</span>" << endl;
-
-   // link to the user home page (if exist)
-   const char* userHomePage = GetHtml()->GetHomepage();
-   if (productName && !strcmp(productName, "ROOT"))
-      userHomePage = "";
-   if (userHomePage && *userHomePage)
-      classFile << "<a class=\"descrheadentry\" href=\"" << userHomePage << "\">" << productName << "</a>" << endl;
-   classFile << "<a class=\"descrheadentry\" href=\"http://root.cern.ch/root/Welcome.html\">ROOT</a>" << endl
-      << "<a class=\"descrheadentry\" href=\"./ClassIndex.html\">Class Index</a>" << endl
-      << "<a class=\"descrheadentry\" href=\"./ClassHierarchy.html\">Class Hierarchy</a>" << endl
-      << "</div>" << endl;
+   TString modulename;
+   fHtml->GetModuleNameForClass(modulename, fCurrentClass);
+   TModuleDocInfo* module = (TModuleDocInfo*) fHtml->GetListOfModules()->FindObject(modulename);
+   WriteTopLinks(classFile, module, fCurrentClass->GetName());
 
    classFile << "<div class=\"descrhead\">" << endl
       << "<span class=\"descrtitle\">Source:</span>" << endl;
@@ -1453,18 +1440,15 @@ void TClassDocOutput::WriteClassDocHeader(std::ostream& classFile)
    TString classFileName(fCurrentClass->GetName());
    NameSpace2FileName(classFileName);
 
-   const char* headerFileName = fHtml->GetDeclFileName(fCurrentClass);
-   if (headerFileName && !headerFileName[0])
-      headerFileName = 0;
-   const char* sourceFileName = fHtml->GetImplFileName(fCurrentClass);
-   if (sourceFileName && !sourceFileName[0])
-      sourceFileName = 0;
-
-   if (headerFileName)
+   TString headerFileName;
+   fHtml->GetDeclFileName(fCurrentClass, kFALSE, headerFileName);
+   TString sourceFileName;
+   fHtml->GetImplFileName(fCurrentClass, kFALSE, sourceFileName);
+   if (headerFileName.Length())
       classFile << "<a class=\"descrheadentry\" href=\"src/" << classFileName
                 << ".h.html\">header file</a>" << endl;
 
-   if (sourceFileName)
+   if (sourceFileName.Length())
       classFile << "<a class=\"descrheadentry\" href=\"src/" << classFileName
                 << ".cxx.html\">source file</a>" << endl;
 
@@ -1517,6 +1501,9 @@ void TClassDocOutput::WriteClassDocHeader(std::ostream& classFile)
       }
    }
 
+   TString currClassNameMangled(fCurrentClass->GetName());
+   NameSpace2FileName(currClassNameMangled);
+
    TString wikiLink = GetHtml()->GetWikiURL();
    if (wikiLink.Length()) {
       if (wikiLink.Contains("%c")) wikiLink.ReplaceAll("%c", currClassNameMangled);
diff --git a/html/src/TDocDirective.cxx b/html/src/TDocDirective.cxx
index f018ccf652cffbf90d261b9ccf5ee6f9c339d3f3..874c4c063b98c3517eb716d5e896574cbe45bf15 100644
--- a/html/src/TDocDirective.cxx
+++ b/html/src/TDocDirective.cxx
@@ -43,6 +43,25 @@
 
 ClassImp(TDocDirective);
 
+//______________________________________________________________________________
+void TDocDirective::DeleteOutputFiles(const char* ext) const
+{
+   // Delete all output generated by the directive beginning 
+   // with Name() and ending with ext
+   TString basename;
+   GetName(basename);
+   basename += "_";
+   TString dirname(GetOutputDir());
+   void* hDir = gSystem->OpenDirectory(dirname);
+   const char* entry = 0;
+   while ((entry = gSystem->GetDirEntry(hDir))) {
+      TString sEntry(entry);
+      if (sEntry.BeginsWith(basename) && isdigit(sEntry[basename.Length()]) && (!ext || sEntry.EndsWith(ext)))
+         gSystem->Unlink((dirname + "/" + entry).Data());
+   }
+   gSystem->FreeDirectory(hDir);
+}
+
 //______________________________________________________________________________
 void TDocDirective::GetName(TString& name) const
 {
@@ -51,7 +70,12 @@ void TDocDirective::GetName(TString& name) const
    name = fName;
    if (fDocParser && fDocParser->GetCurrentClass()) {
       name += "_";
-      name += fDocParser->GetCurrentClass()->GetName();
+      TString outfilename;
+      GetHtml()->GetHtmlFileName(fDocParser->GetCurrentClass(), outfilename);
+      outfilename = gSystem->BaseName(outfilename);
+      Ssiz_t posExt = outfilename.Last('.');
+      outfilename.Remove(posExt, outfilename.Length() - posExt);
+      name += outfilename;
    }
    if (GetTitle() && strlen(GetTitle())) {
       name += "_";
@@ -245,7 +269,6 @@ void TDocMacroDirective::AddLine(const TSubString& line)
    fMacro->AddLine(sLine);
    fIsFilename &= !sLine.Contains('{');
 }
-
 //______________________________________________________________________________
 Bool_t TDocMacroDirective::GetResult(TString& result)
 {
@@ -286,17 +309,17 @@ Bool_t TDocMacroDirective::GetResult(TString& result)
       while (filename.Length() == 0)
          filename = ((TObjString*)iLine())->String().Strip(TString::kBoth);
 
-      TString pwd;
-      if (GetHtml() && GetDocParser() && GetDocParser()->GetCurrentClass()) {
-         TString modulename;
-         GetHtml()->GetModuleNameForClass(modulename, GetDocParser()->GetCurrentClass());
-         TModuleDocInfo* module = 0;
-         if (modulename.Length() 
-            && (module = (TModuleDocInfo*)GetHtml()->GetListOfModules()->FindObject(modulename)))
-            pwd = module->GetSourceDir();
-         else pwd = gSystem->pwd();
-      } else pwd = gSystem->pwd();
-      TString macroPath(GetHtml()->GetMacroPath());
+      TString macroPath;
+      TString modulename;
+      if (GetHtml() && GetDocParser()) {
+         if (GetDocParser()->GetCurrentClass())
+            GetHtml()->GetModuleNameForClass(modulename, GetDocParser()->GetCurrentClass());
+         else GetDocParser()->GetCurrentModule(modulename);
+      }
+      if (modulename.Length()) {
+         GetHtml()->GetModuleMacroPath(modulename, macroPath);
+      } else macroPath = gSystem->pwd();
+
       const char* pathDelimiter = ":"; // use ":" even on windows
       TObjArray* arrDirs(macroPath.Tokenize(pathDelimiter));
       TIter iDir(arrDirs);
@@ -305,8 +328,8 @@ Bool_t TDocMacroDirective::GetResult(TString& result)
       TString filenameDirPart(gSystem->DirName(filename));
       filenameDirPart.Prepend('/'); // as dir delimiter, not as root dir
       while ((osDir = (TObjString*)iDir())) {
-         if (!gSystem->IsAbsoluteFileName(osDir->String()))
-            gSystem->PrependPathName(pwd, osDir->String());
+         if (osDir->String().EndsWith("\\"))
+            osDir->String().Remove(osDir->String().Length() - 1);
          osDir->String() += filenameDirPart;
          macroPath += osDir->String() + pathDelimiter;
       }
@@ -618,7 +641,7 @@ void TDocLatexDirective::CreateLatex(const char* filename)
    latex.SetTextAlign(12);
 
    // calculate positions
-   TIter iLine(fLatex->GetListOfLines());
+   TIter iterLine(fLatex->GetListOfLines());
    TObjString* line = 0;
    TPRegexp regexp;
    if (fSeparator.Length()) {
@@ -626,7 +649,7 @@ void TDocLatexDirective::CreateLatex(const char* filename)
          regexp = TPRegexp(fSeparator);
    } else fSepIsRegexp = kFALSE;
 
-   while ((line = (TObjString*) iLine())) {
+   while ((line = (TObjString*) iterLine())) {
       const TString& str = line->String();
       TObjArray* split = 0;
       if (!fSepIsRegexp) {
diff --git a/html/src/TDocInfo.cxx b/html/src/TDocInfo.cxx
index 660550de99029d8f547bd4f342c6441712bec06d..91ad5cfe7d3dfd533a91d145fc587ead9feff261 100644
--- a/html/src/TDocInfo.cxx
+++ b/html/src/TDocInfo.cxx
@@ -52,7 +52,7 @@ Int_t TClassDocInfo::Compare(const TObject* obj) const
 // which is documented <a href="./HTML_index.html">here</a>. The list of
 // all modules is shown e.g. in the <a href="ClassIndex.html">class index</a>.</p>
 // <p>A module's documentation is searched by combining its source directory
-// (see <a href="#TModuleDocInfo:SetSourceDir">SetSourceDir()</a>) and the
+// (see <a href="#TModuleDocInfo:SetInputDir">SetInputDir()</a>) and the
 // module documentation search path defined by 
 // <a href="./THtml.html#THtml:SetModuleDocPath">THtml::SetModuleDocPath()</a>;
 // it defaults to "../doc", i.e. for a module's sources in "module/src" its
@@ -62,11 +62,3 @@ Int_t TClassDocInfo::Compare(const TObject* obj) const
 
 
 ClassImp(TModuleDocInfo);
-
-void TModuleDocInfo::SetSourceDir(const char* dir)
-{
-   // Set the module's source directory. It serves as part of
-   // the search path for the module documentation.
-   fSourceDir = dir;
-   gSystem->ExpandPathName(fSourceDir);
-}
diff --git a/html/src/TDocOutput.cxx b/html/src/TDocOutput.cxx
index f213851a061d90a019c953a05e87e9d5273f116f..182c903843ec8103a4bfbe3c77e542a79b4700a6 100644
--- a/html/src/TDocOutput.cxx
+++ b/html/src/TDocOutput.cxx
@@ -173,8 +173,7 @@ namespace {
 
 }
 
-
-namespace {
+extern "C" { // std::qsort on solaris wants the sorter to be extern "C"
 
    //______________________________________________________________________________
    static int CaseInsensitiveSort(const void *name1, const void *name2)
@@ -194,6 +193,9 @@ namespace {
 
       return (strcasecmp(*((char **) name1), *((char **) name2)));
    }
+}
+
+namespace {
 
    // std::list::sort(with_stricmp_predicate) doesn't work with Solaris CC...
    static void sort_strlist_stricmp(std::list<std::string>& l)
@@ -333,7 +335,7 @@ Bool_t TDocOutput::CopyHtmlFile(const char *sourceName, const char *destName)
 // Copy file to HTML directory
 //
 //
-//  Input: sourceName - source file name
+//  Input: sourceName - source file name (fully qualified i.e. file system path)
 //         destName   - optional destination name, if not
 //                      specified it would be the same
 //                      as the source file name
@@ -347,16 +349,7 @@ Bool_t TDocOutput::CopyHtmlFile(const char *sourceName, const char *destName)
 
    R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
 
-   // source file name
-   char *tmp1 = gSystem->Which(fHtml->GetSourceDir(), sourceName, kReadPermission);
-   if (!tmp1) {
-      Error("Copy", "Can't copy file '%s' to '%s/%s' - can't find source file!", sourceName,
-            fHtml->GetOutputDir().Data(), destName);
-      return kFALSE;
-   }
-
-   TString sourceFile(tmp1);
-   delete[]tmp1;
+   TString sourceFile(sourceName);
 
    if (!sourceFile.Length()) {
       Error("Copy", "Can't copy file '%s' to '%s' directory - source file name invalid!", sourceName,
@@ -367,9 +360,9 @@ Bool_t TDocOutput::CopyHtmlFile(const char *sourceName, const char *destName)
    // destination file name
    TString destFile;
    if (!destName || !*destName)
-      destFile = fHtml->GetFileName(sourceFile);
+      destFile = gSystem->BaseName(sourceFile);
    else
-      destFile = fHtml->GetFileName(destName);
+      destFile = gSystem->BaseName(destName);
 
    gSystem->PrependPathName(fHtml->GetOutputDir(), destFile);
 
@@ -414,9 +407,12 @@ void TDocOutput::CreateHierarchy()
 
    // write out header
    WriteHtmlHeader(out, "Class Hierarchy");
+
+   WriteTopLinks(out, 0);
+   out << "</div></div>" << endl;
+
    out << "<h1>Class Hierarchy</h1>" << endl;
 
-   WriteSearch(out);
 
    // loop on all classes
    TClassDocInfo* cdi = 0;
@@ -465,7 +461,10 @@ void TDocOutput::CreateClassIndex()
    // write indexFile header
    WriteHtmlHeader(indexFile, "Class Index");
 
-   indexFile << "<h1>Index</h1>" << endl;
+   WriteTopLinks(indexFile, 0);
+   indexFile << "</div></div>" << endl;
+
+   indexFile << "<h1>Class Index</h1>" << endl;
 
    WriteModuleLinks(indexFile);
 
@@ -493,8 +492,6 @@ void TDocOutput::CreateClassIndex()
       }
    }
 
-   WriteSearch(indexFile);
-
    indexFile << "<ul id=\"indx\">" << endl;
 
    // loop on all classes
@@ -548,15 +545,15 @@ void TDocOutput::CreateClassIndex()
 void TDocOutput::CreateModuleIndex()
 {
    // Create the class index for each module, picking up documentation from the
-   // module's TModuleDocInfo::GetSourceDir() plus the (possibly relative)
+   // module's TModuleDocInfo::GetInputPath() plus the (possibly relative)
    // THtml::GetModuleDocPath(). Also creates the library dependency plot if dot
    // exists, see THtml::HaveDot().
 
    const char* title = "LibraryDependencies";
-   TString filename(title);
-   gSystem->PrependPathName(fHtml->GetOutputDir(), filename);
+   TString dotfilename(title);
+   gSystem->PrependPathName(fHtml->GetOutputDir(), dotfilename);
 
-   std::ofstream libDepDotFile(filename + ".dot");
+   std::ofstream libDepDotFile(dotfilename + ".dot");
    libDepDotFile << "digraph G {" << endl
                  << "ratio=compress;" << endl
                  << "node [fontsize=22,labeldistance=0.1];" << endl
@@ -568,29 +565,36 @@ void TDocOutput::CreateModuleIndex()
                  << "K=0.1;" << endl;
 
    TModuleDocInfo* module = 0;
-   TIter iModule(fHtml->GetListOfModules());
+   TIter iterModule(fHtml->GetListOfModules());
 
    std::stringstream sstrCluster;
    std::stringstream sstrDeps;
-   while ((module = (TModuleDocInfo*)iModule())) {
+   while ((module = (TModuleDocInfo*)iterModule())) {
       if (!module->IsSelected())
          continue;
 
       std::vector<std::string> indexChars;
       TString filename(module->GetName());
+      filename.ToUpper();
+      filename.ReplaceAll("/","_");
       filename += "_Index.html";
       gSystem->PrependPathName(fHtml->GetOutputDir(), filename);
       std::ofstream outputFile(filename.Data());
       if (!outputFile.good()) {
-         Error("MakeIndex", "Can't open file '%s' !", filename.Data());
+         Error("CreateModuleIndex", "Can't open file '%s' !", filename.Data());
          continue;
       }
       Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), filename.Data());
 
       TString htmltitle("Index of ");
-      htmltitle += module->GetName();
-      htmltitle += " classes";
+      TString moduletitle(module->GetName());
+      moduletitle.ToUpper();
+      htmltitle += moduletitle;
       WriteHtmlHeader(outputFile, htmltitle);
+
+      WriteTopLinks(outputFile, module);
+      outputFile << "</div></div>" << endl;
+
       outputFile << "<h2>" << htmltitle << "</h2>" << endl;
 
       // Module doc
@@ -598,12 +602,13 @@ void TDocOutput::CreateModuleIndex()
          TString outdir(module->GetName());
          gSystem->PrependPathName(GetHtml()->GetOutputDir(), outdir);
 
-         TString moduleDocDir(GetHtml()->GetModuleDocPath());
-         if (!gSystem->IsAbsoluteFileName(moduleDocDir))
-            gSystem->PrependPathName(module->GetSourceDir(), moduleDocDir);
+         TString moduleDocDir;
+         GetHtml()->GetPathDefinition().GetDocDir(module->GetName(), moduleDocDir);
          ProcessDocInDir(outputFile, moduleDocDir, outdir, module->GetName());
       }
 
+      WriteModuleLinks(outputFile, module);
+
       std::list<std::string> classNames;
       {
          TIter iClass(module->GetClasses());
@@ -620,9 +625,12 @@ void TDocOutput::CreateModuleIndex()
             TString thisLib(libs);
             if (posDepLibs != kNPOS)
                thisLib.Remove(posDepLibs, thisLib.Length());
-            Ssiz_t posExt = thisLib.First('.');
-            if (posExt != kNPOS)
-               thisLib.Remove(posExt, thisLib.Length());
+
+            {
+               Ssiz_t posExt = thisLib.First('.');
+               if (posExt != kNPOS)
+                  thisLib.Remove(posExt, thisLib.Length());
+            }
 
             if (!thisLib.Length())
                continue;
@@ -659,22 +667,6 @@ void TDocOutput::CreateModuleIndex()
          } // while next class in module
       } // just a scope block
 
-      if (classNames.size() > 10) {
-         outputFile << "<div id=\"indxShortX\"><h4>Jump to</h4>" << endl;
-         UInt_t numSections = classNames.size() / 10;
-         if (numSections < 10) numSections = 10;
-         if (numSections > 50) numSections = 50;
-         // find index chars
-         GetIndexChars(classNames, numSections, indexChars);
-         for (UInt_t iIdxEntry = 0; iIdxEntry < indexChars.size(); ++iIdxEntry) {
-            outputFile << "<a href=\"#idx" << iIdxEntry << "\">";
-            ReplaceSpecialChars(outputFile, indexChars[iIdxEntry].c_str());
-            outputFile << "</a>" << endl;
-         }
-         outputFile << "</div><br />" << endl;
-      }
-      outputFile << "<ul id=\"indx\">" << endl;
-
       TIter iClass(module->GetClasses());
       TClassDocInfo* cdi = 0;
       UInt_t count = 0;
@@ -685,10 +677,31 @@ void TDocOutput::CreateModuleIndex()
 
          TClass *classPtr = cdi->GetClass();
          if (!classPtr) {
-            Error("MakeIndex", "Unknown class '%s' !", cdi->GetName());
+            Error("CreateModuleIndex", "Unknown class '%s' !", cdi->GetName());
             continue;
          }
 
+         if (!count) {
+            outputFile << "<h2>Class Index</h2>" << endl;
+
+            if (classNames.size() > 10) {
+               outputFile << "<div id=\"indxShortX\"><h4>Jump to</h4>" << endl;
+               UInt_t numSections = classNames.size() / 10;
+               if (numSections < 10) numSections = 10;
+               if (numSections > 50) numSections = 50;
+               // find index chars
+               GetIndexChars(classNames, numSections, indexChars);
+               for (UInt_t iIdxEntry = 0; iIdxEntry < indexChars.size(); ++iIdxEntry) {
+                  outputFile << "<a href=\"#idx" << iIdxEntry << "\">";
+                  ReplaceSpecialChars(outputFile, indexChars[iIdxEntry].c_str());
+                  outputFile << "</a>" << endl;
+               }
+               outputFile << "</div><br />" << endl;
+            }
+
+            outputFile << "<ul id=\"indx\">" << endl;
+         }
+
          // write a classname to an index file
          outputFile << "<li class=\"idxl" << (count++)%2 << "\">";
          if (currentIndexEntry < indexChars.size()
@@ -715,7 +728,8 @@ void TDocOutput::CreateModuleIndex()
       }
 
 
-      outputFile << "</ul>" << endl;
+      if (count)
+         outputFile << "</ul>" << endl;
 
       // write outputFile footer
       WriteHtmlFooter(outputFile);
@@ -776,7 +790,6 @@ void TDocOutput::CreateModuleIndex()
             sstrCluster << "Everything depends on ";
          sstrCluster << libinfo->GetName() << "\";" << endl;
 
-         const std::set<std::string>& modules = libinfo->GetModules();
          for (std::set<std::string>::const_iterator iModule = modules.begin();
               iModule != modules.end(); ++iModule) {
             sstrCluster << "\"" << *iModule << "\" [style=filled,color=white,URL=\""
@@ -821,21 +834,23 @@ void TDocOutput::CreateModuleIndex()
    libDepDotFile << "}" << endl;
    libDepDotFile.close();
 
-   std::ofstream out(filename + ".html");
+   std::ofstream out(dotfilename + ".html");
    if (!out.good()) {
       Error("CreateModuleIndex", "Can't open file '%s.html' !",
-            filename.Data());
+            dotfilename.Data());
       return;
    }
 
-   Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), (filename + ".html").Data());
+   Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), (dotfilename + ".html").Data());
    // write out header
    WriteHtmlHeader(out, "Library Dependencies");
-   out << "<h1>Library Dependencies</h1>" << endl;
 
-   WriteSearch(out);
+   WriteTopLinks(out, 0);
+   out << "</div></div>" << endl;
+
+   out << "<h1>Library Dependencies</h1>" << endl;
 
-   RunDot(filename, &out, kFdp);
+   RunDot(dotfilename, &out, kFdp);
 
    out << "<img alt=\"Library Dependencies\" class=\"classcharts\" usemap=\"#Map" << title << "\" src=\"" << title << ".gif\"/>" << endl;
 
@@ -863,10 +878,15 @@ void TDocOutput::CreateProductIndex()
    Printf(fHtml->GetCounterFormat(), "", "", outFile.Data());
 
    WriteHtmlHeader(out, GetHtml()->GetProductName() + " Reference Guide");
+
+   WriteTopLinks(out, 0);
+   out << "</div></div>" << endl;
+
    out << "<h1>" << GetHtml()->GetProductName() + " Reference Guide</h1>" << std::endl;
 
-   if (GetHtml()->GetProductDocDir().Length())
-      ProcessDocInDir(out, GetHtml()->GetProductDocDir(), GetHtml()->GetOutputDir(), "./");
+   TString prodDoc;
+   if (GetHtml()->GetPathDefinition().GetDocDir("", prodDoc))
+      ProcessDocInDir(out, prodDoc, GetHtml()->GetOutputDir(), "./");
 
    WriteModuleLinks(out);
 
@@ -907,16 +927,20 @@ void TDocOutput::CreateTypeIndex()
    typesList << "<dl><dd>" << endl;
 
    // make loop on data types
-   TDataType *type;
-   TIter nextType(gROOT->GetListOfTypes());
-
    std::list<std::string> typeNames;
-   while ((type = (TDataType *) nextType()))
-      // no templates ('<' and '>'), no idea why the '(' is in here...
-      if (*type->GetTitle() && !strchr(type->GetName(), '(')
-          && !( strchr(type->GetName(), '<') && strchr(type->GetName(),'>'))
-          && type->GetName())
+
+   {
+      TDataType *type;
+      TIter nextType(gROOT->GetListOfTypes());
+
+      while ((type = (TDataType *) nextType()))
+         // no templates ('<' and '>'), no idea why the '(' is in here...
+         if (*type->GetTitle() && !strchr(type->GetName(), '(')
+             && !( strchr(type->GetName(), '<') && strchr(type->GetName(),'>'))
+             && type->GetName())
             typeNames.push_back(type->GetName());
+   }
+
    sort_strlist_stricmp(typeNames);
 
    std::vector<std::string> indexChars;
@@ -934,7 +958,6 @@ void TDocOutput::CreateTypeIndex()
 
    typesList << "<ul id=\"indx\">" << endl;
 
-   nextType.Reset();
    int idx = 0;
    UInt_t currentIndexEntry = 0;
 
@@ -1131,11 +1154,9 @@ Bool_t TDocOutput::IsModified(TClass * classPtr, EFileType type)
    switch (type) {
    case kSource:
       if (classPtr->GetImplFileLine()) {
-         sourceFile = fHtml->GetImplFileName(classPtr);
-         fHtml->GetSourceFileName(sourceFile);
+         fHtml->GetImplFileName(classPtr, kTRUE, sourceFile);
       } else {
-         sourceFile = fHtml->GetDeclFileName(classPtr);
-         fHtml->GetSourceFileName(sourceFile);
+         fHtml->GetDeclFileName(classPtr, kTRUE, sourceFile);
       }
       dir = "src";
       gSystem->PrependPathName(fHtml->GetOutputDir(), dir);
@@ -1149,16 +1170,14 @@ Bool_t TDocOutput::IsModified(TClass * classPtr, EFileType type)
       break;
 
    case kInclude:
-      filename = fHtml->GetDeclFileName(classPtr);
-      sourceFile = filename;
-      fHtml->GetSourceFileName(sourceFile);
-      filename = fHtml->GetFileName(filename);
+      fHtml->GetDeclFileName(classPtr, kFALSE, filename);
+      filename = gSystem->BaseName(filename);
+      fHtml->GetDeclFileName(classPtr, kTRUE, sourceFile);
       gSystem->PrependPathName(fHtml->GetOutputDir(), filename);
       break;
 
    case kTree:
-      sourceFile = fHtml->GetDeclFileName(classPtr);
-      fHtml->GetSourceFileName(sourceFile);
+      fHtml->GetDeclFileName(classPtr, kTRUE, sourceFile);
       NameSpace2FileName(classname);
       gSystem->PrependPathName(fHtml->GetOutputDir(), classname);
       filename = classname;
@@ -1167,11 +1186,9 @@ Bool_t TDocOutput::IsModified(TClass * classPtr, EFileType type)
 
    case kDoc:
       if (classPtr->GetImplFileLine()) {
-         sourceFile = fHtml->GetImplFileName(classPtr);
-         fHtml->GetSourceFileName(sourceFile);
+         fHtml->GetImplFileName(classPtr, kTRUE, sourceFile);
       } else {
-         sourceFile = fHtml->GetDeclFileName(classPtr);
-         fHtml->GetSourceFileName(sourceFile);
+         fHtml->GetDeclFileName(classPtr, kTRUE, sourceFile);
       }
       filename = classname;
       NameSpace2FileName(filename);
@@ -1277,13 +1294,13 @@ void TDocOutput::ProcessDocInDir(std::ostream& out, const char* indir,
          // convert first
          outfile.Remove(outfile.Length()-3, 3);
          outfile += "html";
-         std::ifstream in(filename);
-         std::ofstream out(outfile);
-         if (in && out) {
-            out << "<pre>"; // this is what e.g. the html directive expects
+         std::ifstream inFurther(filename);
+         std::ofstream outFurther(outfile);
+         if (inFurther && outFurther) {
+            outFurther << "<pre>"; // this is what e.g. the html directive expects
             TDocParser parser(*this);
-            parser.Convert(out, in, "../");
-            out << "</pre>";
+            parser.Convert(outFurther, inFurther, "../");
+            outFurther << "</pre>";
          }
       } else {
          if (gSystem->CopyFile(filename, outfile, kTRUE) == -1)
@@ -1631,6 +1648,11 @@ void TDocOutput::WriteHtmlHeader(std::ostream& out, const char *titleNoSpecial,
       return;
    }
 
+   TString declFileName;
+   if (cls) fHtml->GetDeclFileName(cls, kFALSE, declFileName);
+   TString implFileName;
+   if (cls) fHtml->GetImplFileName(cls, kFALSE, implFileName);
+
    const TString& charset = GetHtml()->GetCharset();
    TDatime date;
    TString strDate(date.AsString());
@@ -1659,8 +1681,8 @@ void TDocOutput::WriteHtmlHeader(std::ostream& out, const char *titleNoSpecial,
 
          if (cls) {
             txt.ReplaceAll("%CLASS%", cls->GetName());
-            txt.ReplaceAll("%INCFILE%", fHtml->GetDeclFileName(cls));
-            txt.ReplaceAll("%SRCFILE%", fHtml->GetImplFileName(cls));
+            txt.ReplaceAll("%INCFILE%", declFileName);
+            txt.ReplaceAll("%SRCFILE%", implFileName);
          }
 
          out << txt << endl;
@@ -1726,7 +1748,7 @@ void TDocOutput::WriteHtmlFooter(std::ostream& out, const char* /*dir*/,
 //
 // Internal method invoked by the overload
 
-   static const char* templateSITags[TDocParser::kNumSourceInfos] = { "%UPDATE%", "%AUTHOR%", "%COPYRIGHT%"};
+   static const char* templateSITags[TDocParser::kNumSourceInfos] = { "%UPDATE%", "%AUTHOR%", "%COPYRIGHT%", "%CHANGED%", "%GENERATED%"};
 
    TString datimeString;
    if (!lastUpdate || !strlen(lastUpdate)) {
@@ -1734,7 +1756,10 @@ void TDocOutput::WriteHtmlFooter(std::ostream& out, const char* /*dir*/,
       datimeString = date.AsString();
       lastUpdate = datimeString.Data();
    }
-   const char* siValues[TDocParser::kNumSourceInfos] = { lastUpdate, author, copyright };
+   TString today;
+   TDatime dtToday;
+   today.Form("%d-%02d-%02d %02d:%02d", dtToday.GetYear(), dtToday.GetMonth(), dtToday.GetDay(), dtToday.GetHour(), dtToday.GetMinute());
+   const char* siValues[TDocParser::kNumSourceInfos] = { lastUpdate, author, copyright, lastUpdate, today };
 
    ifstream addFooterFile(footer);
 
@@ -1788,8 +1813,8 @@ void TDocOutput::WriteHtmlFooter(std::ostream& out, const char *dir,
 // Allows optional user provided footer to be written. Root.Html.Footer holds
 // the file name for this footer. For details see THtml::WriteHtmlHeader (here,
 // the "+" means the user's footer is written in front of Root's!) Occurences
-// of %AUTHOR%, %UPDATE%, and %COPYRIGHT% in the user's file are replaced by
-// their corresponding values (author, lastUpdate, and copyright) before
+// of %AUTHOR%, %CHANGED%, %GENERATED%, and %COPYRIGHT% in the user's file are replaced by
+// their corresponding values (author, lastUpdate, today, and copyright) before
 // written to out.
 // If no author is set (author == "", e.g. for ClassIndex.html") skip the whole
 // line of the footer template containing %AUTHOR%. Accordingly for %COPYRIGHT%.
@@ -1815,17 +1840,51 @@ void TDocOutput::WriteHtmlFooter(std::ostream& out, const char *dir,
 //______________________________________________________________________________
 void TDocOutput::WriteModuleLinks(std::ostream& out)
 {
-   // Create a dov containing links to all modules
+   // Create a dov containing links to all topmost modules
 
    if (fHtml->GetListOfModules()->GetSize()) {
       out << "<div id=\"indxModules\"><h4>Modules</h4>" << endl;
       // find index chars
       TIter iModule(fHtml->GetListOfModules());
       TModuleDocInfo* module = 0;
-      while ((module = (TModuleDocInfo*) iModule()))
-         if (module->IsSelected())
-            out << "<a href=\"" << module->GetName() << "_Index.html\">"
-                      << module->GetName() << "</a>" << endl;
+      while ((module = (TModuleDocInfo*) iModule())) {
+         if (!module->GetName() || strchr(module->GetName(), '/'))
+            continue;
+         if (module->IsSelected()) {
+            TString name(module->GetName());
+            name.ToUpper();
+            out << "<a href=\"" << name << "_Index.html\">"
+                << name << "</a>" << endl;
+         }
+      }
+      out<< "</div><br />" << endl;
+   }
+}
+
+//______________________________________________________________________________
+void TDocOutput::WriteModuleLinks(std::ostream& out, TModuleDocInfo* super)
+{
+   // Create a dov containing links to all modules
+
+   if (super->GetSub().GetSize()) {
+      TString superName(super->GetName());
+      superName.ToUpper();
+      out << "<div id=\"indxModules\"><h4>" << superName << " Modules</h4>" << endl;
+      // find index chars
+      TIter iModule(&super->GetSub());
+      TModuleDocInfo* module = 0;
+      while ((module = (TModuleDocInfo*) iModule())) {
+         if (module->IsSelected()) {
+            TString name(module->GetName());
+            name.ToUpper();
+            TString link(name);
+            link.ReplaceAll("/", "_");
+            Ssiz_t posSlash = name.Last('/');
+            if (posSlash != kNPOS)
+               name.Remove(0, posSlash + 1);
+            out << "<a href=\"" << link << "_Index.html\">" << name << "</a>" << endl;
+         }
+      }
       out<< "</div><br />" << endl;
    }
 }
@@ -1836,8 +1895,13 @@ void TDocOutput::WriteSearch(std::ostream& out)
    // Write a search link or a search box, based on THtml::GetSearchStemURL()
    // and THtml::GetSearchEngine(). The first one is preferred.
 
-   // e.g. searchCmd = "http://www.google.com/search?q=%s+site%3A%u";
+   // e.g. searchCmd = "http://www.google.com/search?q=%s+site%3A%u+-site%3A%u%2Fsrc%2F+-site%3A%u%2Fexamples%2F";
    const TString& searchCmd = GetHtml()->GetSearchStemURL();
+   const TString& searchEngine = GetHtml()->GetSearchEngine();
+
+   if (!searchCmd.Length() && !searchEngine.Length())
+      return;
+
    if (searchCmd.Length()) {
       // create search input
       out << "<script type=\"text/javascript\">" << endl
@@ -1846,15 +1910,77 @@ void TDocOutput::WriteSearch(std::ostream& out)
          << "var ref=String(document.location.href).replace(/https?:\\/\\//,'').replace(/\\/[^\\/]*$/,'').replace(/\\//g,'%2F');" << endl
          << "window.location.href=s.replace(/%u/ig,ref).replace(/%s/ig,escape(document.searchform.t.value));" << endl
          << "return false;}" << endl
-         << "</script><form action=\"javascript:onSearch();\" id=\"searchform\" name=\"searchform\" onsubmit=\"return onSearch()\">" << endl
-         << "<input name=\"t\" value=\"Search documentation...\"  onfocus=\"if (document.searchform.t.value=='Search documentation...') document.searchform.t.value='';\"></input>" << endl
-         << "<button type=\"submit\">Search</button></form>" << endl;
-      return;
+         << "</script>" << endl
+         << "<a class=\"descrheadentry\"> </a>" << endl
+         << "<form id=\"searchform\" name=\"searchform\" onsubmit=\"return onSearch()\" >" << endl
+         << "<input name=\"t\" value=\"Search documentation...\" onfocus=\"if (document.searchform.t.value==' Search documentation...        ') document.searchform.t.value='';\"></input></form>" << endl
+         << "<a id=\"searchlink\" href=\"javascript:onSearch();\" onclick=\"return onSearch()\">Search</a>" << endl;
+   } else if (searchEngine.Length())
+      // create link to search engine page
+      out << "<a class=\"descrheadentry\" href=\"" << searchEngine
+          << "\">Search the Class Reference Guide</a>" << endl;
+}
+
+//______________________________________________________________________________
+void TDocOutput::WriteTopLinks(std::ostream& out, TModuleDocInfo* module, const char* classname)
+{
+   // Write the first part of the links shown ontop of each doc page;
+   // two <div>s have to be closed by caller so additional items can still
+   // be added.
+
+   out << "<div id=\"toplinks\">" << endl;
+
+   // make a link to the description
+   out << "<div class=\"descrhead\">" << endl
+      << "<span class=\"descrtitle\">Location:</span>" << endl;
+   const char *productName = fHtml->GetProductName();
+   out << "<a class=\"descrheadentry\" href=\"index.html\">" << productName << "</a>" << endl;
+
+   if (module) {
+      TString modulename(module->GetName());
+      modulename.ToUpper();
+      TString modulePart;
+      TString modulePath;
+      Ssiz_t pos = 0;
+      while (modulename.Tokenize(modulePart, pos, "/")) {
+         if (pos == kNPOS && !classname)
+            // we are documenting the module itself, no need to link it:
+            break;
+         if (modulePath.Length()) modulePath += "_";
+         modulePath += modulePart;
+         out << " &#187; <a class=\"descrheadentry\" href=\"./" << modulePath << "_Index.html\">" << modulePart << "</a>" << endl;
+      }
    }
 
-   const TString& searchEngine = GetHtml()->GetSearchEngine();
-   if (searchEngine.Length())
-      // create link to search engine page
-      out << "<h2><a href=\"" << searchEngine
-          << "\">Search the Class Reference Guide</a></h2>" << endl;
+   TString entityName;
+   if (classname) entityName = classname;
+   else if (module) {
+      entityName = module->GetName();
+      Ssiz_t posSlash = entityName.Last('/');
+      if (posSlash != kNPOS)
+         entityName.Remove(0, posSlash + 1);
+      entityName.ToUpper();
+   }
+   if (entityName.Length()) {
+      out << " &#187; <a class=\"descrheadentry\" href=\"#TopOfPage\">";
+      ReplaceSpecialChars(out, entityName);
+      out << "</a>" << endl;
+   }
+   out << "</div>" << endl;
+
+   out << "<div class=\"descrhead\">" << endl
+      << "<span class=\"descrtitle\">Quick Links:</span>" << endl;
+
+   // link to the user home page (if exist)
+   const char* userHomePage = GetHtml()->GetHomepage();
+   if (productName && !strcmp(productName, "ROOT"))
+      userHomePage = "";
+   if (userHomePage && *userHomePage)
+      out << "<a class=\"descrheadentry\" href=\"" << userHomePage << "\">" << productName << "</a>" << endl;
+   out << "<a class=\"descrheadentry\" href=\"http://root.cern.ch\">ROOT Homepage</a>" << endl
+      << "<a class=\"descrheadentry\" href=\"./ClassIndex.html\">Class Index</a>" << endl
+      << "<a class=\"descrheadentry\" href=\"./ClassHierarchy.html\">Class Hierarchy</a>" << endl;
+   WriteSearch(out);
+   out << "</div>" << endl;
+
 }
diff --git a/html/src/TDocParser.cxx b/html/src/TDocParser.cxx
index 1be2e801ed2db907a5c7a79ad95aae1a38e75380..958c3cb133ae2b7c6302dd60188c830c34193e72 100644
--- a/html/src/TDocParser.cxx
+++ b/html/src/TDocParser.cxx
@@ -131,7 +131,7 @@ std::set<std::string>  TDocParser::fgKeywords;
 //______________________________________________________________________________
 TDocParser::TDocParser(TClassDocOutput& docOutput, TClass* cl):
    fHtml(docOutput.GetHtml()), fDocOutput(&docOutput), fLineNo(0),
-   fCurrentClass(cl), fDirectiveCount(0), fDocContext(kIgnore), 
+   fCurrentClass(cl), fCurrentModule(0), fDirectiveCount(0), fDocContext(kIgnore), 
    fCheckForMethod(kFALSE), fClassDocState(kClassDoc_Uninitialized), 
    fCommentAtBOL(kFALSE)
 {
@@ -750,6 +750,25 @@ void TDocParser::DecrementMethodCount(const char* name)
    }
 }
 
+//______________________________________________________________________________
+void  TDocParser::DeleteDirectiveOutput() const
+{
+   // Delete output generated by prior runs of all known directives;
+   // the output file names might have changes.
+
+   TIter iClass(gROOT->GetListOfClasses());
+   TClass* cl = 0;
+   while ((cl = (TClass*) iClass()))
+      if (cl != TDocDirective::Class()
+         && cl->InheritsFrom(TDocDirective::Class())) {
+         TDocDirective* directive = (TDocDirective*) cl->New();
+         if (!directive) continue;
+         directive->SetParser(const_cast<TDocParser*>(this));
+         directive->DeleteOutput();
+         delete directive;
+      }
+}
+
 //______________________________________________________________________________
 void TDocParser::ExpandCPPLine(TString& line, Ssiz_t& pos)
 {
@@ -777,8 +796,8 @@ void TDocParser::ExpandCPPLine(TString& line, Ssiz_t& pos)
          if (line.Tokenize(filename, posEndFilename, "[>\"]")) {
             R__LOCKGUARD(fHtml->GetMakeClassMutex());
 
-            TString filesysFileName(filename);
-            if (gSystem->FindFile(fHtml->GetSourceDir(), filesysFileName, kReadPermission)) {
+            TString filesysFileName;
+            if (fHtml->GetPathDefinition().GetFileNameFromInclude(filename, filesysFileName)) {
                fDocOutput->CopyHtmlFile(filesysFileName);
 
                TString endOfLine(line(posEndFilename - 1, line.Length()));
@@ -787,7 +806,7 @@ void TDocParser::ExpandCPPLine(TString& line, Ssiz_t& pos)
                   fDocOutput->ReplaceSpecialChars(line, i);
 
                line += "<a href=\"../";
-               line += fHtml->GetFileName(filename);
+               line += gSystem->BaseName(filename);
                line += "\">";
                line += filename + "</a>" + endOfLine[0]; // add include file's closing '>' or '"'
                posEndOfLine = line.Length() - 1; // set the "processed up to" to it
@@ -814,6 +833,15 @@ void TDocParser::ExpandCPPLine(TString& line, Ssiz_t& pos)
    pos = posEndOfLine;
 }
 
+
+//______________________________________________________________________________
+void TDocParser::GetCurrentModule(TString& out_module) const {
+   // Return the name of module for which sources are currently parsed.
+   if (fCurrentModule) out_module = fCurrentModule;
+   else if (fCurrentClass) fHtml->GetModuleNameForClass(out_module, fCurrentClass);
+   else out_module = "(UNKNOWN MODULE WHILE PARSING)";
+}
+
 //______________________________________________________________________________
 Bool_t TDocParser::HandleDirective(TString& line, Ssiz_t& pos, TString& word, 
                                    Ssiz_t& copiedToCommentUpTo)
@@ -1124,7 +1152,7 @@ TClass* TDocParser::IsDirective(const TString& line, Ssiz_t pos,
 
    TClass* clDirective = fHtml->GetClass(tag);
 
-   if (!clDirective)
+   if (gDebug > 0 && !clDirective)
       Warning("IsDirective", "Unknown THtml directive %s in line %d!", word.Data(), fLineNo);
 
    return clDirective;
@@ -1403,6 +1431,8 @@ void TDocParser::Parse(std::ostream& out)
 
    fClassDocState = kClassDoc_LookingNothingFound;
 
+   DeleteDirectiveOutput();
+
    LocateMethodsInSource(out);
    LocateMethodsInHeaderInline(out);
    LocateMethodsInHeaderClassDecl(out);
@@ -1440,10 +1470,10 @@ void TDocParser::LocateMethods(std::ostream& out, const char* filename,
 
    TString sourceFileName(filename);
    fCurrentFile = filename;
-   fHtml->GetSourceFileName(sourceFileName);
    if (!sourceFileName.Length()) {
+      fHtml->GetImplFileName(fCurrentClass, kFALSE, sourceFileName);
       Error("LocateMethods", "Can't find source file '%s' for class %s!", 
-         fHtml->GetImplFileName(fCurrentClass), fCurrentClass->GetName());
+         sourceFileName.Data(), fCurrentClass->GetName());
       return;
    }
    ifstream sourceFile(sourceFileName.Data());
@@ -1652,8 +1682,8 @@ void TDocParser::LocateMethodsInSource(std::ostream& out)
       pattern.Remove(0, posLastScope + 2);
    pattern += "::";
    
-   const char* implFileName = fHtml->GetImplFileName(fCurrentClass);
-   if (implFileName && implFileName[0])
+   TString implFileName;
+   if (fHtml->GetImplFileName(fCurrentClass, kTRUE, implFileName))
       LocateMethods(out, implFileName, kFALSE /*source info*/, useDocxxStyle, 
                     kFALSE /*allowPureVirtual*/, pattern, ".cxx.html");
    else out << "</div>" << endl; // close class descr div
@@ -1675,8 +1705,8 @@ void TDocParser::LocateMethodsInHeaderInline(std::ostream& out)
       pattern.Remove(0, posLastScope + 1);
    pattern += "::";
    
-   const char* declFileName = fHtml->GetDeclFileName(fCurrentClass);
-   if (declFileName && declFileName[0])
+   TString declFileName;
+   if (fHtml->GetDeclFileName(fCurrentClass, kTRUE, declFileName))
       LocateMethods(out, declFileName, kTRUE /*source info*/, useDocxxStyle, 
                     kFALSE /*allowPureVirtual*/, pattern, 0);
 }
@@ -1688,8 +1718,8 @@ void TDocParser::LocateMethodsInHeaderClassDecl(std::ostream& out)
    // class declaration block, and extract documentation to out,
    // while beautifying the header file in parallel.
 
-   const char* declFileName = fHtml->GetDeclFileName(fCurrentClass);
-   if (declFileName && declFileName[0])
+   TString declFileName;
+   if (fHtml->GetDeclFileName(fCurrentClass, kTRUE, declFileName))
       LocateMethods(out, declFileName, kTRUE/*source info*/, kTRUE /*useDocxxStyle*/,
                     kTRUE /*allowPureVirtual*/, 0, ".h.html");
 }
diff --git a/html/src/THtml.cxx b/html/src/THtml.cxx
index 1f015727d838b3c1688f50c29edb26d8ca84ec31..75b4cda312d5b9b1edab23c623481af0c931b4d4 100644
--- a/html/src/THtml.cxx
+++ b/html/src/THtml.cxx
@@ -1,5 +1,5 @@
 // @(#)root/html:$Id$
-// Author: Nenad Buncic (18/10/95), Axel Naumann <mailto:axel@fnal.gov> (09/28/01)
+// Author: Nenad Buncic (18/10/95), Axel Naumann (09/28/01)
 
 /*************************************************************************
  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
@@ -22,6 +22,7 @@
 #include "TEnv.h"
 #include "TInterpreter.h"
 #include "TObjString.h"
+#include "TPRegexp.h"
 #include "TRegexp.h"
 #include "TROOT.h"
 #include "TSystem.h"
@@ -35,6 +36,8 @@
 
 THtml *gHtml = 0;
 
+//______________________________________________________________________________
+//______________________________________________________________________________
 namespace {
    class THtmlThreadInfo {
    public:
@@ -49,6 +52,532 @@ namespace {
 };
 
 
+//______________________________________________________________________________
+THtml::THelperBase::~THelperBase()
+{
+   // Helper's destructor.
+   // Check that no THtml object is attached to the helper - it might still need it!
+   if (fHtml) {
+      fHtml->HelperDeleted(this);
+   }
+}
+
+
+//______________________________________________________________________________
+void THtml::THelperBase::SetOwner(THtml* html) {
+   // Set the THtml object owning this object; if it's already set to
+   // a different THtml object than issue an error message and signal to
+   // the currently set object that we are not belonging to it anymore.
+   if (fHtml && html && html != fHtml) {
+      Error("SetOwner()", "Object already owned by an THtml instance!");
+      fHtml->HelperDeleted(this);
+   }
+   fHtml = html;
+}
+
+
+//______________________________________________________________________________
+bool THtml::TModuleDefinition::GetModule(TClass* cl, TString& out_modulename) const
+{
+   // Set out_modulename to cl's module name; return true if it's valid.
+   // If applicable, the module contains super modules separated by "/".
+   //
+   // ROOT takes the directory part of cl's implementation file name 
+   // (or declaration file name, if the implementation file name is empty),
+   // removes the last subdirectory if it is "src/" or "inc/", and interprets
+   // the remaining path as the module hierarchy, converting it to upper case.
+   // hist/histpainter/src/THistPainter.cxx thus becomes the module
+   // HIST/HISTPAINTER. (Node: some ROOT packages get special treatment.)
+   // If the file cannot be mapped into this scheme, the class's library
+   // name (without directories, leading "lib" prefix or file extensions)
+   // ius taken as the module name. If the module cannot be determined it is
+   // set to "USER" and false is returned.
+   //
+   // If your software cannot be mapped into this scheme then derive your
+   // own class from TModuleDefinition and pass it to THtml::SetModuleDefinition().
+
+   out_modulename = "USER";
+   if (!cl) return false;
+
+   // Filename: impl or decl?
+   TString filename;
+   if (!GetOwner()->GetImplFileName(cl, kFALSE, filename))
+      if (!GetOwner()->GetDeclFileName(cl, kFALSE, filename))
+         return false;
+
+   // take the directory name without "/" or leading "."
+   out_modulename = gSystem->DirName(filename);
+   while (out_modulename[0] == '.')
+      out_modulename.Remove(0, 1);
+   out_modulename.ReplaceAll("\\", "/");
+   while (out_modulename[0] == '/')
+      out_modulename.Remove(0, 1);
+   while (out_modulename.EndsWith("/"))
+      out_modulename.Remove(out_modulename.Length() - 1);
+
+   // remove "/src", "/inc"
+   if (out_modulename.EndsWith("/src")
+      || out_modulename.EndsWith("/inc"))
+      out_modulename.Remove(out_modulename.Length() - 4, 4);
+   else {
+   // remove "/src/whatever", "/inc/whatever"
+      Ssiz_t pos = out_modulename.Index("/src/");
+      if (pos == kNPOS)
+         pos = out_modulename.Index("/inc/");
+      if (pos != kNPOS)
+         out_modulename.Remove(pos);
+   }
+
+   while (out_modulename.EndsWith("/"))
+      out_modulename.Remove(out_modulename.Length() - 1);
+
+   // special treatment:
+   if (out_modulename == "MATH/GENVECTOR")
+      out_modulename = "MATHCORE";
+   else if (out_modulename == "MATH/MATRIX")
+      out_modulename = "SMATRIX";
+   else if (!out_modulename.Length()) {
+      const char* cname= cl->GetName();
+      if (strstr(cname, "::SMatrix<") || strstr(cname, "::SVector<"))
+         out_modulename = "SMATRIX";
+      else if (strstr(cname, "::TArrayProxy<") || strstr(cname, "::TClaArrayProxy<")
+               || strstr(cname, "::TImpProxy<") || strstr(cname, "::TClaImpProxy<"))
+         out_modulename = "TREEPLAYER";
+      else {
+         // determine the module name from the library name:
+         out_modulename = cl->GetSharedLibs();
+         Ssiz_t pos = out_modulename.Index(' ');
+         if (pos != kNPOS)
+            out_modulename.Remove(pos, out_modulename.Length());
+         if (out_modulename.BeginsWith("lib"))
+            out_modulename.Remove(0,3);
+         pos = out_modulename.Index('.');
+         if (pos != kNPOS)
+            out_modulename.Remove(pos, out_modulename.Length());
+
+         if (!out_modulename.Length()) {
+            out_modulename = "USER";
+            return false;
+         }
+      }
+   }
+
+   return true;
+}
+
+//______________________________________________________________________________
+void THtml::TFileDefinition::ExpandSearchPath(TString& path) const
+{
+   // Create all permutations of path and THtml's input path:
+   // path being PP/ and THtml's input being .:include/:src/ gives
+   // .:./PP/:include:include/PP/:src/:src/PP
+   THtml* owner = GetOwner();
+   if (!owner) return;
+
+   TString pathext;
+   TString inputdir = owner->GetInputPath();
+   TString tok;
+   Ssiz_t start = 0;
+   while (inputdir.Tokenize(tok, start, THtml::GetDirDelimiter())) {
+      if (pathext.Length())
+         pathext += GetDirDelimiter();
+      if (tok.EndsWith("\\"))
+         tok.Remove(tok.Length() - 1);
+      pathext += tok;
+      pathext += GetDirDelimiter() + tok + "/" + path;
+   }
+   path = pathext;
+
+}
+
+//______________________________________________________________________________
+void THtml::TFileDefinition::SplitClassIntoDirFile(const TString& clname, TString& dir, TString& filename) const
+{
+   // Given a class name with a scope, split the class name into directory part
+   // and file name: A::B::C becomes module B, filename C.
+   TString token;
+   Ssiz_t from = 0;
+   filename = "";
+   dir = "";
+   while (clname.Tokenize(token, from, "::") ) {
+      dir = filename;
+      filename = token;
+   }
+
+   // convert from Scope, class to module, filename.h
+   dir.ToLower();
+}
+
+
+//______________________________________________________________________________
+bool THtml::TFileDefinition::GetDeclFileName(const TClass* cl, TString& out_filename, TString& out_fsys) const
+{
+   // Determine cl's declaration file name. Usually it's just
+   // cl->GetDeclFileName(), but sometimes conversions need to be done
+   // like include/ to abc/cde/inc/. If no declaration file name is
+   // available, look for b/inc/C.h for class A::B::C. out_fsys will contain
+   // the file system's (i.e. local machine's) full path name to the file.
+   // The function returns false if the class's header file cannot be found.
+   //
+   // If your software cannot be mapped into this scheme then derive your
+   // own class from TFileDefinition and pass it to THtml::SetFileDefinition().
+
+   return GetFileName(cl, true, out_filename, out_fsys);
+}
+
+//______________________________________________________________________________
+bool THtml::TFileDefinition::GetImplFileName(const TClass* cl, TString& out_filename, TString& out_fsys) const
+{
+   // Determine cl's implementation file name. Usually it's just
+   // cl->GetImplFileName(), but sometimes conversions need to be done.
+   // If no implementation file name is available look for b/src/C.cxx for
+   // class A::B::C. out_fsys will contain the file system's (i.e. local 
+   // machine's) full path name to the file.
+   // The function returns false if the class's source file cannot be found.
+   //
+   // If your software cannot be mapped into this scheme then derive your
+   // own class from TFileDefinition and pass it to THtml::SetFileDefinition().
+
+   return GetFileName(cl, false, out_filename, out_fsys);
+}
+
+
+//______________________________________________________________________________
+bool THtml::TFileDefinition::GetFileName(const TClass* cl, bool decl, TString& out_filename, TString& out_fsys) const
+{
+   // Common implementation for GetDeclFileName(), GetImplFileName()
+
+   out_fsys = "";
+
+   if (!cl) {
+      out_filename = "";
+      return false;
+   }
+
+   TString possibleFileName;
+   TString possiblePath;
+   TString filesysname;
+
+   TString clfile = decl ? cl->GetDeclFileName() : cl->GetImplFileName();
+   out_filename = clfile;
+   if (clfile.Length()) {
+      // check that clfile doesn't start with one of the include paths;
+      // that's not what we want (include/TObject.h), we want the actual file
+      // if it exists (core/base/inc/TObject.h)
+      TString inclDir;
+      TString inclPath(GetOwner()->GetPathInfo().fIncludePath);
+      Ssiz_t pos = 0;
+      Ssiz_t longestMatch = kNPOS;
+      while (inclPath.Tokenize(inclDir, pos, GetOwner()->GetDirDelimiter())) {
+         if (clfile.BeginsWith(inclDir) && (longestMatch == kNPOS || inclDir.Length() > longestMatch))
+            longestMatch = inclDir.Length();
+      }
+      if (longestMatch != kNPOS) {
+         clfile.Remove(0, longestMatch);
+         if (clfile.BeginsWith("/") || clfile.BeginsWith("\\"))
+            clfile.Remove(0, 1);
+         TString asincl(clfile);
+         GetOwner()->GetPathDefinition().GetFileNameFromInclude(asincl, clfile);
+         out_filename = clfile;
+      }
+   } else {
+      // check for a file named like the class:
+      filesysname = cl->GetName();
+      int templateLevel = 0;
+      Ssiz_t end = filesysname.Length();
+      Ssiz_t start = end - 1;
+      for (; start >= 0 && (templateLevel || filesysname[start] != ':'); --start) {
+         if (filesysname[start] == '>')
+            ++templateLevel;
+         else if (filesysname[start] == '<') {
+            --templateLevel;
+            if (!templateLevel)
+               end = start;
+         }
+      }
+      filesysname = filesysname(start + 1, end - start - 1);
+      if (decl)
+         filesysname += ".h";
+      else
+         filesysname += ".cxx";
+      TFileSysEntry* fsentry = (TFileSysEntry*) GetOwner()->GetLocalFiles()->GetEntries().FindObject(filesysname);
+      if (fsentry) {
+         fsentry->GetFullName(filesysname);
+         clfile = filesysname;
+         out_filename = filesysname;
+      }
+   }
+
+   if (!decl && !clfile.Length()) {
+      // determine possiblt impl file name from the decl file name,
+      // replacing ".whatever" by ".cxx", and looking for it in the known
+      // file names
+      TString declSysFileName;
+      if (GetFileName(cl, true, filesysname, declSysFileName)) {
+         filesysname = gSystem->BaseName(filesysname);
+         Ssiz_t posExt = filesysname.Last('.');
+         if (posExt != kNPOS)
+            filesysname.Remove(posExt);
+         filesysname += ".cxx";
+         TFileSysEntry* fsentry = (TFileSysEntry*) GetOwner()->GetLocalFiles()->GetEntries().FindObject(filesysname);
+         if (fsentry) {
+            fsentry->GetFullName(filesysname);
+            clfile = filesysname;
+            out_filename = filesysname;
+         }
+      }
+   }
+
+   if (!clfile.Length()) {
+      // determine possible decl file name from class + scope name:
+      // A::B::C::myclass will result in possible file name myclass.h
+      // in directory C/inc/
+      out_filename = cl->GetName();
+      if (!out_filename.Contains("::")) {
+         out_filename = "";
+         return false;
+      }
+      SplitClassIntoDirFile(out_filename, possiblePath, possibleFileName);
+
+      // convert from Scope, class to module, filename.h
+      if (possibleFileName.Length()) {
+         if (decl)
+            possibleFileName += ".h";
+         else
+            possibleFileName += ".cxx";
+      }
+      if (possiblePath.Length())
+         possiblePath += "/";
+      if (decl)
+         possiblePath += "inc/";
+      else
+         possiblePath += "src/";
+      out_filename = possiblePath + "/" + possibleFileName;
+   } else {
+      possiblePath = gSystem->DirName(clfile);
+      possibleFileName = gSystem->BaseName(clfile);
+   }
+
+   if (possiblePath.Length())
+      ExpandSearchPath(possiblePath);
+
+   out_fsys = gSystem->FindFile(possiblePath, possibleFileName, kReadPermission);
+   if (out_fsys.Length()) return true;
+   out_filename = "";
+   return false;
+}
+
+//______________________________________________________________________________
+bool THtml::TPathDefinition::GetMacroPath(const TString& module, TString& out_dir) const
+{
+   // Determine the path to look for macros (see TDocMacroDirective) for
+   // classes from a given module. If the path was sucessfully determined return true.
+   // For ROOT, this directory is the "doc/macros" subdirectory of the module
+   // directory; the path returned is GetDocDir(module) + "/macros".
+   //
+   // If your software cannot be mapped into this scheme then derive your
+   // own class from TPathDefinition and pass it to THtml::SetPathDefinition().
+
+   TString moduledoc;
+   if (!GetDocDir(module, moduledoc))
+      return false;
+   if (moduledoc.EndsWith("\\"))
+      moduledoc.Remove(moduledoc.Length() - 1);
+
+   TString macropath(GetOwner()->GetMacroPath());
+   TString macrodirpart;
+   out_dir = "";
+   Ssiz_t pos = 0;
+   while (macropath.Tokenize(macrodirpart, pos, ":")) {
+      out_dir += moduledoc + "/" + macrodirpart + ":";
+   }
+   return true;
+}
+
+
+//______________________________________________________________________________
+bool THtml::TPathDefinition::GetDocDir(const TString& module, TString& doc_dir) const
+{
+   // Determine the module's documentation directory. If module is empty,
+   // set doc_dir to the product's documentation directory.
+   // If the path was sucessfuly determined return true.
+   // For ROOT, this directory is the subdir "doc/" in the
+   // module's path; the directory returned is module + "/doc".
+   //
+   // If your software cannot be mapped into this scheme then derive your
+   // own class from TPathDefinition and pass it to THtml::SetPathDefinition().
+
+   if (module.Length())
+      doc_dir = module + "/";
+   doc_dir += GetOwner()->GetPathInfo().fDocPath;
+   return true;
+}
+
+
+//______________________________________________________________________________
+bool THtml::TPathDefinition::GetIncludeAs(TClass* cl, TString& out_dir) const
+{
+   // Determine the path and filename used in an include statement for the
+   // header file of the given class. E.g. the class ROOT::Math::Boost is
+   // meant to be included as "Math/Genvector/Boost.h" - which is what
+   // out_dir is set to. GetIncludeAs() returns whether the include 
+   // statement's path was successfully determined.
+   //
+   // Any leading directory part that is part of fIncludePath (see SetIncludePath)
+   // will be removed. For ROOT, leading "include/" is removed; everything after
+   // is the include path. Only classes from TMVA are different; they are included
+   // as TMVA/ClassName.h.
+   //
+   // If your software cannot be mapped into this scheme then derive your
+   // own class from TPathDefinition and pass it to THtml::SetPathDefinition().
+
+   out_dir = "";
+   if (!cl || !GetOwner()) return false;
+
+   const char* clname = cl->GetName();
+   TString hdr;
+   if (!GetOwner()->GetDeclFileName(cl, kFALSE, hdr))
+      return false;
+
+   out_dir = hdr;
+   bool includePathMatches = false;
+   TString tok;
+   Ssiz_t pos = 0;
+   while (!includePathMatches && GetOwner()->GetPathInfo().fIncludePath.Tokenize(tok, pos, THtml::GetDirDelimiter()))
+      if (out_dir.BeginsWith(tok)) {
+         out_dir = hdr(tok.Length(), hdr.Length());
+         includePathMatches = true;
+      }
+
+   if (!includePathMatches) {
+      // We probably have a file super/module/inc/optional/filename.h.
+      // That gets translated into optional/filename.h.
+      // Assume that only one occurrence of "/inc/" exists in hdr.
+      // If /inc/ is not part of the include file name then
+      // just return the full path.
+      // If we have matched any include path then this ROOT-only
+      // algorithm is skipped!
+      hdr = strstr(hdr, "/inc/");
+      if (!hdr) return true;
+      hdr += 5;
+      out_dir = hdr;
+
+      // TMVA special treatment:
+      // TMVA::Whatever claims to be in in math/tmva/inc/Whatever.h
+      // but it needs to get included as TMVA/Whatever.h
+      if (strstr(clname, "TMVA::"))
+         out_dir.Prepend("TMVA/");
+   }
+
+   return (out_dir.Length());
+}
+
+
+//______________________________________________________________________________
+bool THtml::TPathDefinition::GetFileNameFromInclude(const char* included, TString& out_fsname) const
+{
+   // Set out_fsname to the full pathname corresponding to a file
+   // included as "included". Return false if this file cannot be determined
+   // or found. For ROOT, out_fsname corresponds to included prepended with
+   // "include"; only THtml prefers to work on the original files, e.g.
+   // core/base/inc/TObject.h instead of include/TObject.h, so the
+   // default implementation searches the TFileSysDB for an entry with
+   // basename(included) and with matching directory part, setting out_fsname
+   // to the TFileSysEntry's path.
+
+   if (!included) return false;
+
+   out_fsname = included;
+
+   if (!strncmp(included, "TMVA/", 5)) {
+      out_fsname.Remove(0, 4);
+      out_fsname.Prepend("tmva/inc");
+      return true;
+   }
+
+   TString incBase(gSystem->BaseName(included));
+   TList* bucket = GetOwner()->GetLocalFiles()->GetEntries().GetListForObject(incBase);
+   if (!bucket) return false;
+
+   TString alldir(gSystem->DirName(included));
+   TObjArray* arrSubDirs = alldir.Tokenize("/");
+   TIter iEntry(bucket);
+   TFileSysEntry* entry = 0;
+   while ((entry = (TFileSysEntry*) iEntry())) {
+      if (incBase != entry->GetName()) continue;
+      // find entry with matching enclosing directory
+      THtml::TFileSysDir* parent = entry->GetParent();
+      for (int i = arrSubDirs->GetEntries() - 1; parent && i >= 0; --i) {
+         const TString& subdir(((TObjString*)(*arrSubDirs)[i])->String());
+         if (!subdir.Length() || subdir == ".")
+            continue;
+         if (subdir == parent->GetName())
+            parent = parent->GetParent();
+         else parent = 0;
+      }
+      if (parent) {
+         // entry found!
+         entry->GetFullName(out_fsname);
+         delete arrSubDirs;
+         return true;
+      }
+   }
+   delete arrSubDirs;
+   return false;
+}
+
+//______________________________________________________________________________
+void THtml::TFileSysDir::Recurse(TFileSysDB* db, const char* path)
+{
+   // Recursively fill entries by parsing the path;
+   // can be a THtml::GetDirDelimiter() delimited list of paths.
+
+   TString sPath(path);
+   printf("scanning %s...\n", path);
+   TString dir;
+   Ssiz_t posPath = 0;
+   TPMERegexp regexp(db->GetIgnore());
+   while (sPath.Tokenize(dir, posPath, THtml::GetDirDelimiter())) {
+      dir += "/";
+      void* hDir = gSystem->OpenDirectory(dir);
+      const char* direntry = 0;
+      while ((direntry = gSystem->GetDirEntry(hDir))) {
+         if (!direntry[0] || direntry[0] == '.') continue;
+         TString entryPath(dir + direntry);
+         if (gSystem->AccessPathName(entryPath, kReadPermission)
+            || regexp.Match(entryPath))
+            continue;
+         FileStat_t buf;
+         gSystem->GetPathInfo(entryPath, buf);
+         if (R_ISDIR(buf.fMode)) {
+            // skip if we would nest too deeply,  and skip soft links:
+            if (GetLevel() > db->GetMaxLevel()
+#ifndef R__WIN32
+               || db->GetMapIno().GetValue(buf.fIno)
+#endif
+               ) continue;
+            TFileSysDir* subdir = new TFileSysDir(direntry, this);
+            fDirs.Add(subdir);
+#ifndef R__WIN32
+            db->GetMapIno().Add(buf.fIno, (Long_t)subdir);
+#endif
+            subdir->Recurse(db, entryPath);
+         } else {
+            int delen = strlen(direntry);
+            // only .cxx and .h are taken
+            if (strcmp(direntry + delen - 4, ".cxx")
+               && strcmp(direntry + delen - 2, ".h"))
+               continue;
+            TFileSysEntry* entry = new TFileSysEntry(direntry, this);
+            db->GetEntries().Add(entry);
+            fFiles.Add(entry);
+         }
+      } // while dir entry
+      gSystem->FreeDirectory(hDir);
+   } // while sPath token
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 /* BEGIN_HTML
 <p>The THtml class is designed to easily document
@@ -121,7 +650,7 @@ which you can set in your .rootrc.
 
 <p>In your .rootrc, define Root.Html.SourceDir to point to directories containing 
 .cxx and .h files (see: <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>) 
-of the classes you want to document, or call THtml::SetSourceDir()</p>
+of the classes you want to document, or call THtml::SetInputDir()</p>
 
 <p>Example:</p><pre>
   Root.Html.SourceDir:  .:src:include
@@ -141,7 +670,7 @@ will create it.</p>
 <h4><a name="conf:liblink">II.3 Linking other documentation</a></h4>
 
 <p>When trying to document a class, THtml searches for a source file in 
-the directories set via SetSourceDir(). If it cannot find it, it assumes
+the directories set via SetInputDir(). If it cannot find it, it assumes
 that this class must have been documented before. Based on the library
 this class is defined in, it checks the configuration variable
 <tt>Root.Html.LibName</tt>, and creates a link using its value.
@@ -516,43 +1045,40 @@ END_HTML */
 
 ClassImp(THtml)
 //______________________________________________________________________________
-THtml::THtml(): fIncludePath("include"), fFoundDot(-1), 
+THtml::THtml():
    fCounterFormat("%12s %5s %s"),
-   fProductName("(UNKNOWN PRODUCT)"), fProductDocDir("doc"),
-   fMacroPath("../doc/macros:."), fModuleDocPath("../doc"),
-   fThreadedClassIter(0), fMakeClassMutex(0)
-
+   fProductName("(UNKNOWN PRODUCT)"),
+   fThreadedClassIter(0), fMakeClassMutex(0),
+   fPathDef(0), fModuleDef(0), fFileDef(0),
+   fLocalFiles(0)
 {
    // Create a THtml object.
    // In case output directory does not exist an error
    // will be printed and gHtml stays 0 also zombie bit will be set.
 
-   // get prefix for source directory
-   fSourcePrefix = gEnv->GetValue("Root.Html.SourcePrefix", "");
-
    // check for source directory
-   fSourceDir = gEnv->GetValue("Root.Html.SourceDir", "./:src/:include/");
+   fPathInfo.fInputPath = gEnv->GetValue("Root.Html.SourceDir", "./:src/:include/");
 
    // check for output directory
-   fOutputDir = gEnv->GetValue("Root.Html.OutputDir", "htmldoc");
-
-   fXwho = gEnv->GetValue("Root.Html.XWho", "http://consult.cern.ch/xwho/people?");
-   fROOTURL = gEnv->GetValue("Root.Html.Root", "http://root.cern.ch/root/html");
-   fClassDocTag = gEnv->GetValue("Root.Html.Description", "//____________________");
-   fAuthorTag = gEnv->GetValue("Root.Html.Author", "// Author:");
-   fLastUpdateTag = gEnv->GetValue("Root.Html.LastUpdate", "// @(#)");
-   fCopyrightTag = gEnv->GetValue("Root.Html.Copyright", "* Copyright");
-   fHeader = gEnv->GetValue("Root.Html.Header", "");
-   fFooter = gEnv->GetValue("Root.Html.Footer", "");
-   fHomepage = gEnv->GetValue("Root.Html.Homepage", "");
-   fSearchStemURL = gEnv->GetValue("Root.Html.Search", "");
-   fSearchEngine = gEnv->GetValue("Root.Html.SearchEngine", "");
-   fViewCVS = gEnv->GetValue("Root.Html.ViewCVS", "");
-   fCharset = gEnv->GetValue("Root.Html.Charset", "ISO-8859-1");
-   fDocStyle = gEnv->GetValue("Root.Html.DescriptionStyle", "");
-
-   fClasses.SetOwner();
-   fModules.SetOwner();
+   fPathInfo.fOutputDir = gEnv->GetValue("Root.Html.OutputDir", "htmldoc");
+
+   fLinkInfo.fXwho = gEnv->GetValue("Root.Html.XWho", "http://consult.cern.ch/xwho/people?");
+   fLinkInfo.fROOTURL = gEnv->GetValue("Root.Html.Root", "http://root.cern.ch/root/html");
+   fDocSyntax.fClassDocTag = gEnv->GetValue("Root.Html.Description", "//____________________");
+   fDocSyntax.fAuthorTag = gEnv->GetValue("Root.Html.Author", "// Author:");
+   fDocSyntax.fLastUpdateTag = gEnv->GetValue("Root.Html.LastUpdate", "// @(#)");
+   fDocSyntax.fCopyrightTag = gEnv->GetValue("Root.Html.Copyright", "* Copyright");
+   fOutputStyle.fHeader = gEnv->GetValue("Root.Html.Header", "");
+   fOutputStyle.fFooter = gEnv->GetValue("Root.Html.Footer", "");
+   fLinkInfo.fHomepage = gEnv->GetValue("Root.Html.Homepage", "");
+   fLinkInfo.fSearchStemURL = gEnv->GetValue("Root.Html.Search", "");
+   fLinkInfo.fSearchEngine = gEnv->GetValue("Root.Html.SearchEngine", "");
+   fLinkInfo.fViewCVS = gEnv->GetValue("Root.Html.ViewCVS", "");
+   fOutputStyle.fCharset = gEnv->GetValue("Root.Html.Charset", "ISO-8859-1");
+   fDocSyntax.fDocStyle = gEnv->GetValue("Root.Html.DescriptionStyle", "");
+
+   fDocEntityInfo.fClasses.SetOwner();
+   fDocEntityInfo.fModules.SetOwner();
    // insert html object in the list of special ROOT objects
    if (!gHtml) {
       gHtml = this;
@@ -567,12 +1093,16 @@ THtml::~THtml()
 {
 // Default destructor
 
-   fClasses.Clear();
-   fModules.Clear();
+   fDocEntityInfo.fClasses.Clear();
+   fDocEntityInfo.fModules.Clear();
    if (gHtml == this) {
       gROOT->GetListOfSpecials()->Remove(gHtml);
       gHtml = 0;
    }
+   delete fPathDef;
+   delete fModuleDef;
+   delete fFileDef;
+   delete fLocalFiles;
 }
 
 //______________________________________________________________________________
@@ -589,8 +1119,8 @@ void THtml::AddMacroPath(const char* path)
 #else
       ':';
 #endif
-   fMacroPath += pathDelimiter;
-   fMacroPath += path;
+   fPathInfo.fMacroPath += pathDelimiter;
+   fPathInfo.fMacroPath += path;
 }
 
 
@@ -603,31 +1133,71 @@ void THtml::CreateAuxiliaryFiles() const
    CopyFileFromEtcDir("HELP.html");
 }
 
+//______________________________________________________________________________
+const THtml::TModuleDefinition& THtml::GetModuleDefinition() const
+{
+   // Return the TModuleDefinition (or derived) object as set by
+   // SetModuleDefinition(); create and return a TModuleDefinition object
+   // if none was set.
+   if (!fModuleDef) {
+      fModuleDef = new TModuleDefinition();
+      fModuleDef->SetOwner(const_cast<THtml*>(this));
+   }
+   return *fModuleDef;
+}
+
+//______________________________________________________________________________
+const THtml::TFileDefinition& THtml::GetFileDefinition() const
+{
+   // Return the TFileDefinition (or derived) object as set by
+   // SetFileDefinition(); create and return a TFileDefinition object
+   // if none was set.
+   if (!fFileDef) {
+      fFileDef = new TFileDefinition();
+      fFileDef->SetOwner(const_cast<THtml*>(this));
+   }
+   return *fFileDef;
+}
+
+//______________________________________________________________________________
+const THtml::TPathDefinition& THtml::GetPathDefinition() const
+{
+   // Return the TModuleDefinition (or derived) object as set by
+   // SetModuleDefinition(); create and return a TModuleDefinition object
+   // if none was set.
+   if (!fPathDef) {
+      fPathDef = new TPathDefinition();
+      fPathDef->SetOwner(const_cast<THtml*>(this));
+   }
+   return *fPathDef;
+}
+
+
 //______________________________________________________________________________
 const char* THtml::GetEtcDir()
 {
 // Get the directory containing THtml's auxiliary files ($ROOTSYS/etc/html)
 
-   if (fEtcDir.Length())
-      return fEtcDir;
+   if (fPathInfo.fEtcDir.Length())
+      return fPathInfo.fEtcDir;
 
    R__LOCKGUARD(GetMakeClassMutex());
 
-   fEtcDir = "html";
+   fPathInfo.fEtcDir = "html";
 
 #ifdef ROOTETCDIR
-   gSystem->PrependPathName(ROOTETCDIR, fEtcDir);
+   gSystem->PrependPathName(ROOTETCDIR, fPathInfo.fEtcDir);
 #else
-   gSystem->PrependPathName("etc", fEtcDir);
+   gSystem->PrependPathName("etc", fPathInfo.fEtcDir);
 # ifdef ROOTPREFIX
-   gSystem->PrependPathName(ROOTPREFIX, fEtcDir);
+   gSystem->PrependPathName(ROOTPREFIX, fPathInfo.fEtcDir);
 # else
    if (getenv("ROOTSYS"))
-      gSystem->PrependPathName(getenv("ROOTSYS"), fEtcDir);
+      gSystem->PrependPathName(getenv("ROOTSYS"), fPathInfo.fEtcDir);
 # endif
 #endif
 
-   return fEtcDir;
+   return fPathInfo.fEtcDir;
 }
 
 
@@ -649,7 +1219,7 @@ TClassDocInfo *THtml::GetNextClass()
       fThreadedClassIter = 0;
    }
 
-   fCounter.Form("%5d", fClasses.GetSize() - fThreadedClassCount++);
+   fCounter.Form("%5d", fDocEntityInfo.fClasses.GetSize() - fThreadedClassCount++);
 
    return classinfo;
 }
@@ -665,11 +1235,11 @@ const char* THtml::GetURL(const char* lib /*=0*/) const
    R__LOCKGUARD(GetMakeClassMutex());
 
    if (lib && strlen(lib)) {
-      std::map<std::string, TString>::const_iterator iUrl = fLibURLs.find(lib);
-      if (iUrl != fLibURLs.end()) return iUrl->second;
-      return gEnv->GetValue(TString("Root.Html.") + lib, fROOTURL);
+      std::map<std::string, TString>::const_iterator iUrl = fLinkInfo.fLibURLs.find(lib);
+      if (iUrl != fLinkInfo.fLibURLs.end()) return iUrl->second;
+      return gEnv->GetValue(TString("Root.Html.") + lib, fLinkInfo.fROOTURL);
    }
-   return fROOTURL;
+   return fLinkInfo.fROOTURL;
 }
 
 //______________________________________________________________________________
@@ -678,27 +1248,40 @@ Bool_t THtml::HaveDot()
    // Check whether dot is available in $PATH or in the directory set 
    // by SetDotPath()
 
-   if (fFoundDot != -1) 
-      return (Bool_t)fFoundDot;
+   if (fPathInfo.fFoundDot != -1) 
+      return (Bool_t)fPathInfo.fFoundDot;
 
    R__LOCKGUARD(GetMakeClassMutex());
 
    Info("HaveDot", "Checking for Graphviz (dot)...");
    TString runDot("dot");
-   if (fDotDir.Length())
-      gSystem->PrependPathName(fDotDir, runDot);
+   if (fPathInfo.fDotDir.Length())
+      gSystem->PrependPathName(fPathInfo.fDotDir, runDot);
    runDot += " -V";
    if (gDebug > 3)
       Info("HaveDot", "Running: %s", runDot.Data());
    if (gSystem->Exec(runDot)) {
-      fFoundDot = 0;
+      fPathInfo.fFoundDot = TPathInfo::kDotNotFound;
       return kFALSE;
    }
-   fFoundDot = 1;
+   fPathInfo.fFoundDot = TPathInfo::kDotFound;
    return kTRUE;
 
 }
 
+//______________________________________________________________________________
+void THtml::HelperDeleted(THtml::THelperBase* who)
+{
+   // Inform the THtml object that one of its helper objects was deleted.
+   // Called by THtml::HelperBase::~HelperBase().
+
+   THelperBase* helpers[3] = {fPathDef, fModuleDef, fFileDef};
+   for (int i = 0; who && i < 3; ++i)
+      if (who == helpers[i])
+         helpers[i] = who = 0;
+}
+
+
 //______________________________________________________________________________
 void THtml::Convert(const char *filename, const char *title,
                     const char *dirname /*= ""*/, const char *relpath /*= "../"*/)
@@ -723,8 +1306,8 @@ void THtml::Convert(const char *filename, const char *title,
 
    // if it's not defined, make the "examples" as a default directory
    if (!*dirname) {
-      gSystem->ExpandPathName(fOutputDir);
-      dir = gSystem->ConcatFileName(fOutputDir, "examples");
+      gSystem->ExpandPathName(fPathInfo.fOutputDir);
+      dir = gSystem->ConcatFileName(fPathInfo.fOutputDir, "examples");
    } else
       dir = dirname;
 
@@ -734,7 +1317,7 @@ void THtml::Convert(const char *filename, const char *title,
 
    // find a file
    char *realFilename =
-       gSystem->Which(fSourceDir, filename, kReadPermission);
+       gSystem->Which(fPathInfo.fInputPath, filename, kReadPermission);
 
    if (!realFilename) {
       Error("Convert", "Can't find file '%s' !", filename);
@@ -759,7 +1342,7 @@ void THtml::Convert(const char *filename, const char *title,
       return;
    }
    char *tmp1 =
-       gSystem->ConcatFileName(dir, GetFileName(filename));
+       gSystem->ConcatFileName(dir, gSystem->BaseName(filename));
 
    TDocOutput output(*this);
    output.Convert(sourceFile, tmp1, title, relpath);
@@ -769,66 +1352,26 @@ void THtml::Convert(const char *filename, const char *title,
    tmp1 = 0;
 }
 
-
-//______________________________________________________________________________
-void THtml::GetModuleName(TString& modulename, const char* filename) const 
-{
-   // Returns the module a class with filename belongs to.
-   // For ROOT, this is determined by MODULE/src/*.cxx or MODULE/inc/*.h. 
-   // Math/GenVector (MATHCORE) and Math/Matrix (SMATRIX) get special
-   // treatment.
-   // All classes not fitting into this layout are assigned to the
-   // module USER.
-
-   size_t offset = 0;
-   if (filename[0] == '.' && (filename[1] == '/' || filename[1] == '\\'))
-      offset = 2;
-
-   modulename = filename + offset;
-   const char* posSlash = strchr(filename + offset, '/');
-   const char *srcdir = 0;
-   if (posSlash) {
-      // for new ROOT install the impl file name has the form: base/src/TROOT.cxx
-      srcdir = strstr(posSlash, "/src/");
-      
-      // if impl is unset, check for decl and see if it matches
-      // format "base/inc/TROOT.h" - in which case it's not a USER
-      // class, but a BASE class.
-      if (!srcdir) srcdir=strstr(posSlash, "/inc/");
-   } else srcdir = 0;
-
-   if (srcdir && srcdir == posSlash) {
-      modulename.Remove(srcdir - (filename + offset), modulename.Length());
-      modulename.ToUpper();
-   } else {
-      if (posSlash && !strncmp(posSlash,"/Math/GenVector/", 16))
-         modulename = "MATHCORE";
-      else if (posSlash && !strncmp(posSlash,"/Math/Matrix", 12))
-         modulename = "SMATRIX";
-      else
-         modulename = "USER";
-   }
-}
-
 //______________________________________________________________________________
 void  THtml::GetModuleNameForClass(TString& module, TClass* cl) const
 {
    // Return the module name for a given class.
-   // Use the cached information from fClasses.
+   // Use the cached information from fDocEntityInfo.fClasses.
 
    module = "(UNKNOWN)";
-   TClassDocInfo* cdi = (TClassDocInfo*)fClasses.FindObject(cl->GetName());
+   TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(cl->GetName());
    if (!cdi || !cdi->GetModule())
       return;
    module = cdi->GetModule()->GetName();
 }
 
+
 //______________________________________________________________________________
 void THtml::CreateListOfClasses(const char* filter)
 {
 // Create the list of all known classes
 
-   if (fClasses.GetSize() && fClassFilter == filter)
+   if (fDocEntityInfo.fClasses.GetSize() && fDocEntityInfo.fClassFilter == filter)
       return;
 
    Info("CreateListOfClasses", "Initializing - this might take a while...");
@@ -836,10 +1379,10 @@ void THtml::CreateListOfClasses(const char* filter)
    Int_t totalNumberOfClasses = gClassTable->Classes();
 
    // allocate memory
-   fClasses.Clear();
-   fModules.Clear();
+   fDocEntityInfo.fClasses.Clear();
+   fDocEntityInfo.fModules.Clear();
 
-   fClassFilter = filter;
+   fDocEntityInfo.fClassFilter = filter;
 
    // start from begining
    gClassTable->Init();
@@ -861,157 +1404,106 @@ void THtml::CreateListOfClasses(const char* filter)
       TClass *classPtr = TClass::GetClass((const char *) cname, kTRUE);
       if (!classPtr) continue;
 
-      TString srcGuess;
-      TString hdrGuess;
-      const char *impname=GetImplFileName(classPtr);
-      if (!impname || !impname[0]) {
-         impname = GetDeclFileName(classPtr);
-         if (impname && !impname[0]) {
-            // no impl, no decl - might be a cintex dict
-            // use namespace to decrypt path.
-            TString impnameString(cname);
-            TObjArray* arrScopes = impnameString.Tokenize("::");
-
-            // for A::B::C, we assume B to be the module, 
-            // b/inc/B/C.h the header, and b/src/C.cxx the source.
-            TIter iScope(arrScopes, kIterBackward);
-            TObjString *osFile   = (TObjString*)iScope();
-            TObjString *osModule = 0;
-            if (osFile) osModule = (TObjString*)iScope();
-
-            if (osModule) {
-               hdrGuess = osModule->String();
-               hdrGuess.ToLower();
-               hdrGuess += "/inc/";
-               hdrGuess += osModule->String();
-               hdrGuess += "/";
-               hdrGuess += osFile->String();
-               hdrGuess += ".h";
-               char* realFile = gSystem->Which(fSourceDir, hdrGuess, kReadPermission);
-               if (realFile) {
-                  delete realFile;
-                  fGuessedDeclFileNames[classPtr] = hdrGuess.Data();
-                  impname = hdrGuess.Data();
-                  
-                  // only check for source if we've found the header!
-                  srcGuess = osModule->String();
-                  srcGuess.ToLower();
-                  srcGuess += "/src/";
-                  srcGuess += osFile->String();
-                  srcGuess += ".cxx";
-                  realFile = gSystem->Which(fSourceDir, srcGuess, kReadPermission);
-                  if (realFile) {
-                     delete realFile;
-                     fGuessedImplFileNames[classPtr] = srcGuess.Data();
-                     impname = srcGuess.Data();
-                  }
-               }
-            }
-            delete arrScopes;
+      // we cannot document namespaces yet - and TMath is really a class
+      if (IsNamespace(classPtr) && s != "TMath")
+         continue;
+
+      TString hdr;
+      TString hdrFS;
+      TString src;
+      TString srcFS;
+      TString htmlfilename;
+
+      TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cname);
+      if (cdi) {
+         hdr = cdi->GetDeclFileName();
+         hdrFS = cdi->GetDeclFileSysName();
+         src = cdi->GetImplFileName();
+         srcFS = cdi->GetImplFileSysName();
+         htmlfilename = cdi->GetHtmlFileName();
+      }
+
+      if (!hdrFS.Length()) {
+         if (!GetFileDefinition().GetDeclFileName(classPtr, hdr, hdrFS)) {
+            // we don't even know where the class is defined;
+            // just skip
+            if (!classPtr->GetDeclFileName() || !strstr(classPtr->GetDeclFileName(),"prec_stl/"))
+               Warning("CreateListOfClasses",
+                  "Cannot determine declaration file name for %s!", cname);
+            continue;
          }
       }
 
-      if (!impname || !impname[0]) {
-         cout << "WARNING class " << cname <<
-            " has no implementation file name !" << endl;
-         continue;
+      Bool_t haveSource = (srcFS.Length());
+      if (!haveSource)
+         haveSource = GetFileDefinition().GetImplFileName(classPtr, src, srcFS);
+
+      if (!haveSource && gDebug > 3) {
+         Info("CreateListOfClasses",
+            "Cannot determine implementation file name for %s!", cname);
       }
 
-      if (strstr(impname,"prec_stl/")) continue;
-      //if (strstr(cname, "ROOT::") && !strstr(cname,"Math::")
-      //    && !strstr(cname,"Reflex::") && !strstr(cname,"Cintex::"))
-      //   continue;
+      if (!htmlfilename.Length())
+         GetHtmlFileName(classPtr, htmlfilename);
+
+      if (!cdi) {
+         cdi = new TClassDocInfo(classPtr, htmlfilename, hdrFS, srcFS, hdr, src);
+         fDocEntityInfo.fClasses.Add(cdi);
+      } else {
+         cdi->SetDeclFileName(hdr);
+         cdi->SetImplFileName(src);
+         cdi->SetDeclFileSysName(hdrFS);
+         cdi->SetImplFileSysName(srcFS);
+         cdi->SetHtmlFileName(htmlfilename);
+      }
 
-      TString htmlfilename;
-      GetHtmlFileName(classPtr, htmlfilename);
-      TClassDocInfo* cdi = new TClassDocInfo(classPtr, htmlfilename.Data());
       cdi->SetSelected(!(filter && filter[0] && strcmp(filter,"*") && s.Index(re) == kNPOS));
-      char* realFile = gSystem->Which(fSourceDir, impname, kReadPermission); // delete at end of block
-      cdi->SetHaveSource((realFile));
-
-      fClasses.Add(cdi);
 
       TString modulename;
-      GetModuleName(modulename, impname);
+      GetModuleDefinition().GetModule(classPtr, modulename);
       if (!modulename.Length() || modulename == "USER") 
          GetModuleNameForClass(modulename, classPtr);
-      if (modulename == "(UNKNOWN)") modulename = "USER";
-      if (!modulename.Length() || modulename == "USER") {
-         modulename = classPtr->GetSharedLibs();
-         Ssiz_t pos = modulename.Index(' ');
-         if (pos != kNPOS)
-            modulename.Remove(pos, modulename.Length());
-         if (modulename.BeginsWith("lib"))
-            modulename.Remove(0,3);
-         pos = modulename.Index('.');
-         if (pos != kNPOS)
-            modulename.Remove(pos, modulename.Length());
-         modulename.ToUpper();
-      }
-      if (!modulename.Length()) {
-         if (strstr(cname, "::SMatrix<") || strstr(cname, "::SVector<"))
-            modulename = "SMATRIX";
-         else if (strstr(cname, "::TArrayProxy<") || strstr(cname, "::TClaArrayProxy<")
-                  || strstr(cname, "::TImpProxy<") || strstr(cname, "::TClaImpProxy<"))
-            modulename = "TREEPLAYER";
-      }
-      if (!modulename.Length())
-         modulename = "USER";
       
-      TModuleDocInfo* module = (TModuleDocInfo*) fModules.FindObject(modulename);
+      TModuleDocInfo* module = (TModuleDocInfo*) fDocEntityInfo.fModules.FindObject(modulename);
       if (!module) {
-         module = new TModuleDocInfo(modulename);
-
-         TString moduledir;
-         if (modulename == "MATHCORE")
-            moduledir = "mathcore/src";
-         else if (modulename == "MATHMORE")
-            moduledir = "mathmore/src";
-         else if (modulename == "REFLEX")
-            moduledir = "reflex/src";
-         else if (modulename == "TMVA")
-            moduledir = "tmva/src";
-         else if (modulename == "SMATRIX")
-            moduledir = "smatrix/src";
-         if (moduledir.Length())
-            module->SetSourceDir(moduledir);
-
-         module->SetSelected(kFALSE);
-         fModules.Add(module);
-      }
-      if (module) {
-         if (!strcmp(module->GetName(), "REFLEX")
-             // take class doc from header, so ignore sources:
-             //|| !strcmp(module->GetName(), "MATHCORE")
-             //|| !strcmp(module->GetName(), "MATHMORE")
-             ) {
-            TString srcFile = gSystem->BaseName(impname);
-            srcFile.ReplaceAll(".h", ".cxx");
-            gSystem->PrependPathName(module->GetSourceDir(), srcFile);
-            if (!gSystem->AccessPathName(srcFile))
-               SetImplFileName(classPtr, srcFile);
+         bool moduleSelected = cdi->IsSelected();
+
+         TString parentModuleName(gSystem->DirName(modulename));
+         TModuleDocInfo* super = 0;
+         if (parentModuleName.Length() && parentModuleName != ".") {
+            super = (TModuleDocInfo*) fDocEntityInfo.fModules.FindObject(parentModuleName);
+            if (!super) {
+               // create parents:
+               TString token;
+               Ssiz_t pos = 0;
+               while (parentModuleName.Tokenize(token, pos, "/")) {
+                  if (!token.Length() || token == ".") continue;
+                  super = new TModuleDocInfo(token, super);
+                  super->SetSelected(moduleSelected);
+                  fDocEntityInfo.fModules.Add(super);
+               }
+            }
          }
+         module = new TModuleDocInfo(modulename, super);
+         module->SetSelected(moduleSelected);
+         fDocEntityInfo.fModules.Add(module);
+      }
 
+      if (module) {
          module->AddClass(cdi);
          cdi->SetModule(module);
          if (cdi->HaveSource() && cdi->IsSelected())
             module->SetSelected();
-         if (cdi->HaveSource() && !module->GetSourceDir().Length()) {
-            TString realfile(GetImplFileName(classPtr));
-            if (gSystem->FindFile(fSourceDir, realfile, kReadPermission))
-               module->SetSourceDir(gSystem->DirName(realfile));
-         }
       }
-      delete[] realFile;
    }
 
-   fClasses.Sort();
-   fModules.Sort();
+   fDocEntityInfo.fClasses.Sort();
+   fDocEntityInfo.fModules.Sort();
 
    if (fProductName == "(UNKNOWN PRODUCT)" 
-      && fModules.FindObject("BASE") 
-      && fModules.FindObject("CONT") 
-      && fModules.FindObject("RINT")
+      && fDocEntityInfo.fModules.FindObject("core/base") 
+      && fDocEntityInfo.fModules.FindObject("core/cont") 
+      && fDocEntityInfo.fModules.FindObject("core/rint")
       && gProgName && strstr(gProgName, "root"))
       // if we have these modules we're probably building the root doc
       fProductName = "ROOT";
@@ -1090,7 +1582,7 @@ void THtml::GetDerivedClasses(TClass* cl, std::map<TClass*, Int_t>& derived) con
    // fill derived with all classes inheriting from cl and their inheritance 
    // distance to cl
 
-   TIter iClass(&fClasses);
+   TIter iClass(&fDocEntityInfo.fClasses);
    TClassDocInfo* cdi = 0;
    while ((cdi = (TClassDocInfo*) iClass())) {
       TClass* candidate = cdi->GetClass();
@@ -1116,51 +1608,6 @@ void THtml::GetDerivedClasses(TClass* cl, std::map<TClass*, Int_t>& derived) con
    }
 }
 
-//______________________________________________________________________________
-const char *THtml::GetFileName(const char *filename) const
-{
-// It discards any directory information inside filename
-//
-//
-//  Input: filename - pointer to the file name
-//
-// Output: pointer to the string containing just a file name
-//         without any other directory information, i.e.
-//         '/usr/root/test.dat' will return 'test.dat'
-//
-
-   if (!filename || !filename[0]) return "";
-   return gSystem->BaseName(filename);
-}
-
-//______________________________________________________________________________
-void THtml::GetSourceFileName(TString& filename)
-{
-   // Find the source file. If filename contains a path it will be used
-   // together with the possible source prefix. If not found we try
-   // old algorithm, by stripping off the path and trying to find it in the
-   // specified source search path.
-
-   TString found(filename);
-
-   if (strchr(filename, '/') 
-#ifdef WIN32
-   || strchr(filename, '\\')
-#endif
-   ){
-      TString found(fSourcePrefix);
-      if (found.Length())
-         gSystem->PrependPathName(found, filename);
-      gSystem->FindFile(fSourceDir, filename, kReadPermission);
-      if (filename.Length())
-         return;
-   }
-
-   filename = GetFileName(filename);
-   if (filename.Length())
-      gSystem->FindFile(fSourceDir, filename, kReadPermission);
-}
-
 //______________________________________________________________________________
 void THtml::GetHtmlFileName(TClass * classPtr, TString& filename) const
 {
@@ -1175,13 +1622,13 @@ void THtml::GetHtmlFileName(TClass * classPtr, TString& filename) const
    filename.Remove(0);
    if (!classPtr) return;
 
-   const char* cFilename = GetImplFileName(classPtr);
-   if (!cFilename || !cFilename[0])
-      cFilename = GetDeclFileName(classPtr);
+   TString cFilename;
+   if (!GetImplFileName(classPtr, kFALSE, cFilename))
+      GetDeclFileName(classPtr, kFALSE, cFilename);
 
    // classes without Impl/DeclFileName don't have docs,
    // and classes without docs don't have output file names
-   if (!cFilename || !cFilename[0])
+   if (!cFilename.Length())
       return;
 
    TString libName;
@@ -1213,7 +1660,7 @@ void THtml::GetHtmlFileName(TClass * classPtr, TString& filename) const
    filename = cFilename;
    TString htmlFileName;
    if (!filename.Length() ||
-      !gSystem->FindFile(fSourceDir, filename, kReadPermission)) {
+      !gSystem->FindFile(fPathInfo.fInputPath, filename, kReadPermission)) {
       htmlFileName = GetURL(libName);
    } else
       htmlFileName = "./";
@@ -1235,7 +1682,7 @@ const char* THtml::GetHtmlFileName(const char* classname) const
 {
    // Get the html file name for a class named classname.
    // Returns 0 if the class is not documented.
-   TClassDocInfo* cdi = (TClassDocInfo*) fClasses.FindObject(classname);
+   TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(classname);
    if (cdi)
       return cdi->GetHtmlFileName();
    return 0;
@@ -1256,7 +1703,7 @@ TClass *THtml::GetClass(const char *name1) const
       if (ret) return 0;
    }
 
-   TClassDocInfo* cdi = (TClassDocInfo*)fClasses.FindObject(name1);
+   TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(name1);
    if (!cdi) return 0;
    TClass *cl=cdi->GetClass();
    // hack to get rid of prec_stl types
@@ -1266,31 +1713,79 @@ TClass *THtml::GetClass(const char *name1) const
        strstr(GetDeclFileName(cl),"prec_stl/"))
       cl = 0;
    */
-   if (cl && GetDeclFileName(cl) && GetDeclFileName(cl)[0])
+   TString declFileName;
+   if (cl && GetDeclFileName(cl, kFALSE, declFileName))
       return cl;
    return 0;
 }
 
 //______________________________________________________________________________
-const char* THtml::GetDeclFileName(TClass * cl) const
+bool THtml::GetDeclFileName(TClass * cl, Bool_t filesys, TString& out_name) const
 {
-   // Return declaration file name
-
-   R__LOCKGUARD(GetMakeClassMutex());
-   std::map<TClass*,std::string>::const_iterator iClDecl = fGuessedDeclFileNames.find(cl);
-   if (iClDecl == fGuessedDeclFileNames.end()) return cl->GetDeclFileName();
-   return iClDecl->second.c_str();
+   // Return declaration file name; return the full path if filesys is true.
+   return GetDeclImplFileName(cl, filesys, true, out_name);
 }
 
 //______________________________________________________________________________
-const char* THtml::GetImplFileName(TClass * cl) const
+bool THtml::GetImplFileName(TClass * cl, Bool_t filesys, TString& out_name) const
 {
    // Return implementation file name
+   return GetDeclImplFileName(cl, filesys, false, out_name);
+}
+
+//______________________________________________________________________________
+bool THtml::GetDeclImplFileName(TClass * cl, bool filesys, bool decl, TString& out_name) const
+{
+   // Combined implementation for GetDeclFileName(), GetImplFileName():
+   // Return declaration / implementation file name (depending on decl);
+   // return the full path if filesys is true.
+
+   out_name = "";
 
    R__LOCKGUARD(GetMakeClassMutex());
-   std::map<TClass*,std::string>::const_iterator iClImpl = fGuessedImplFileNames.find(cl);
-   if (iClImpl == fGuessedImplFileNames.end()) return cl->GetImplFileName();
-   return iClImpl->second.c_str();
+   TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
+   // whether we need to determine the fil name
+   bool determine = (!cdi); // no cdi
+   if (!determine) determine |=  decl &&  filesys && !cdi->GetDeclFileSysName()[0];
+   if (!determine) determine |=  decl && !filesys && !cdi->GetDeclFileName()[0];
+   if (!determine) determine |= !decl &&  filesys && !cdi->GetImplFileSysName()[0];
+   if (!determine) determine |= !decl && !filesys && !cdi->GetImplFileName()[0];
+   if (determine) {
+      TString name;
+      TString sysname;
+      if (decl) {
+         if (!GetFileDefinition().GetDeclFileName(cl, name, sysname))
+            return false;
+      } else {
+         if (!GetFileDefinition().GetImplFileName(cl, name, sysname))
+            return false;
+      }
+      if (cdi) {
+         if (decl) {
+            if (!cdi->GetDeclFileName() || !cdi->GetDeclFileName()[0])
+               cdi->SetDeclFileName(name);
+            if (!cdi->GetDeclFileSysName() || !cdi->GetDeclFileSysName()[0])
+               cdi->SetDeclFileSysName(sysname);
+         } else {
+            if (!cdi->GetImplFileName() || !cdi->GetImplFileName()[0])
+               cdi->SetImplFileName(name);
+            if (!cdi->GetImplFileSysName() || !cdi->GetImplFileSysName()[0])
+               cdi->SetImplFileSysName(sysname);
+         }
+      }
+
+      if (filesys) out_name = sysname;
+      else         out_name = name;
+      return true;
+   }
+   if (filesys) {
+      if (decl) out_name = cdi->GetDeclFileSysName();
+      else      out_name = cdi->GetImplFileSysName();
+   } else {
+      if (decl) out_name = cdi->GetDeclFileName();
+      else      out_name = cdi->GetImplFileName();
+   }
+   return true;
 }
 
 //______________________________________________________________________________
@@ -1302,19 +1797,19 @@ const TString& THtml::GetOutputDir(Bool_t createDir /*= kTRUE*/) const
    if (createDir) {
       R__LOCKGUARD(GetMakeClassMutex());
 
-      gSystem->ExpandPathName(const_cast<THtml*>(this)->fOutputDir);
+      gSystem->ExpandPathName(const_cast<THtml*>(this)->fPathInfo.fOutputDir);
       Long64_t sSize;
       Long_t sId, sFlags, sModtime;
-      Int_t st = gSystem->GetPathInfo(fOutputDir, &sId, &sSize, &sFlags, &sModtime);
+      Int_t st = gSystem->GetPathInfo(fPathInfo.fOutputDir, &sId, &sSize, &sFlags, &sModtime);
       if (st || !(sFlags & 2)) {
          if (st == 0)
             Error("GetOutputDir", "output directory %s is an existing file",
-                  fOutputDir.Data());
-         else if (gSystem->MakeDirectory(fOutputDir) == -1)
-            Error("GetOutputDir", "output directory %s does not exist and can't create it", fOutputDir.Data());
+                  fPathInfo.fOutputDir.Data());
+         else if (gSystem->MakeDirectory(fPathInfo.fOutputDir) == -1)
+            Error("GetOutputDir", "output directory %s does not exist and can't create it", fPathInfo.fOutputDir.Data());
       }
    }
-   return fOutputDir;
+   return fPathInfo.fOutputDir;
 }
 
 //______________________________________________________________________________
@@ -1393,13 +1888,13 @@ void THtml::MakeAll(Bool_t force, const char *filter, int numthreads /*= -1*/)
    if (numthreads == 1) {
       // CreateListOfClasses(filter); already done by MakeIndex
       TClassDocInfo* classinfo = 0;
-      TIter iClassInfo(&fClasses);
+      TIter iClassInfo(&fDocEntityInfo.fClasses);
       UInt_t count = 0;
 
       while ((classinfo = (TClassDocInfo*)iClassInfo())) {
          if (!classinfo->IsSelected()) 
             continue;
-         fCounter.Form("%5d", fClasses.GetSize() - count++);
+         fCounter.Form("%5d", fDocEntityInfo.fClasses.GetSize() - count++);
          MakeClass(classinfo, force);
       }
    } else {
@@ -1411,7 +1906,7 @@ void THtml::MakeAll(Bool_t force, const char *filter, int numthreads /*= -1*/)
             numthreads = 2;
       }
       fThreadedClassCount = 0;
-      fThreadedClassIter = new TIter(&fClasses);
+      fThreadedClassIter = new TIter(&fDocEntityInfo.fClasses);
       THtmlThreadInfo hti(this, force);
       if (!fMakeClassMutex && gGlobalMutex) {
          gGlobalMutex->Lock();
@@ -1455,7 +1950,7 @@ void THtml::MakeClass(const char *className, Bool_t force)
 //
    CreateListOfClasses("*");
 
-   TClassDocInfo* cdi = (TClassDocInfo*)fClasses.FindObject(className);
+   TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(className);
    if (!cdi) {
       if (!TClassEdit::IsStdClass(className)) // stl classes won't be available, so no warning
          Error("MakeClass", "Unknown class '%s'!", className);
@@ -1473,7 +1968,7 @@ void THtml::MakeClass(void *cdi_void, Bool_t force)
 //
 // Input: cdi - doc info for class to process
 //
-   if (!fClasses.GetSize())
+   if (!fDocEntityInfo.fClasses.GetSize())
       CreateListOfClasses("*");
 
    TClassDocInfo* cdi = (TClassDocInfo*) cdi_void;
@@ -1562,23 +2057,55 @@ void THtml::MakeTree(const char *className, Bool_t force)
 }
 
 //______________________________________________________________________________
-void THtml::SetSourcePrefix(const char *prefix)
+void THtml::SetFoundDot(Bool_t found) {
+   // Set whether "dot" (a GraphViz utility) is avaliable
+   if (found) fPathInfo.fFoundDot = TPathInfo::kDotFound;
+   else fPathInfo.fFoundDot = TPathInfo::kDotNotFound;
+}
+
+//______________________________________________________________________________
+void THtml::SetLocalFiles() const
 {
-   // Sets the source prefix, see GetSourceFileName().
-   // Also resets the class structure, in case new files can
-   // be found after this call.
+   // Fill the files available in the file system below fPathInfo.fInputPath
+   if (fLocalFiles) delete fLocalFiles;
+   fLocalFiles = new TFileSysDB(fPathInfo.fInputPath, fPathInfo.fIgnorePath + "|(\\b" + GetOutputDir(kFALSE) + "\\b)" , 6);
+}
+
+//______________________________________________________________________________
+void THtml::SetModuleDefinition(const TModuleDefinition& md)
+{
+   // Set the module defining object to be used; can also be a user derived
+   // object (a la traits).
+   delete fModuleDef;
+   fModuleDef = (TModuleDefinition*) md.Clone();
+   fModuleDef->SetOwner(const_cast<THtml*>(this));
+}
 
-   fSourcePrefix = prefix;
 
-   // reset class table
-   fClasses.Clear();
-   fModules.Clear();
-   fGuessedDeclFileNames.clear();
-   fGuessedImplFileNames.clear();
+//______________________________________________________________________________
+void THtml::SetFileDefinition(const TFileDefinition& md)
+{
+   // Set the file defining object to be used; can also be a user derived
+   // object (a la traits).
+   delete fFileDef;
+   fFileDef = (TFileDefinition*) md.Clone();
+   fFileDef->SetOwner(const_cast<THtml*>(this));
 }
 
+
 //______________________________________________________________________________
-void THtml::SetSourceDir(const char *dir)
+void THtml::SetPathDefinition(const TPathDefinition& md)
+{
+   // Set the path defining object to be used; can also be a user derived
+   // object (a la traits).
+   delete fPathDef;
+   fPathDef = (TPathDefinition*) md.Clone();
+   fPathDef->SetOwner(const_cast<THtml*>(this));
+}
+
+
+//______________________________________________________________________________
+void THtml::SetInputDir(const char *dir)
 {
    // Set the directory containing the source files.
    // The source file for a class MyClass will be searched
@@ -1588,25 +2115,33 @@ void THtml::SetSourceDir(const char *dir)
    // Also resets the class structure, in case new files can
    // be found after this call.
 
-   fSourceDir = dir;
+   fPathInfo.fInputPath = dir;
 
    // reset class table
-   fClasses.Clear();
-   fModules.Clear();
-   fGuessedDeclFileNames.clear();
-   fGuessedImplFileNames.clear();
+   fDocEntityInfo.fClasses.Clear();
+   fDocEntityInfo.fModules.Clear();
 }
 
 //______________________________________________________________________________
 void THtml::SetDeclFileName(TClass* cl, const char* filename)
 {
    // Explicitly set a decl file name for TClass cl.
-   fGuessedDeclFileNames[cl] = filename;
+   TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
+   if (!cdi) {
+      cdi = new TClassDocInfo(cl, "" /*html*/, "" /*fsdecl*/, "" /*fsimpl*/, filename);
+      fDocEntityInfo.fClasses.Add(cdi);
+   } else
+      cdi->SetDeclFileName(filename);
 }
 
 //______________________________________________________________________________
 void THtml::SetImplFileName(TClass* cl, const char* filename)
 {
    // Explicitly set a impl file name for TClass cl.
-   fGuessedImplFileNames[cl] = filename;
+   TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
+   if (!cdi) {
+      cdi = new TClassDocInfo(cl, "" /*html*/, "" /*fsdecl*/, "" /*fsimpl*/, 0 /*decl*/, filename);
+      fDocEntityInfo.fClasses.Add(cdi);
+   } else
+      cdi->SetImplFileName(filename);
 }