From 9e34481c1a67ca9ffb6a83f9723f23f6cf3982c7 Mon Sep 17 00:00:00 2001
From: dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>
Date: Sun, 14 Sep 2008 19:14:55 +0000
Subject: Release-1.5.6-20080914

---
 INSTALL                |   4 +-
 README                 |   4 +-
 configure              |   2 +-
 doc/config.doc         |  19 +++----
 doc/customize.doc      |  15 ++++-
 doc/doxygen_manual.tex |   6 +-
 src/code.l             |  50 +++++++++++-----
 src/commentscan.l      |  16 +++---
 src/config.l           | 125 +++++++++++++++++++---------------------
 src/cppvalue.cpp       |  10 +++-
 src/declinfo.l         |   2 +-
 src/defargs.l          |  18 +++++-
 src/docparser.cpp      |  18 +++---
 src/doctokenizer.l     |  11 ++--
 src/doxygen.cpp        |  76 +++++++++++++++----------
 src/doxygen.h          |   2 +-
 src/htmlgen.cpp        |  12 +++-
 src/htmlgen.h          |   1 +
 src/htmlhelp.cpp       |   5 ++
 src/layout.cpp         |  29 ++++++++--
 src/layout_default.h   |  16 +++---
 src/layout_default.xml |  16 +++---
 src/memberlist.cpp     |  19 ++++++-
 src/pagedef.cpp        |   4 +-
 src/pre.l              |   4 +-
 src/rtfdocvisitor.cpp  |  20 +++++++
 src/scanner.l          |  58 ++++++++++++-------
 src/util.cpp           | 151 ++++++++++++++++++++++++++++++++++---------------
 src/util.h             |   8 ++-
 29 files changed, 472 insertions(+), 249 deletions(-)

diff --git a/INSTALL b/INSTALL
index eb27c2d..d07c4bc 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
-DOXYGEN Version 1.5.6-20080819
+DOXYGEN Version 1.5.6-20080914
 
 Please read the installation section of the manual 
 (http://www.doxygen.org/install.html) for instructions.
 
 --------
-Dimitri van Heesch (19 August 2008)
+Dimitri van Heesch (14 September 2008)
diff --git a/README b/README
index 2063e27..bb58a11 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.5.6_20080819
+DOXYGEN Version 1.5.6_20080914
 
 Please read INSTALL for compilation instructions.
 
@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
 
 Enjoy,
 
-Dimitri van Heesch (dimitri@stack.nl) (19 August 2008)
+Dimitri van Heesch (dimitri@stack.nl) (14 September 2008)
diff --git a/configure b/configure
index a0a1ffc..d59e719 100755
--- a/configure
+++ b/configure
@@ -20,7 +20,7 @@ doxygen_version_minor=5
 doxygen_version_revision=6
 
 #NOTE: Setting version_mmn to "NO" will omit mmn info from the package.
-doxygen_version_mmn=20080819
+doxygen_version_mmn=20080914
 
 bin_dirs=`echo $PATH | sed -e "s/:/ /g"`
 
diff --git a/doc/config.doc b/doc/config.doc
index 27fde41..3768df7 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -67,6 +67,8 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_case_sense_names CASE_SENSE_NAMES 
 \refitem cfg_chm_file CHM_FILE
 \refitem cfg_class_diagrams CLASS_DIAGRAMS 
+\refitem cfg_class_graph CLASS_GRAPH
+\refitem cfg_collaboration_graph COLLABORATION_GRAPH
 \refitem cfg_cols_in_alpha_index COLS_IN_ALPHA_INDEX
 \refitem cfg_compact_latex COMPACT_LATEX 
 \refitem cfg_compact_rtf COMPACT_RTF
@@ -130,6 +132,7 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_generate_treeview GENERATE_TREEVIEW
 \refitem cfg_generate_xml GENERATE_XML
 \refitem cfg_graphical_hierarchy GRAPHICAL_HIERARCHY
+\refitem cfg_group_graphs GROUP_GRAPHS
 \refitem cfg_have_dot HAVE_DOT
 \refitem cfg_hhc_location HHC_LOCATION
 \refitem cfg_hide_friend_compounds HIDE_FRIEND_COMPOUNDS
@@ -147,6 +150,7 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_idl_property_support IDL_PROPERTY_SUPPORT
 \refitem cfg_ignore_prefix IGNORE_PREFIX
 \refitem cfg_image_path IMAGE_PATH
+\refitem cfg_include_graph INCLUDE_GRAPH
 \refitem cfg_include_path INCLUDE_PATH
 \refitem cfg_inherit_docs INHERIT_DOCS
 \refitem cfg_inline_info INLINE_INFO
@@ -206,6 +210,7 @@ followed by the descriptions of the tags grouped by category.
 \refitem cfg_short_names SHORT_NAMES
 \refitem cfg_show_dirs SHOW_DIRECTORIES
 \refitem cfg_show_files SHOW_FILES
+\refitem cfg_show_include_files SHOW_INCLUDE_FILES
 \refitem cfg_show_namespaces SHOW_NAMESPACES
 \refitem cfg_sip_support SIP_SUPPORT
 \refitem cfg_skip_function_macros SKIP_FUNCTION_MACROS
@@ -687,14 +692,12 @@ function's detailed documentation block.
  will show members with their full class and namespace scopes in the
  documentation. If set to \c YES the scope will be hidden. 
 
-<!--
 \anchor cfg_show_include_files
 <dt>\c SHOW_INCLUDE_FILES <dd>
  \addindex SHOW_INCLUDE_FILES
  If the SHOW_INCLUDE_FILES tag is set to YES (the default) then doxygen
  will put a list of the files that are included by a file in the documentation 
  of that file.
--->
 
 \anchor cfg_inline_info
 <dt>\c INLINE_INFO <dd>
@@ -786,14 +789,12 @@ function's detailed documentation block.
  individual variables and defines can be controlled using \ref cmdshowinitializer "\\showinitializer"
  or \ref cmdhideinitializer "\\hideinitializer" command in the documentation.
 
-<!--
 \anchor cfg_show_used_files
 <dt>\c SHOW_USED_FILES <dd>
  \addindex SHOW_USED_FILES
  Set the \c SHOW_USED_FILES tag to \c NO to disable the list of files generated
  at the bottom of the documentation of classes and structs. If set to \c YES the
  list will mention the files that were used to generate the documentation.
--->
 
 \anchor cfg_show_dirs
 <dt>\c SHOW_DIRECTORIES <dd>
@@ -954,9 +955,9 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn"
  doxygen. The layout file controls the global structure of the generated output files
  in an output format independent way. The create the layout file that represents
  doxygen's defaults, run doxygen with the -l option. You can optionally specify a
- file name after the option, if omitted doxygenlayout.xml will be used as the name
+ file name after the option, if omitted DoxygenLayout.xml will be used as the name
  of the layout file. Note that if you run doxygen from a directory containing 
- a file called doxygenlayout.xml, doxygen will parse it automatically even if 
+ a file called DoxygenLayout.xml, doxygen will parse it automatically even if 
  the \c LAYOUT_FILE tag is left empty.
 
 \anchor cfg_recursive
@@ -1408,7 +1409,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn"
  Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
  probably better off using the HTML help feature. Other possible values
  for this tag are: \c HIERARCHIES, which will generate the Groups, Directories,
- and Class Hiererachy pages using a tree view instead of an ordered list;
+ and Class Hierarchy pages using a tree view instead of an ordered list;
  ALL, which combines the behavior of \c FRAME and \c HIERARCHIES, and \c NONE, 
  which disables this behavior completely. For backwards compatibility 
  with previous releases of Doxygen, the values YES and NO are equivalent 
@@ -1937,7 +1938,6 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre>
  different font using \c DOT_FONTNAME you can set the path where dot 
  can find it using this tag. 
 
-<!--
 \anchor cfg_class_graph
 <dt>\c CLASS_GRAPH <dd>
  \addindex CLASS_GRAPH
@@ -1959,7 +1959,6 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre>
  \addindex GROUP_GRAPHS
  If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
  will generate a graph for groups, showing the direct groups dependencies.
--->
 
 \anchor cfg_uml_look
 <dt>\c UML_LOOK <dd>
@@ -1981,7 +1980,6 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre>
  inheritance and usage relations if the target is undocumented
  or is not a class.
 
-<!--
 \anchor cfg_include_graph
 <dt>\c INCLUDE_GRAPH <dd>
  \addindex INCLUDE_GRAPH 
@@ -1997,7 +1995,6 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre>
  \c HAVE_DOT tags are set to \c YES then doxygen will generate a graph for each
  documented header file showing the documented files that directly or indirectly
  include this file.
--->
 
 \anchor cfg_call_graph
 <dt>\c CALL_GRAPH <dd>
diff --git a/doc/customize.doc b/doc/customize.doc
index e8bc99a..d840484 100644
--- a/doc/customize.doc
+++ b/doc/customize.doc
@@ -85,7 +85,7 @@ by doxygen using the following command:
 doxygen -l 
 \endverbatim
 optionally the name of the layout file can be specified, if omitted
-\c doxygenlayout.xml will be used.
+\c DoxygenLayout.xml will be used.
 
 The toplevel structure of the file looks as follows:
 \verbatim
@@ -149,10 +149,19 @@ Doxygen will list the pieces in the order in which they appear
 in the XML file. 
 
 Some tags have a \c visible attribute which can be 
-used to hide the fragment from the generated output. 
+used to hide the fragment from the generated output, by setting the attribute's
+value to "no". You can also use the value of a configuration option to 
+determine the visibility, by using 
+its name prefixed with a dollar sign, e.g.
+\verbatim
+  ...
+  <includes visible="$SHOW_INCLUDE_FILES"/>
+  ...
+\endverbatim
+This was mainly added for backward compatibility.
 Note that the \c visible attribute is just a hint for doxygen. 
 If no relevant information is available for a certain piece it is 
-omitted even if it is set to \c yes.
+omitted even if it is set to \c yes (i.e. no empty sections are generated). 
 
 Some tags have a \c title attribute. This attribute can be used
 to customize the title doxygen will use as a header for the piece.
diff --git a/doc/doxygen_manual.tex b/doc/doxygen_manual.tex
index 3020fd4..bb6675e 100644
--- a/doc/doxygen_manual.tex
+++ b/doc/doxygen_manual.tex
@@ -12,7 +12,7 @@
 % Documents produced by Doxygen are derivative works derived from the
 % input used in their production; they are not affected by this license.
 
-\documentclass[a4paper]{article}
+\documentclass[a4paper]{report}
 \usepackage{a4wide}
 \usepackage{makeidx}
 \usepackage{fancyhdr}
@@ -23,6 +23,7 @@
 \usepackage{multicol}
 \usepackage{times}
 \usepackage{alltt}
+\usepackage{tocloft}
 \usepackage[pdftex,
             pagebackref=true,
             colorlinks=true,
@@ -31,6 +32,9 @@
 \makeindex
 \setcounter{tocdepth}{1}
 \renewcommand{\footrulewidth}{0.4pt}
+\renewcommand{\cftsecindent}{0 em}
+\renewcommand{\cftsecnumwidth}{3.2 em}
+\renewcommand{\cftsubsecindent}{3.2 em}
 \begin{document}
 \begin{titlepage}
 \includegraphics[width=\textwidth]{doxygen_logo}
diff --git a/src/code.l b/src/code.l
index fde0d82..e246cc0 100644
--- a/src/code.l
+++ b/src/code.l
@@ -389,7 +389,7 @@ static void pushScope(const char *s)
     g_classScope += "::";
     g_classScope += s;
   }
-  //printf("pushScope() result: `%s'\n",g_classScope.data());
+  //printf("pushScope(%s) result: `%s'\n",s,g_classScope.data());
 }
 
 /*! remove the top class/namespace name from the scope */
@@ -441,7 +441,18 @@ static void setClassScope(const QCString &name)
     // remove template from scope
     n=n.left(ts)+n.right(n.length()-te-1);
   }
-  g_classScope = n;
+  while (!g_classScopeLengthStack.isEmpty())
+  {
+    popScope();
+  }
+  g_classScope.resize(0);
+  int i;
+  while ((i=n.find("::"))!=-1)
+  {
+    pushScope(n.left(i));
+    n = n.mid(i+2);
+  }
+  pushScope(n);
   //printf("--->New class scope `%s'\n",g_classScope.data());
 }
 
@@ -821,7 +832,6 @@ static bool getLinkInScope(const QCString &c,  // scope
   if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef) && 
       md->isLinkable())
   {
-    //printf("Found!\n");
     if (g_exampleBlock)
     {
       QCString anchor;
@@ -871,7 +881,7 @@ static bool getLink(const char *className,
 		    CodeOutputInterface &ol,
 		    const char *text=0)
 {
-  //printf("getLink(%s,%s)\n",className,memberName);
+  //printf("getLink(%s,%s) g_curClassName=%s\n",className,memberName,g_curClassName.data());
   QCString m=removeRedundantWhiteSpace(memberName);
   QCString c=className;
   if (!getLinkInScope(c,m,memberName,ol,text))
@@ -1201,7 +1211,7 @@ static void generateFunctionLink(CodeOutputInterface &ol,char *funcName)
 {
   //CodeClassDef *ccd=0;
   ClassDef *ccd=0;
-  QCString locScope=g_classScope.copy();
+  QCString locScope=g_classScope;
   QCString locFunc=removeRedundantWhiteSpace(funcName);
   //fprintf(stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data());
   int len=2;
@@ -1209,7 +1219,14 @@ static void generateFunctionLink(CodeOutputInterface &ol,char *funcName)
   if (i==-1) i=locFunc.findRev("."),len=1;
   if (i>0)
   {
-    locScope=locFunc.left(i);
+    if (locScope.isEmpty())
+    {
+      locScope=locFunc.left(i);
+    }
+    else
+    {
+      locScope+="::"+locFunc.left(i);
+    }
     locFunc=locFunc.right(locFunc.length()-i-len).stripWhiteSpace();
     int ts=locScope.find('<'); // start of template
     int te=locScope.findRev('>'); // end of template
@@ -1650,7 +1667,7 @@ static int yyread(char *buf,int max_size)
 
 B       [ \t]
 BN      [ \t\n\r]
-ID	"$"?[a-z_A-Z][a-z_A-Z0-9]*
+ID	"$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
 SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
 TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">"
 SCOPETNAME ((({ID}{TEMPLIST}?){BN}*"::"{BN}*)*)((~{BN}*)?{ID})
@@ -2200,6 +2217,10 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
   					  startFontClass("keywordflow");
   					  codifyLines(yytext);
 					  endFontClass();
+					  // insert the variable in the parent scope, see bug 546158
+					  g_theVarContext.popScope();
+					  g_theVarContext.addVariable(g_parmType,g_parmName);
+					  g_theVarContext.pushScope();
   				          g_name.resize(0);g_type.resize(0);
 					}
 <Body>{FLOWKW}/{BN}*"(" 			{
@@ -2328,6 +2349,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
 <Body>{SCOPETNAME}/{BN}*"("		{ // a() or c::a() or t<A,B>::a()
   					  addType();
 					  generateFunctionLink(*g_code,yytext);
+					  //printf("---> g_classScope=%s\n",g_classScope.data());
 					  //g_theVarContext.addVariable(g_type,yytext);
   					  g_bracketCount=0;
 					  g_args.resize(0);
@@ -2770,7 +2792,9 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
 					  int index = g_name.findRev("::");
 					  if (index!=-1) 
 					  {
-					    ClassDef *cd=getResolvedClass(Doxygen::globalScope,g_sourceFileDef,g_name.left(index));
+					    QCString scope = g_name.left(index);
+					    if (!g_classScope.isEmpty()) scope.prepend(g_classScope+"::");
+					    ClassDef *cd=getResolvedClass(Doxygen::globalScope,g_sourceFileDef,scope);
 					    if (cd)
 					    {
 					      setClassScope(cd->name());
@@ -2885,22 +2909,22 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
 <SkipInits>{ID}				{
 					  generateClassOrGlobalLink(*g_code,yytext);
   					}
-<FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/"("	{
+<FuncCall>{ID}/"("			{
 					  generateFunctionLink(*g_code,yytext);
 					}
-<FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/("."|"->") { 
+<FuncCall>{ID}/("."|"->")               { 
 					  g_name=yytext; 
 					  generateClassOrGlobalLink(*g_code,yytext);
 					  BEGIN( MemberCall2 ); 
 					}
-<FuncCall,MemberCall2>("("{B}*("*"{B}*)+[a-z_A-Z][a-z_A-Z0-9]*{B}*")"{B}*)/("."|"->") { 
+<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}*{B}*")"{B}*)/("."|"->") { 
   					  g_code->codify(yytext);
 					  int s=0;while (!isId(yytext[s])) s++;
                                           int e=yyleng-1;while (!isId(yytext[e])) e--;
 					  g_name=((QCString)yytext).mid(s,e-s+1); 
 					  BEGIN( MemberCall2 ); 
 					}
-<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*"(") { 
+<MemberCall2>{ID}/([ \t\n]*"(")         { 
   					  if (!g_args.isEmpty())
 					    generateMemberLink(*g_code,g_args,yytext);
 					  else
@@ -2908,7 +2932,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
 					  g_args.resize(0);
 					  BEGIN( FuncCall );
 					}
-<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*("."|"->")) {
+<MemberCall2>{ID}/([ \t\n]*("."|"->"))  {
   					  //g_code->codify(yytext);
 					  g_name=yytext; 
 					  generateClassOrGlobalLink(*g_code,yytext);
diff --git a/src/commentscan.l b/src/commentscan.l
index 8351407..1500f49 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -801,13 +801,13 @@ ATTR      ({B}+[^>\n]*)?
 DOCNL     "\n"|"\\_linebr"
 LC        "\\"{B}*"\n"
 NW	  [^a-z_A-Z0-9]
-FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+]
-FILEECHAR [a-z_A-Z0-9\-\+]
+FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+]
+FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+]
 FILE      ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+"\"")
-ID        "$"?[a-z_A-Z][a-z_A-Z0-9]*
-LABELID   [a-z_A-Z][a-z_A-Z0-9\-]*
+ID        "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
+LABELID   [a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF\-]*
 SCOPEID   {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
-SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID})
+SCOPENAME "$"?(({ID}?{BN}*("::"|"."){BN}*)*)((~{BN}*)?{ID})
 MAILADR   [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]+ 
 RCSTAG    "$"{ID}":"[^\n$]+"$"
 
@@ -1111,7 +1111,7 @@ RCSTAG    "$"{ID}":"[^\n$]+"$"
   /* ------------ handle argument of namespace command --------------- */
 
 <NameSpaceDocArg1>{SCOPENAME}		{ // handle argument
-  					  current->name = yytext;
+  					  current->name = substitute(yytext,".","::");
 					  BEGIN( Comment );
   					}
 <NameSpaceDocArg1>{LC}			{ // line continuation
@@ -1155,7 +1155,7 @@ RCSTAG    "$"{ID}":"[^\n$]+"$"
   /* ------ handle argument of class/struct/union command --------------- */
 
 <ClassDocArg1>{SCOPENAME}		{ // first argument
-					  current->name = yytext;
+  					  current->name = substitute(yytext,".","::");
 					  if (current->section==Entry::PROTOCOLDOC_SEC)
 					  {
 					    current->name+="-p";
@@ -1164,7 +1164,7 @@ RCSTAG    "$"{ID}":"[^\n$]+"$"
 					  BEGIN( ClassDocArg2 );
 					}
 <CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
-					  current->name = yytext;
+  					  current->name = substitute(yytext,".","::");
 					  BEGIN( ClassDocArg2 );
    					}
 <ClassDocArg1,CategoryDocArg1>{LC}      { // line continuation
diff --git a/src/config.l b/src/config.l
index 21e7a39..6790c76 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1901,13 +1901,13 @@ void Config::create()
                     "documentation. If set to YES the scope will be hidden. \n",
                     FALSE
                  );
-  //cb = addBool(
-  //                  "SHOW_INCLUDE_FILES",
-  //                  "If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \n"
-  //                  "will put a list of the files that are included by a file in the documentation \n"
-  //                  "of that file. \n",
-  //                  TRUE
-  //               );
+  cb = addBool(
+                    "SHOW_INCLUDE_FILES",
+                    "If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \n"
+                    "will put a list of the files that are included by a file in the documentation \n"
+                    "of that file. \n",
+                    TRUE
+                 );
   cb = addBool(
                     "INLINE_INFO",
                     "If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \n"
@@ -1993,13 +1993,13 @@ void Config::create()
                     "command in the documentation regardless of this setting. \n",
                     0,10000,30
                  );
-  //cb = addBool(
-  //                  "SHOW_USED_FILES",
-  //                  "Set the SHOW_USED_FILES tag to NO to disable the list of files generated \n"
-  //                  "at the bottom of the documentation of classes and structs. If set to YES the \n"
-  //                  "list will mention the files that were used to generate the documentation. \n",
-  //                  TRUE
-  //              );
+  cb = addBool(
+                    "SHOW_USED_FILES",
+                    "Set the SHOW_USED_FILES tag to NO to disable the list of files generated \n"
+                    "at the bottom of the documentation of classes and structs. If set to YES the \n"
+                    "list will mention the files that were used to generate the documentation. \n",
+                    TRUE
+                );
   cb = addBool(
                     "SHOW_DIRECTORIES",
 		    "If the sources in your project are distributed over multiple directories \n"
@@ -2036,19 +2036,12 @@ void Config::create()
 		   "doxygen. The layout file controls the global structure of the generated output files \n"
 		   "in an output format independent way. The create the layout file that represents \n"
 		   "doxygen's defaults, run doxygen with the -l option. You can optionally specify a \n"
-		   "file name after the option, if omitted doxygenlayout.xml will be used as the name \n"
+		   "file name after the option, if omitted DoxygenLayout.xml will be used as the name \n"
 		   "of the layout file.\n"
 	      );
   cs->setWidgetType(ConfigString::File);
   addObsolete("DETAILS_AT_TOP");
-  addObsolete("SHOW_INCLUDE_FILES");
-  addObsolete("SHOW_USED_FILES");
   addObsolete("ALPHABETICAL_INDEX");
-  addObsolete("CLASS_GRAPH");
-  addObsolete("COLLABORATION_GRAPH");
-  addObsolete("GROUP_GRAPHS");
-  addObsolete("INCLUDE_GRAPH");
-  addObsolete("INCLUDED_BY_GRAPH");
 
   
   //-----------------------------------------------------------------------------------------------
@@ -2528,7 +2521,7 @@ void Config::create()
 		    "Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \n"
 		    "probably better off using the HTML help feature. Other possible values \n"
 		    "for this tag are: HIERARCHIES, which will generate the Groups, Directories,\n"
-                    "and Class Hiererachy pages using a tree view instead of an ordered list;\n"
+                    "and Class Hierarchy pages using a tree view instead of an ordered list;\n"
                     "ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which\n"
                     "disables this behavior completely. For backwards compatibility with previous\n"
                     "releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE\n"
@@ -3048,31 +3041,31 @@ void Config::create()
 		    "different font using DOT_FONTNAME you can set the path where dot \n"
 		    "can find it using this tag. \n"
                 );
-  //cb = addBool(
-  //                  "CLASS_GRAPH",
-  //                  "If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \n"
-  //                  "will generate a graph for each documented class showing the direct and \n"
-  //                  "indirect inheritance relations. Setting this tag to YES will force the \n"
-  //                  "the CLASS_DIAGRAMS tag to NO.\n",
-  //                  TRUE
-  //               );
-  //cb->addDependency("HAVE_DOT");
-  //cb = addBool(
-  //                  "COLLABORATION_GRAPH",
-  //                  "If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \n"
-  //                  "will generate a graph for each documented class showing the direct and \n"
-  //                  "indirect implementation dependencies (inheritance, containment, and \n"
-  //                  "class references variables) of the class with other documented classes. \n",
-  //                  TRUE
-  //               );
-  //cb->addDependency("HAVE_DOT");
-  //cb = addBool(
-  //                  "GROUP_GRAPHS",
-  //                  "If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen \n"
-  //                  "will generate a graph for groups, showing the direct groups dependencies\n",
-  //                  TRUE
-  //               );                 
-  //cb->addDependency("HAVE_DOT");
+  cb = addBool(
+                    "CLASS_GRAPH",
+                    "If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \n"
+                    "will generate a graph for each documented class showing the direct and \n"
+                    "indirect inheritance relations. Setting this tag to YES will force the \n"
+                    "the CLASS_DIAGRAMS tag to NO.\n",
+                    TRUE
+                 );
+  cb->addDependency("HAVE_DOT");
+  cb = addBool(
+                    "COLLABORATION_GRAPH",
+                    "If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \n"
+                    "will generate a graph for each documented class showing the direct and \n"
+                    "indirect implementation dependencies (inheritance, containment, and \n"
+                    "class references variables) of the class with other documented classes. \n",
+                    TRUE
+                 );
+  cb->addDependency("HAVE_DOT");
+  cb = addBool(
+                    "GROUP_GRAPHS",
+                    "If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen \n"
+                    "will generate a graph for groups, showing the direct groups dependencies\n",
+                    TRUE
+                 );                 
+  cb->addDependency("HAVE_DOT");
   cb = addBool(
                     "UML_LOOK",
                     "If the UML_LOOK tag is set to YES doxygen will generate inheritance and \n"
@@ -3088,24 +3081,24 @@ void Config::create()
                     FALSE
                  );
   cb->addDependency("HAVE_DOT");
-  //cb = addBool(
-  //                  "INCLUDE_GRAPH",
-  //                  "If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \n"
-  //                  "tags are set to YES then doxygen will generate a graph for each documented \n"
-  //                  "file showing the direct and indirect include dependencies of the file with \n"
-  //                  "other documented files. \n",
-  //                  TRUE
-  //               );
-  //cb->addDependency("HAVE_DOT");
-  //cb = addBool(
-  //                  "INCLUDED_BY_GRAPH",
-  //                  "If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \n"
-  //                  "HAVE_DOT tags are set to YES then doxygen will generate a graph for each \n"
-  //                  "documented header file showing the documented files that directly or \n"
-  //                  "indirectly include this file. \n",
-  //                  TRUE
-  //               );
-  //cb->addDependency("HAVE_DOT");
+  cb = addBool(
+                    "INCLUDE_GRAPH",
+                    "If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \n"
+                    "tags are set to YES then doxygen will generate a graph for each documented \n"
+                    "file showing the direct and indirect include dependencies of the file with \n"
+                    "other documented files. \n",
+                    TRUE
+                 );
+  cb->addDependency("HAVE_DOT");
+  cb = addBool(
+                    "INCLUDED_BY_GRAPH",
+                    "If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \n"
+                    "HAVE_DOT tags are set to YES then doxygen will generate a graph for each \n"
+                    "documented header file showing the documented files that directly or \n"
+                    "indirectly include this file. \n",
+                    TRUE
+                 );
+  cb->addDependency("HAVE_DOT");
   cb = addBool(
                     "CALL_GRAPH",
                     "If the CALL_GRAPH and HAVE_DOT options are set to YES then \n"
diff --git a/src/cppvalue.cpp b/src/cppvalue.cpp
index af4b03d..7acce1f 100644
--- a/src/cppvalue.cpp
+++ b/src/cppvalue.cpp
@@ -71,7 +71,15 @@ CPPValue parseCharacter() // does not work for '\n' and the alike
       case '?':  return CPPValue((long)'\?');
       case '\'': return CPPValue((long)'\'');
       case '"':  return CPPValue((long)'"');
-      case '0':  return parseOctal();
+      case '0':  // fall through
+      case '1':  // fall through
+      case '2':  // fall through
+      case '3':  // fall through
+      case '4':  // fall through
+      case '5':  // fall through
+      case '6':  // fall through
+      case '7':  // fall through
+                 return parseOctal();
       case 'x': 
       case 'X':  return parseHexadecimal();
       default:   printf("Invalid escape sequence %s found!\n",g_strToken.data()); 
diff --git a/src/declinfo.l b/src/declinfo.l
index d36610e..d4c2676 100644
--- a/src/declinfo.l
+++ b/src/declinfo.l
@@ -97,7 +97,7 @@ static int yyread(char *buf,int max_size)
 %}
 
 B       [ \t]
-ID	([a-z_A-Z][a-z_A-Z0-9]*)|(@[0-9]+)
+ID	([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+)
 
 %option nounput
 %option noyywrap
diff --git a/src/defargs.l b/src/defargs.l
index f44c1f3..42faf17 100644
--- a/src/defargs.l
+++ b/src/defargs.l
@@ -98,7 +98,7 @@ static int yyread(char *buf,int max_size)
 %}
 
 B       [ \t]
-ID	[a-z_A-Z][a-z_A-Z0-9]*
+ID	[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
 
 %option noyywrap
 
@@ -302,6 +302,22 @@ ID	[a-z_A-Z][a-z_A-Z0-9]*
 					      { // type contains a name
 						a->type = removeRedundantWhiteSpace(g_curArgTypeName.left(i+1));
 						a->name = g_curArgTypeName.right(l-i-1).stripWhiteSpace();
+
+						// if the type becomes a type specifier only then we make a mistake
+						// and need to correct it to avoid seeing a nameless parameter
+						// "struct A" as a parameter with type "struct" and name "A".
+						int sv=0;
+						if (a->type.left(6)=="const ") sv=6;
+						else if (a->type.left(8)=="volatile ") sv=9;
+						if (a->type.mid(sv)=="struct"    || 
+						    a->type.mid(sv)=="union"     || 
+						    a->type.mid(sv)=="class"     || 
+						    a->type.mid(sv)=="typename"  || 
+						    a->type=="const" || a->type=="volatile")
+						{ 
+						  a->type = a->type + " " + a->name;
+						  a->name.resize(0);
+						}
 					      }
 					      else // assume only the type was specified, try to determine name later 
 					      {
diff --git a/src/docparser.cpp b/src/docparser.cpp
index a434ac7..3a3c999 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -327,7 +327,7 @@ static void checkArgumentName(const QString &name,bool isParam)
   //printf("isDocsForDefinition()=%d\n",g_memberDef->isDocsForDefinition());
   if (al==0) return; // no argument list
 
-  static QRegExp re("[a-zA-Z0-9_]+\\.*");
+  static QRegExp re("[a-zA-Z0-9_\\x80-\\xFF]+\\.*");
   int p=0,i=0,l;
   while ((i=re.match(name,p,&l))!=-1) // to handle @param x,y
   {
@@ -2135,8 +2135,8 @@ DocRef::DocRef(DocNode *parent,const QString &target,const QString &context) :
     if (sec->type!=SectionInfo::Page) m_anchor = sec->label;
     m_refToAnchor  = sec->type==SectionInfo::Anchor;
     m_refToSection = sec->type!=SectionInfo::Anchor;
-    //printf("m_text=%s,m_ref=%s,m_file=%s,m_refToAnchor=%d\n",
-    //    m_text.data(),m_ref.data(),m_file.data(),m_refToAnchor);
+    //printf("m_text=%s,m_ref=%s,m_file=%s,m_refToAnchor=%d type=%d\n",
+    //    m_text.data(),m_ref.data(),m_file.data(),m_refToAnchor,sec->type);
     return;
   }
   else if (resolveLink(context,target,TRUE,&compound,anchor))
@@ -2760,7 +2760,8 @@ int DocInternal::parse(int level)
          (level==4 && retval==RetVal_Paragraph)
         )
   {
-    DocSection *s=new DocSection(this,level,g_token->sectionId);
+    DocSection *s=new DocSection(this,
+        QMIN(level+Doxygen::subpageNestingLevel,4),g_token->sectionId);
     m_children.append(s);
     retval = s->parse();
   }
@@ -5817,7 +5818,8 @@ int DocSection::parse()
     while (retval==RetVal_Subsection) // more sections follow
     {
       //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];
-      DocSection *s=new DocSection(this,2,g_token->sectionId);
+      DocSection *s=new DocSection(this,
+          QMIN(2+Doxygen::subpageNestingLevel,4),g_token->sectionId);
       m_children.append(s);
       retval = s->parse();
     }
@@ -5828,7 +5830,8 @@ int DocSection::parse()
     while (retval==RetVal_Subsubsection) // more sections follow
     {
       //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];
-      DocSection *s=new DocSection(this,3,g_token->sectionId);
+      DocSection *s=new DocSection(this,
+          QMIN(3+Doxygen::subpageNestingLevel,4),g_token->sectionId);
       m_children.append(s);
       retval = s->parse();
     }
@@ -6015,7 +6018,8 @@ void DocRoot::parse()
     SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId];
     if (sec)
     {
-      DocSection *s=new DocSection(this,1,g_token->sectionId);
+      DocSection *s=new DocSection(this,
+          QMIN(1+Doxygen::subpageNestingLevel,4),g_token->sectionId);
       m_children.append(s);
       retval = s->parse();
     }
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 7edafa0..d183e4c 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -240,8 +240,8 @@ static void handleHtmlTag()
       else // value without any quotes
       {
 	startAttrib=i;
-	// search for separator
-        while (i<yyleng && !isspace(c)) { c=tagText.at(++i); } 
+	// search for separator or end symbol
+        while (i<yyleng && !isspace(c) && c!='>') { c=tagText.at(++i); } 
 	endAttrib=i;
 	if (i<yyleng) c=tagText.at(++i);
       }
@@ -312,7 +312,8 @@ PARAMIO   {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]"
 TEMPCHAR  [a-z_A-Z0-9,: \t\*\&]
 FUNCCHAR  [a-z_A-Z0-9,:\<\> \t\*\&]
 SCOPESEP  "::"|"#"|"."
-SCOPEPRE  {ID}("<"{TEMPCHAR}*">")?{SCOPESEP}
+TEMPLPART "<"{TEMPCHAR}*">"
+SCOPEPRE  {ID}{TEMPLPART}?{SCOPESEP}
 SCOPEKEYS ":"({ID}":")*
 SCOPECPP  {SCOPEPRE}*(~)?{ID}("<"{TEMPCHAR}*">")?
 SCOPEOBJC {SCOPEPRE}?{ID}{SCOPEKEYS}?
@@ -339,7 +340,7 @@ HTMLKEYL  "strong"|"center"|"table"|"caption"|"small"|"code"|"dfn"|"var"|"img"|"
 HTMLKEYU  "STRONG"|"CENTER"|"TABLE"|"CAPTION"|"SMALL"|"CODE"|"DFN"|"VAR"|"IMG"|"PRE"|"SUB"|"SUP"|"TR"|"TD"|"TH"|"OL"|"UL"|"LI"|"TT"|"KBD"|"EM"|"HR"|"DL"|"DT"|"DD"|"BR"|"I"|"A"|"B"|"P"
 HTMLKEYW  {HTMLKEYL}|{HTMLKEYU}
 LABELID   [a-z_A-Z][a-z_A-Z0-9\-]*
-REFWORD   ("#"|"::")?({ID}("."|"#"|"::"|"-"|"/"))*({ID}(":")?){FUNCARG}?
+REFWORD   ("#"|"::")?({ID}{TEMPLPART}?("."|"#"|"::"|"-"|"/"))*({ID}(":")?){FUNCARG}?
 
 %option noyywrap
 %option yylineno
@@ -810,7 +811,7 @@ REFWORD   ("#"|"::")?({ID}("."|"#"|"::"|"-"|"/"))*({ID}(":")?){FUNCARG}?
                          g_token->name = g_token->name.stripWhiteSpace();
 			 return TK_WORD;
   		       }
-<St_Link>{LINKMASK}    {
+<St_Link>{LINKMASK}|{REFWORD}    {
                          g_token->name = yytext;
 			 return TK_WORD;
                        }
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 0c1bdae..e8a045f 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -138,7 +138,7 @@ QCString         Doxygen::objDBFileName;
 QCString         Doxygen::entryDBFileName;
 bool             Doxygen::gatherDefines = TRUE;
 IndexList        Doxygen::indexList;
-
+int              Doxygen::subpageNestingLevel = 0;
 bool             Doxygen::userComments = FALSE;
 
 // locally accessible globals
@@ -1952,6 +1952,7 @@ static MemberDef *addVariableToClass(
             md->memberType()==MemberDef::Variable)
         { // Objective-C 2.0 property
           // turn variable into a property
+          md->setProtection(root->protection);
           cd->reclassifyMember(md,MemberDef::Property);
         }
         addMemberDocs(rootNav,md,def,0,FALSE);
@@ -2842,14 +2843,18 @@ static void buildFunctionList(EntryNav *rootNav)
         int te=rname.find('>');
         if (memIndex>0 && (ts==-1 || te==-1))
         {
-          nd = Doxygen::namespaceSDict->find(rname.left(memIndex));
-          isMember = nd==0;
-          if (nd)
-          {
-            // strip namespace scope from name
-            scope=rname.left(memIndex);
-            rname=rname.right(rname.length()-memIndex-2);
-          }
+          // note: the following code was replaced by inMember=TRUE to deal with a 
+          // function rname='X::foo' of class X inside a namespace also called X...
+          // bug id 548175
+          //nd = Doxygen::namespaceSDict->find(rname.left(memIndex));
+          //isMember = nd==0;
+          //if (nd)
+          //{
+          //  // strip namespace scope from name
+          //  scope=rname.left(memIndex);
+          //  rname=rname.right(rname.length()-memIndex-2);
+          //}
+          isMember = TRUE;
         }
         else
         {
@@ -2962,13 +2967,7 @@ static void buildFunctionList(EntryNav *rootNav)
                     md->setArgumentList(argList);
                   }
                 }
-#if 0
-                else if (!md->documentation().isEmpty() && !root->doc.isEmpty() && mnd==rnd)
-                {
-                  warn(root->docFile,root->docLine,"Warning: member %s: ignoring the detailed description found here, since another one was found at line %d of file %s!",md->name().data(),md->docLine(),md->docFile().data());
-                  //printf("md->docs=[%s] root->docs=[%s]\n",md->documentation().data(),root->doc.data());
-                }
-#endif
+
                 md->setDocumentation(root->doc,root->docFile,root->docLine);
                 md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
                 md->setDocsForDefinition(!root->proto);
@@ -2977,12 +2976,6 @@ static void buildFunctionList(EntryNav *rootNav)
                 {
                   md->setArgsString(root->args);
                 }
-#if 0
-                else if (!md->briefDescription().isEmpty() && !root->brief.isEmpty() && mnd==rnd)
-                {
-                  warn(root->briefFile,root->briefLine,"Warning: member %s: ignoring the brief description found here, since another one was found at line %d of file %s!",md->name().data(),md->briefLine(),md->briefFile().data());
-                }
-#endif
                 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
 
                 md->addSectionsToDefinition(root->anchors);
@@ -4160,6 +4153,7 @@ static bool findClassRelation(
           // TODO: here we should try to find the correct template specialization
           // but for now, we only look for the unspecializated base class.
           int e=findEndOfTemplate(baseClassName,i+1);
+          //printf("baseClass==0 i=%d e=%d\n",i,e);
           if (e!=-1) // end of template was found at e
           {
             templSpec=baseClassName.mid(i,e-i);
@@ -4182,6 +4176,7 @@ static bool findClassRelation(
                                                     // instance (for instance if a class
                                                     // derived from a template argument)
         {
+          //printf("baseClass=%p templSpec=%s\n",baseClass,templSpec.data());
           ClassDef *templClass=getClass(baseClass->name()+templSpec);
           if (templClass)
           {
@@ -4193,6 +4188,7 @@ static bool findClassRelation(
 
         //printf("cd=%p baseClass=%p\n",cd,baseClass);
         bool found=baseClass!=0 && (baseClass!=cd || mode==TemplateInstances);
+        //printf("1. found=%d\n",found);
         if (!found && si!=-1)
         {
           QCString tmpTemplSpec;
@@ -4209,12 +4205,11 @@ static bool findClassRelation(
           found=baseClass!=0 && baseClass!=cd;
           if (found) templSpec = tmpTemplSpec;
         }
+        //printf("2. found=%d\n",found);
         
         //printf("root->name=%s biName=%s baseClassName=%s\n",
         //        root->name.data(),biName.data(),baseClassName.data());
 
-        //FileDef *fd=cd->getFileDef();
-        //NamespaceDef *nd=cd->getNamespaceDef();
         if (!found)
         {
           baseClass=findClassWithinClassContext(context,cd,baseClassName);
@@ -4227,6 +4222,7 @@ static bool findClassRelation(
         // make templSpec canonical
         templSpec = getCanonicalTemplateSpec(cd, cd->getFileDef(), templSpec);
 
+        //printf("3. found=%d\n",found);
         if (found)
         {
           Debug::print(Debug::Classes,0,"    Documented base class `%s' templSpec=%s\n",biName.data(),templSpec.isEmpty()?"":templSpec.data());
@@ -4650,7 +4646,7 @@ static void addListReferences()
     QCString name = pd->name();
     if (pd->getGroupDef())
     {
-      name = pd->getGroupDef()->getOutputFileBase().copy();
+      name = pd->getGroupDef()->getOutputFileBase();
     }
     {
       LockingPtr< QList<ListItemInfo> > xrefItems = pd->xrefListItems();
@@ -4659,6 +4655,20 @@ static void addListReferences()
           name,pd->title());
     }
   }
+  DirSDict::Iterator ddi(*Doxygen::directories);
+  DirDef *dd = 0;
+  for (ddi.toFirst();(dd=ddi.current());++ddi)
+  {
+    QCString name = dd->getOutputFileBase();
+    //if (dd->getGroupDef())
+    //{
+    //  name = dd->getGroupDef()->getOutputFileBase();
+    //}
+    LockingPtr< QList<ListItemInfo> > xrefItems = dd->xrefListItems();
+    addRefItem(xrefItems.pointer(),
+        theTranslator->trDir(TRUE,TRUE),
+        name,dd->displayName());
+  }
 }
 
 //----------------------------------------------------------------------
@@ -5207,9 +5217,13 @@ static void findMember(EntryNav *rootNav,
     isRelated=TRUE;
     isMemberOf=(root->relatesType == MemberOf);
     if (getClass(root->relates)==0 && !scopeName.isEmpty())
+    {
       scopeName= mergeScopes(scopeName,root->relates);
+    }
     else 
+    {
       scopeName = root->relates;
+    }
   }
 
   if (root->relates.isEmpty() && rootNav->parent() && 
@@ -5285,7 +5299,8 @@ static void findMember(EntryNav *rootNav,
     {
       scopeName=namespaceName;
     }
-    else if (!getClass(className)) // class name only exists in a namespace
+    else if (!root->relates.isEmpty() || // relates command with explicit scope
+             !getClass(className)) // class name only exists in a namespace
     {
       scopeName=namespaceName+"::"+className;
     }
@@ -5741,7 +5756,7 @@ static void findMember(EntryNav *rootNav,
     {
       Debug::print(Debug::FindMembers,0,"2. related function\n"
               "  scopeName=%s className=%s\n",scopeName.data(),className.data());
-      if (className.isEmpty()) className=root->relates.copy();
+      if (className.isEmpty()) className=root->relates;
       ClassDef *cd;
       //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data());
       if ((cd=getClass(scopeName)))
@@ -7661,6 +7676,7 @@ static void findDirDocumentation(EntryNav *rootNav)
       //printf("Match for with dir %s\n",matchingDir->name().data());
       matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
       matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
+      matchingDir->setRefItems(root->sli);
       addDirToGroups(root,matchingDir);
     }
     else
@@ -7731,7 +7747,7 @@ static void findMainPage(EntryNav *rootNav)
           indexName,
           Doxygen::mainPage->name(),
           Doxygen::mainPage->title(),
-          SectionInfo::Section);
+          SectionInfo::Page);
       Doxygen::sectionDict.insert(indexName,si);
       Doxygen::mainPage->addSectionsToDefinition(root->anchors);
     }
@@ -9057,7 +9073,7 @@ void readConfiguration(int argc, char **argv)
         genLayout=TRUE;
         layoutName=getArg(argc,argv,optind);
         if (!layoutName)
-        { layoutName="doxygenlayout.xml"; }
+        { layoutName="DoxygenLayout.xml"; }
         break;
       case 'd':
         debugLabel=getArg(argc,argv,optind);
@@ -9611,7 +9627,7 @@ void parseInput()
   bool defaultLayoutUsed = FALSE;
   if (layoutFileName.isEmpty())
   {
-    layoutFileName = "doxygenlayout.xml";
+    layoutFileName = "DoxygenLayout.xml";
     defaultLayoutUsed = TRUE;
   }
 
diff --git a/src/doxygen.h b/src/doxygen.h
index 4a8430e..034389f 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -43,7 +43,6 @@ class PageSList;
 class PageSDict;
 class PageDef;
 class SearchIndex;
-class DirDef;
 class ParserManager;
 class ObjCache;
 class Store;
@@ -130,6 +129,7 @@ class Doxygen
     static bool                      gatherDefines;
     static bool                      userComments;
     static IndexList                 indexList;
+    static int                       subpageNestingLevel;
 };
 
 void initDoxygen();
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index bcc462c..500651b 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -806,11 +806,11 @@ void HtmlGenerator::startDoxyAnchor(const char *,const char *,
 {
   t << "<a class=\"anchor\" name=\"" << anchor << "\"></a>";
   t << "<!-- doxytag: member=\"";
-  docify(name); 
+  docify(name,TRUE); 
   t << "\" ref=\""; 
-  docify(anchor); 
+  docify(anchor,TRUE); 
   t << "\" args=\"";
-  docify(args);
+  docify(args,TRUE);
   t << "\" -->";
 }
 
@@ -1030,6 +1030,11 @@ void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type)
 
 void HtmlGenerator::docify(const char *str)
 {
+  docify(str,FALSE);
+}
+
+void HtmlGenerator::docify(const char *str,bool inHtmlComment)
+{
   if (str)
   {
     const char *p=str;
@@ -1043,6 +1048,7 @@ void HtmlGenerator::docify(const char *str)
         case '>':  t << "&gt;"; break;
         case '&':  t << "&amp;"; break;
         case '"':  t << "&quot;"; break;
+        case '-':  if (inHtmlComment) t << "&#45;"; else t << "-"; break;
         case '\\':
                    if (*p=='<')
                      { t << "&lt;"; p++; }
diff --git a/src/htmlgen.h b/src/htmlgen.h
index 9f97d35..9e012c8 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -247,6 +247,7 @@ class HtmlGenerator : public OutputGenerator
     QCString lastTitle;
     QCString lastFile;
     QCString relPath;
+    void docify(const char *text,bool inHtmlComment);
 
     HtmlGenerator &operator=(const HtmlGenerator &g);
     HtmlGenerator(const HtmlGenerator &g);
diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp
index 0944c15..2a48662 100644
--- a/src/htmlhelp.cpp
+++ b/src/htmlhelp.cpp
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <qlist.h>
 #include <qdict.h>
+#include <qregexp.h>
 #include "qtextcodec.h"
 
 #include "htmlhelp.h"
@@ -117,6 +118,10 @@ void HtmlHelpIndex::addItem(const char *level1,const char *level2,
 {
   QCString key = level1; 
   if (level2) key+= (QCString)"?" + level2;
+  if (key.find(QRegExp("@[0-9]+"))!=-1) // skip anonymous stuff
+  {
+    return;
+  }
   if (dict->find(key)==0) // new key
   {
     //printf(">>>>>>>>> HtmlHelpIndex::addItem(%s,%s,%s,%s)\n",
diff --git a/src/layout.cpp b/src/layout.cpp
index 3a9949c..85b200f 100644
--- a/src/layout.cpp
+++ b/src/layout.cpp
@@ -32,6 +32,27 @@ static const char layout_default[] =
 #include "layout_default.h"
 ;
 
+static bool elemIsVisible(const QXmlAttributes &attrib,bool defVal=TRUE)
+{
+  QCString visible = convertToQCString(attrib.value("visible"));
+  if (visible.isEmpty()) return defVal;
+  if (visible.at(0)=='$' && visible.length()>1)
+  {
+    QCString id = visible.mid(1);
+    ConfigOption *opt = Config::instance()->get(id);
+    if (opt && opt->kind()==ConfigOption::O_Bool)
+    {
+      return *((ConfigBool *)opt)->valueRef();
+    }
+    else if (!opt)
+    {
+      err("Warning: found unsupported value %s for visible attribute in layout file\n",
+          visible.data());
+    }
+  }
+  return visible!="no" && visible!="0";
+}
+
 //---------------------------------------------------------------------------------
 
 LayoutNavEntry *LayoutNavEntry::find(LayoutNavEntry::Kind kind) const
@@ -658,8 +679,7 @@ class LayoutParser : public QXmlDefaultHandler
 
     void startSimpleEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib)
     {
-      QCString visible = convertToQCString(attrib.value("visible"));
-      bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0");
+      bool isVisible = elemIsVisible(attrib);
       if (m_part!=-1 && isVisible)
       {
         LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
@@ -670,8 +690,7 @@ class LayoutParser : public QXmlDefaultHandler
     void startSectionEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib,
                            const QCString &title)
     {
-      QCString visible = convertToQCString(attrib.value("visible"));
-      bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0");
+      bool isVisible = elemIsVisible(attrib);
       QCString userTitle = convertToQCString(attrib.value("title"));
       //printf("startSectionEntry: title='%s' userTitle='%s'\n",
       //    title.data(),userTitle.data());
@@ -704,8 +723,6 @@ class LayoutParser : public QXmlDefaultHandler
     void startMemberDefEntry(const QXmlAttributes &attrib,MemberList::ListType type,
                              const QCString &title,const QCString &)
     {
-      //QCString visible = convertToQCString(attrib.value("visible"));
-      //bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0");
       QCString userTitle = convertToQCString(attrib.value("title"));
       if (userTitle.isEmpty()) userTitle = title;
       //printf("memberdef: %s\n",userTitle.data());
diff --git a/src/layout_default.h b/src/layout_default.h
index 1067d12..dc1c087 100644
--- a/src/layout_default.h
+++ b/src/layout_default.h
@@ -25,9 +25,9 @@
 "  <!-- Layout definition for a class page -->\n"
 "  <class>\n"
 "    <briefdescription visible=\"yes\"/>\n"
-"    <includes visible=\"yes\"/>\n"
-"    <inheritancegraph visible=\"yes\"/>\n"
-"    <collaborationgraph visible=\"yes\"/>\n"
+"    <includes visible=\"$SHOW_INCLUDE_FILES\"/>\n"
+"    <inheritancegraph visible=\"$CLASS_GRAPH\"/>\n"
+"    <collaborationgraph visible=\"$COLLABORATION_GRAPH\"/>\n"
 "    <allmemberslink visible=\"yes\"/>\n"
 "    <memberdecl>\n"
 "      <membergroups visible=\"yes\"/>\n"
@@ -72,7 +72,7 @@
 "      <properties title=\"\"/>\n"
 "      <events title=\"\"/>\n"
 "    </memberdef>\n"
-"    <usedfiles visible=\"yes\"/>\n"
+"    <usedfiles visible=\"$SHOW_USED_FILES\"/>\n"
 "    <authorsection visible=\"yes\"/>\n"
 "  </class>\n"
 "\n"
@@ -101,9 +101,9 @@
 "  <!-- Layout definition for a file page -->\n"
 "  <file>\n"
 "    <briefdescription visible=\"yes\"/>\n"
-"    <includes visible=\"yes\"/>\n"
-"    <includegraph visible=\"yes\"/>\n"
-"    <includedbygraph visible=\"yes\"/>\n"
+"    <includes visible=\"$SHOW_INCLUDE_FILES\"/>\n"
+"    <includegraph visible=\"$INCLUDE_GRAPH\"/>\n"
+"    <includedbygraph visible=\"$INCLUDED_BY_GRAPH\"/>\n"
 "    <sourcelink visible=\"yes\"/>\n"
 "    <memberdecl>\n"
 "      <classes visible=\"yes\" title=\"\"/>\n"
@@ -128,7 +128,7 @@
 "  <!-- Layout definition for a group page -->\n"
 "  <group>\n"
 "    <briefdescription visible=\"yes\"/>\n"
-"    <groupgraph visible=\"yes\"/>\n"
+"    <groupgraph visible=\"$GROUP_GRAPHS\"/>\n"
 "    <memberdecl>\n"
 "      <classes visible=\"yes\" title=\"\"/>\n"
 "      <namespaces visible=\"yes\" title=\"\"/>\n"
diff --git a/src/layout_default.xml b/src/layout_default.xml
index 6532a9e..82404f4 100644
--- a/src/layout_default.xml
+++ b/src/layout_default.xml
@@ -25,9 +25,9 @@
   <!-- Layout definition for a class page -->
   <class>
     <briefdescription visible="yes"/>
-    <includes visible="yes"/>
-    <inheritancegraph visible="yes"/>
-    <collaborationgraph visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <inheritancegraph visible="$CLASS_GRAPH"/>
+    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
     <allmemberslink visible="yes"/>
     <memberdecl>
       <membergroups visible="yes"/>
@@ -72,7 +72,7 @@
       <properties title=""/>
       <events title=""/>
     </memberdef>
-    <usedfiles visible="yes"/>
+    <usedfiles visible="$SHOW_USED_FILES"/>
     <authorsection visible="yes"/>
   </class>
 
@@ -101,9 +101,9 @@
   <!-- Layout definition for a file page -->
   <file>
     <briefdescription visible="yes"/>
-    <includes visible="yes"/>
-    <includegraph visible="yes"/>
-    <includedbygraph visible="yes"/>
+    <includes visible="$SHOW_INCLUDE_FILES"/>
+    <includegraph visible="$INCLUDE_GRAPH"/>
+    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
     <sourcelink visible="yes"/>
     <memberdecl>
       <classes visible="yes" title=""/>
@@ -128,7 +128,7 @@
   <!-- Layout definition for a group page -->
   <group>
     <briefdescription visible="yes"/>
-    <groupgraph visible="yes"/>
+    <groupgraph visible="$GROUP_GRAPHS"/>
     <memberdecl>
       <classes visible="yes" title=""/>
       <namespaces visible="yes" title=""/>
diff --git a/src/memberlist.cpp b/src/memberlist.cpp
index d6b389b..e2ffedb 100644
--- a/src/memberlist.cpp
+++ b/src/memberlist.cpp
@@ -26,6 +26,7 @@
 #include "outputlist.h"
 #include "groupdef.h"
 #include "marshal.h"
+#include "vhdldocgen.h"
 
 MemberList::MemberList()
 {
@@ -319,6 +320,8 @@ void MemberList::writeDeclarations(OutputList &ol,
              /*, bool inGroup,bool countSubGroups*/)
 {
   //printf("----- writeDeclaration() this=%p ----\n",this);
+  static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+
   countDecMembers(showEnumValues); // count member not in group
   Definition *ctx = cd;
   if (ctx==0 && nd) ctx = nd;
@@ -342,7 +345,21 @@ void MemberList::writeDeclarations(OutputList &ol,
     ol.endMemberSubtitle();
   }
 
-  writePlainDeclarations(ol,cd,nd,fd,gd);
+  // TODO: Two things need to be worked out for proper VHDL output:
+  // 1. Signals and types under the group need to be
+  //    formatted to associate them with the group somehow
+  //    indentation, or at the very least, extra space after
+  //    the group is done
+  // 2. This might need to be repeated below for memberGroupLists
+  if (optimizeVhdl) // use specific declarations function
+  {
+    VhdlDocGen::writeVhdlDeclarations(this,ol,0,cd);
+  }
+  else
+  {
+    writePlainDeclarations(ol,cd,nd,fd,gd);
+  }
+ 
   
   //printf("memberGroupList=%p\n",memberGroupList);
   if (memberGroupList)
diff --git a/src/pagedef.cpp b/src/pagedef.cpp
index 2f59f2a..cf2c21a 100644
--- a/src/pagedef.cpp
+++ b/src/pagedef.cpp
@@ -75,7 +75,7 @@ void PageDef::writeDocumentation(OutputList &ol)
   else
     pageName=name().lower();
 
-  startFile(ol,pageName,pageName,title(),HLI_None,TRUE);
+  startFile(ol,pageName,pageName,title(),HLI_Pages,TRUE);
 
   ol.pushGeneratorState();
   //1.{ 
@@ -200,7 +200,9 @@ void PageDef::writePageDocumentation(OutputList &ol)
       ol.startSection(subPage->name(),title,sectionType);
       ol.parseText(title);
       ol.endSection(subPage->name(),sectionType);
+      Doxygen::subpageNestingLevel++;
       subPage->writePageDocumentation(ol);
+      Doxygen::subpageNestingLevel--;
     }
 
     ol.popGeneratorState();
diff --git a/src/pre.l b/src/pre.l
index 0917d3a..ffb447e 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -222,7 +222,7 @@ static FILE *findFile(const char *fileName,bool localInclude)
     QFileInfo fi(g_yyFileName);
     if (fi.exists())
     {
-      QCString absName = QCString(fi.dirPath().data())+"/"+fileName;
+      QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+fileName;
       FILE *f = checkAndOpenFile(absName);
       if (f)
       {
@@ -1152,7 +1152,7 @@ static void readIncludeFile(const QCString &inc)
 
       // Deal with file changes due to 
       // #include's within { .. } blocks
-      QCString lineStr;
+      QCString lineStr(g_yyFileName.length()+20);
       lineStr.sprintf("# 1 \"%s\" 1\n",g_yyFileName.data());
       outputArray(lineStr.data(),lineStr.length());
       
diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp
index da7b062..9bb5888 100644
--- a/src/rtfdocvisitor.cpp
+++ b/src/rtfdocvisitor.cpp
@@ -1203,6 +1203,26 @@ void RTFDocVisitor::visitPre(DocParamList *pl)
 {
   if (m_hide) return;
   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamList)}\n");
+
+  // Put in the direction: in/out/in,out if specified.
+  if (pl->direction()!=DocParamSect::Unspecified)
+  {
+    m_t << "[";
+    if (pl->direction()==DocParamSect::In)
+    {
+      m_t << "in";
+    }
+    else if (pl->direction()==DocParamSect::Out)
+    {
+      m_t << "out";
+    }
+    else if (pl->direction()==DocParamSect::InOut)
+    {
+      m_t << "in,out";
+    }
+    m_t << "] ";
+  }
+
   m_t << "{\\i ";
   //QStrListIterator li(pl->parameters());
   //const char *s;
diff --git a/src/scanner.l b/src/scanner.l
index b102853..3bd0fad 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -559,27 +559,17 @@ BN        [ \t\n\r]
 BL        [ \t\r]*"\n" 
 B         [ \t]
 BS        ^(({B}*"//")?)(({B}*"*"+)?){B}*
-FILESCHAR [a-z_A-Z0-9\\:\\\/\-\+]
-FILEECHAR [a-z_A-Z0-9\-\+]
+FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+]
+FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+]
 FILE      ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]+"\"")
-ID        "$"?[a-z_A-Z][a-z_A-Z0-9]*
-LABELID   [a-z_A-Z][a-z_A-Z0-9\-]*
+ID        "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
 SCOPEID   {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
 SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID})
 TSCOPE    {ID}("<"[a-z_A-Z0-9 \t\*\&,]*">")?
 FTSCOPE   {ID}("<"[a-z_A-Z0-9\*\&,]*">")?
 CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID})
-ATTR      ({B}+[^>\n]*)?
-A         [aA]
-BR	  [bB][rR]
 PRE       [pP][rR][eE]
 CODE      [cC][oO][dD][eE]
-TABLE	  [tT][aA][bB][lL][eE]
-P	  [pP]
-UL        [uU][lL]
-OL	  [oO][lL]
-DL	  [dD][lL]
-TITLE     [tT][iI][tT][lL][eE]
 CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'"))
 PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 IDLATTR   ("["[^\]]*"]"){BN}*
@@ -795,12 +785,19 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
 					  else
 					    REJECT;
                                         }
-
 <FindMembers>{PHPKW}			{ if (insidePHP)
 					    BEGIN( NextSemi );
 					  else
 					    REJECT;
 					}
+<FindMembers>"%{"[^\n]*			{ // Mozilla XPIDL lang-specific block
+					  if (!insideIDL)
+					    REJECT;
+					}
+<FindMembers>"%}"			{ // Mozilla XPIDL lang-specific block end
+					  if (!insideIDL)
+					    REJECT;
+					}
 <FindMembers>{B}*("properties"){BN}*":"{BN}*  { // IDL or Borland C++ builder property 
   					  current->mtype = mtype = Property;
 					  current->protection = protection = Public ;
@@ -4326,11 +4323,11 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
 					  current->spec |= Entry::Template;
 					  current->tArgLists->append(al);
 					  currentArgumentList = al;
-					  current->name+="<";
+					  //current->name+="<";
 					  templateStr="<";
 					  fullArgString = templateStr;
-					  copyArgString = &current->name;
-					  currentArgumentContext = CompoundName;
+					  copyArgString = &current->args;
+					  currentArgumentContext = ClassVar;
 					  BEGIN( ReadTempArgs );
   					}
 <ObjCProtocolList>"<"			{
@@ -4464,6 +4461,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
 					    lastCSConstraint = YY_START;
 					    BEGIN( CSConstraintName );
 					  }
+					  else if (insideCli &&  strcmp(yytext,"abstract"))
+					  {
+					    current->spec|=Entry::Abstract;
+					  }
+					  else if (insideCli &&  strcmp(yytext,"sealed"))
+					  {
+					    current->spec|=Entry::Sealed;
+					  }
 					  else
 					  {
 					    if (current->section == Entry::ENUM_SEC)
@@ -4672,9 +4677,22 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
 <BasesProt>{BN}				{ lineCount(); }
 <BasesProt>.				{ unput(*yytext); BEGIN(Bases); }
 <Bases>("::")?{BN}*({ID}{BN}*"::"{BN}*)*{ID}	{ 
-  					  baseName+=yytext;
-					  current->args += ' ';
-					  current->args += yytext;
+                                          QCString baseScope = yytext;
+                                          if (insideCS && baseScope.stripWhiteSpace()=="where")
+					  { 
+					    // type contraint for a class
+                                            delete current->typeConstr;
+                                            current->typeConstr = new ArgumentList;
+					    current->typeConstr->append(new Argument);
+					    lastCSConstraint = YY_START;
+					    BEGIN( CSConstraintName );
+					  }
+					  else
+					  {
+  					    baseName+=yytext;
+					    current->args += ' ';
+					    current->args += yytext;
+					  }
 					}
 <Bases>{BN}*{ID}("."{ID})*		{ // Java style class
     					  QCString name = substitute(yytext,".","::");
diff --git a/src/util.cpp b/src/util.cpp
index 4c2e628..945f48a 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -116,13 +116,6 @@ void TextGeneratorOLImpl::writeLink(const char *extRef,const char *file,
 // an inheritance tree of depth of 100000 should be enough for everyone :-)
 const int maxInheritanceDepth = 100000; 
 
-bool isId(int c)
-{
-  if (c<0 || c>255) return FALSE;
-  return c=='_' || isalnum(c);
-}
-
-
 /*! 
   Removes all anoymous scopes from string s
   Possible examples:
@@ -1504,7 +1497,13 @@ QCString removeRedundantWhiteSpace(const QCString &s)
 {
   static bool cliSupport = Config_getBool("CPP_CLI_SUPPORT");
   if (s.isEmpty()) return s;
-  QCString result;
+  int resultLen = 1024;
+  int resultPos = 0;
+  QCString result(resultLen);
+  // we use ADD_CHAR(c) instead of result+=c to 
+  // improve the performance of this function
+#define ADD_CHAR(c) if (resultPos>=resultLen) { resultLen+=1024; result.resize(resultLen); } \
+                    result[resultPos++]=(c)
   uint i;
   uint l=s.length();
   uint csp=0;
@@ -1539,13 +1538,16 @@ nextChar:
     if (c=='"') // quoted string
     {
       i++;
-      result+=c;
+      ADD_CHAR(c);
       while (i<l)
       {
         char cc=s.at(i);
-        result+=cc;
+        ADD_CHAR(cc);
         if (cc=='\\') // escaped character
-        { result+=s.at(i+1); i+=2; }
+        { 
+          ADD_CHAR(s.at(i+1));
+          i+=2; 
+        }
         else if (cc=='"') // end of string
         { i++; goto nextChar; }
         else // any other character
@@ -1557,21 +1559,24 @@ nextChar:
         (i<8 || !findOperator(s,i)) // string in front is not "operator"
         )
     {
-      result+="< "; // insert extra space for layouting (nested) templates
+      ADD_CHAR('<');
+      ADD_CHAR(' ');
     }
     else if (i>0 && c=='>' && // current char is a >
         (isId(s.at(i-1)) || isspace((uchar)s.at(i-1)) || s.at(i-1)=='*' || s.at(i-1)=='&') && // prev char is an id char or space
         (i<8 || !findOperator(s,i)) // string in front is not "operator"
         )
     {
-      result+=" >"; // insert extra space for layouting (nested) templates
+      ADD_CHAR(' ');
+      ADD_CHAR('>');
     }
     else if (i>0 && c==',' && !isspace((uchar)s.at(i-1))
         && ((i<l-1 && isId(s.at(i+1)))
           || (i<l-2 && s.at(i+1)=='$' && isId(s.at(i+2)))  // for PHP
           || (i<l-3 && s.at(i+1)=='&' && s.at(i+2)=='$' && isId(s.at(i+3)))))  // for PHP
     {
-      result+=", ";
+      ADD_CHAR(',');
+      ADD_CHAR(' ');
     }
     else if (i>0 && 
         ((isId(s.at(i)) && s.at(i-1)==')') || 
@@ -1579,8 +1584,8 @@ nextChar:
         )
         )
     {
-      result+=' ';
-      result+=s.at(i);
+      ADD_CHAR(' ');
+      ADD_CHAR(s.at(i));
     }
     else if (c=='t' && csp==5 /*&& (i<5 || !isId(s.at(i-5)))*/ &&
              !(isId(s.at(i+1)) /*|| s.at(i+1)==' '*/ || 
@@ -1591,14 +1596,16 @@ nextChar:
             ) 
       // prevent const ::A from being converted to const::A
     {
-      result+="t ";
+      ADD_CHAR('t');
+      ADD_CHAR(' ');
       if (s.at(i+1)==' ') i++;
       csp=0;
     }
     else if (c==':' && csp==6 /*&& (i<6 || !isId(s.at(i-6)))*/) 
       // replace const::A by const ::A
     {
-      result+=" :";
+      ADD_CHAR(' ');
+      ADD_CHAR(':');
       csp=0;
     }
     else if (c=='l' && vsp==7 /*&& (i<7 || !isId(s.at(i-7)))*/ &&
@@ -1610,14 +1617,16 @@ nextChar:
             ) 
       // prevent virtual ::A from being converted to virtual::A
     {
-      result+="l ";
+      ADD_CHAR('l');
+      ADD_CHAR(' ');
       if (s.at(i+1)==' ') i++;
       vsp=0;
     }
     else if (c==':' && vsp==8 /*&& (i<8 || !isId(s.at(i-8)))*/) 
       // replace virtual::A by virtual ::A
     {
-      result+=" :";
+      ADD_CHAR(' ');
+      ADD_CHAR(':');
       vsp=0;
     }
     else if (!isspace((uchar)c) || // not a space
@@ -1630,19 +1639,25 @@ nextChar:
     {
       if (c=='*' || c=='&' || c=='@' || c=='$')
       {  
-        uint rl=result.length();
+        //uint rl=result.length();
+        uint rl=resultPos;
         if ((rl>0 && (isId(result.at(rl-1)) || result.at(rl-1)=='>')) &&
             (c!='*' || !findOperator2(s,i)) // avoid splitting operator* and operator->*
            ) 
         {
-          result+=' ';
+          ADD_CHAR(' ');
         }
       }
-      result+=c;
-      if (cliSupport && (c=='^' || c=='%') && i>1 && isId(s.at(i-1))) result+=' '; // C++/CLI: Type^ name and Type% name
+      ADD_CHAR(c);
+      if (cliSupport && (c=='^' || c=='%') && i>1 && isId(s.at(i-1))) 
+      {
+        ADD_CHAR(' '); // C++/CLI: Type^ name and Type% name
+      }
     }
   }
   //printf("removeRedundantWhiteSpace(`%s')=`%s'\n",s.data(),result.data());
+  ADD_CHAR(0);
+  result.resize(resultPos);
   return result;
 }  
 
@@ -1671,7 +1686,7 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope,
     bool keepSpaces)
 {
   //printf("`%s'\n",text);
-  static QRegExp regExp("[a-z_A-Z][~!a-z_A-Z0-9.:]*");
+  static QRegExp regExp("[a-z_A-Z\\x80-\\xFF][~!a-z_A-Z0-9.:\\x80-\\xFF]*");
   static QRegExp regExpSplit("(?!:),");
   QCString txtStr=text;
   int strLen = txtStr.length();
@@ -3180,7 +3195,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type)
   //printf("extractCanonicalType(type=%s) start: def=%s file=%s\n",type.data(),
   //    d ? d->name().data() : "<null>",fs ? fs->name().data() : "<null>");
 
-  static QRegExp id("[a-z_A-Z][:a-z_A-Z0-9]*");
+  static QRegExp id("[a-z_A-Z\\x80-\\xFF][:a-z_A-Z0-9\\x80-\\xFF]*");
 
   QCString canType,templSpec,word;
   int i,p=0,pp=0;
@@ -3197,7 +3212,7 @@ static QCString extractCanonicalType(Definition *d,FileDef *fs,QCString type)
                               // (i.e. type is not a template specialization)
                               // then resolve any identifiers inside. 
     {
-      static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
+      static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
       int tp=0,tl,ti;
       // for each identifier template specifier
       //printf("adding resolved %s to %s\n",templSpec.data(),canType.data());
@@ -3304,6 +3319,7 @@ bool matchArguments2(Definition *srcScope,FileDef *srcFileScope,ArgumentList *sr
     bool checkCV
     )
 {
+  //printf("*** matchArguments2\n");
   ASSERT(srcScope!=0 && dstScope!=0);
 
   if (srcAl==0 || dstAl==0)
@@ -4024,7 +4040,8 @@ bool resolveRef(/* in */  const char *scName,
     /* in */  const char *name,
     /* in */  bool inSeeBlock,
     /* out */ Definition **resContext,
-    /* out */ MemberDef  **resMember
+    /* out */ MemberDef  **resMember,
+    bool lookForSpecialization
     )
 {
   QCString tsName = name;
@@ -4087,10 +4104,21 @@ bool resolveRef(/* in */  const char *scName,
   // strip template specifier
   // TODO: match against the correct partial template instantiation 
   int templPos=nameStr.find('<');
+  bool tryUnspecializedVersion = FALSE;
   if (templPos!=-1 && nameStr.find("operator")==-1)
   {
     int endTemplPos=nameStr.findRev('>');
-    nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
+    if (endTemplPos!=-1)
+    {
+      if (!lookForSpecialization)
+      {
+        nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
+      }
+      else
+      {
+        tryUnspecializedVersion = TRUE;
+      }
+    }
   }
 
   QCString scopeStr=scName;
@@ -4138,6 +4166,11 @@ bool resolveRef(/* in */  const char *scName,
     }
   }
 
+  if (tryUnspecializedVersion)
+  {
+    return resolveRef(scName,name,inSeeBlock,resContext,resMember,FALSE);
+  }
+
   return FALSE;
 }
 
@@ -4414,18 +4447,34 @@ QCString substituteClassNames(const QCString &s)
 
 QCString substitute(const char *s,const char *src,const char *dst)
 {
-  // TODO: optimize by using strstr() instead of find
-  QCString input=s;
-  QCString output;
-  int i=0,p;
-  while ((p=input.find(src,i))!=-1)
+  if (s==0 || src==0 || dst==0) return s;
+  const char *p, *q;
+  int srcLen = strlen(src);
+  int dstLen = strlen(dst);
+  int resLen;
+  if (srcLen!=dstLen)
   {
-    output+=input.mid(i,p-i);
-    output+=dst;
-    i=p+strlen(src);
+    int count;
+    for (count=0, p=s; (q=strstr(p,src))!=0; p=q+srcLen) count++;
+    resLen = p-s+strlen(p)+count*(dstLen-srcLen);
   }
-  output+=input.mid(i,input.length()-i);
-  return output;
+  else // result has same size as s
+  {
+    resLen = strlen(s);
+  }
+  QCString result(resLen+1);
+  char *r;
+  for (r=result.data(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
+  {
+    int l = (int)(q-p);
+    memcpy(r,p,l);
+    r+=l;
+    memcpy(r,dst,dstLen);
+    r+=dstLen;
+  }
+  strcpy(r,p);
+  //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data());
+  return result;
 }
 
 //----------------------------------------------------------------------
@@ -4667,7 +4716,19 @@ QCString escapeCharsInString(const char *name,bool allowDots)
       case '+': result+="_09"; break;
       case '=': result+="_0A"; break;
       default: 
-                if (caseSenseNames || !isupper(c))
+                if (c<0)
+                {
+                  static char map[] = "0123456789ABCDEF";
+                  char ids[5];
+                  unsigned char id = (unsigned char)c;
+                  ids[0]='_';
+                  ids[1]='x';
+                  ids[2]=map[id>>4];
+                  ids[3]=map[id&0xF];
+                  ids[4]=0;
+                  result+=ids;
+                }
+                else if (caseSenseNames || !isupper(c))
                 {
                   result+=c;
                 }
@@ -5280,7 +5341,7 @@ void addMembersToMemberGroup(MemberList *ml,
  */
 int extractClassNameFromType(const QCString &type,int &pos,QCString &name,QCString &templSpec)
 {
-  static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
+  static const QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9:\\x80-\\xFF]*");
   name.resize(0);
   templSpec.resize(0);
   int i,l;
@@ -5347,7 +5408,7 @@ QCString substituteTemplateArgumentsInString(
   //    name.data(),argListToString(formalArgs).data(),argListToString(actualArgs).data());
   if (formalArgs==0) return name;
   QCString result;
-  static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
+  static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
   int p=0,l,i;
   // for each identifier in the base class name (e.g. B<T> -> B and T)
   while ((i=re.match(name,p,&l))!=-1)
@@ -6208,7 +6269,7 @@ QCString stripPath(const char *s)
 /** returns \c TRUE iff string \a s contains word \a w */
 bool containsWord(const QCString &s,const QCString &word)
 {
-  static QRegExp wordExp("[a-z_A-Z]+");
+  static QRegExp wordExp("[a-z_A-Z\\x80-\\xFF]+");
   int p=0,i,l;
   while ((i=wordExp.match(s,p,&l))!=-1)
   {
@@ -6220,7 +6281,7 @@ bool containsWord(const QCString &s,const QCString &word)
 
 bool findAndRemoveWord(QCString &s,const QCString &word)
 {
-  static QRegExp wordExp("[a-z_A-Z]+");
+  static QRegExp wordExp("[a-z_A-Z\\x80-\\xFF]+");
   int p=0,i,l;
   while ((i=wordExp.match(s,p,&l))!=-1)
   {
@@ -6284,7 +6345,7 @@ void stringToSearchIndex(const QCString &docBaseUrl,const QCString &title,
   if (searchEngine)
   {
     Doxygen::searchIndex->setCurrentDoc(title,docBaseUrl,anchor);
-    static QRegExp wordPattern("[a-z_A-Z][a-z_A-Z0-9]*");
+    static QRegExp wordPattern("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
     int i,p=0,l;
     while ((i=wordPattern.match(str,p,&l))!=-1)
     {
diff --git a/src/util.h b/src/util.h
index c2ac2d9..e836e0e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -135,7 +135,8 @@ bool resolveRef(/* in */  const char *scName,
                 /* in */  const char *name,
                 /* in */  bool inSeeBlock,
                 /* out */ Definition **resContext,
-                /* out */ MemberDef  **resMember
+                /* out */ MemberDef  **resMember,
+                /* in */  bool lookForSpecializations = TRUE
                );
 
 bool resolveLink(/* in */  const char *scName,
@@ -191,7 +192,10 @@ QCString showFileDefMatches(const FileNameDict *fnDict,const char *n);
 
 int guessSection(const char *name);
 
-bool isId(int c);
+inline bool isId(int c)
+{
+  return c=='_' || isalnum(c) || c>=128 || c<0;
+}
 
 QCString removeRedundantWhiteSpace(const QCString &s);
 
-- 
cgit v0.12

