From 104be290eb99ab3277906a57fb4673dfa1850bc6 Mon Sep 17 00:00:00 2001
From: dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>
Date: Mon, 15 Dec 2003 18:58:39 +0000
Subject: Release-1.3.5-20031215

---
 INSTALL                   |   2 +-
 README                    |   2 +-
 configure                 |  25 +-
 doc/index.doc             |  14 +-
 doc/language.doc          |   6 +-
 make.bat                  | 120 +++----
 packages/rpm/doxygen.spec | 153 --------
 qtools/qcache.h           | 104 ++++++
 qtools/qgcache.cpp        | 868 ++++++++++++++++++++++++++++++++++++++++++++++
 qtools/qgcache.h          | 128 +++++++
 qtools/qtools.pro.in      |   3 +
 src/config.l              |   7 +-
 src/dot.cpp               |   2 +-
 src/entry.cpp             |   2 +
 src/entry.h               |   1 +
 src/htmldocvisitor.cpp    |   8 +-
 src/htmlgen.cpp           | 126 ++++---
 src/lang_cfg.h            |   1 +
 src/language.cpp          |   7 +
 src/latexgen.cpp          |   4 +-
 src/libdoxygen.pro.in     |   3 +-
 src/pre.l                 |  84 ++++-
 src/scanner.l             | 198 +++++++++--
 src/translator_ke.h       |  50 +++
 src/translator_sr.h       | 118 +++++--
 src/util.cpp              | 146 ++++++--
 src/xmlgen.cpp            |   2 +-
 wintools/Doxygen.dsp      |   8 -
 28 files changed, 1800 insertions(+), 392 deletions(-)
 create mode 100644 qtools/qcache.h
 create mode 100644 qtools/qgcache.cpp
 create mode 100644 qtools/qgcache.h
 create mode 100644 src/translator_ke.h

diff --git a/INSTALL b/INSTALL
index 273c62c..24a222b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -4,4 +4,4 @@ Please read the installation section of the manual
 (http://www.doxygen.org/install.html) for instructions.
 
 --------
-Dimitri van Heesch (21 November 2003)
+Dimitri van Heesch (14 December 2003)
diff --git a/README b/README
index 2025ad2..cdee277 100644
--- a/README
+++ b/README
@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
 
 Enjoy,
 
-Dimitri van Heesch (dimitri@stack.nl) (21 November 2003)
+Dimitri van Heesch (dimitri@stack.nl) (14 December 2003)
diff --git a/configure b/configure
index df7b481..1d0e39f 100755
--- a/configure
+++ b/configure
@@ -27,7 +27,7 @@ f_prefix=/usr
 f_insttool=NO
 f_english=NO
 f_wizard=NO
-f_langs=nl,se,cz,fr,it,de,jp,je,es,fi,ru,hr,pl,pt,hu,kr,ro,si,cn,no,br,dk,sk,ua,gr,tw,sr,ca
+f_langs=nl,se,cz,fr,it,de,jp,je,es,fi,ru,hr,pl,pt,hu,kr,ke,ro,si,cn,no,br,dk,sk,ua,gr,tw,sr,ca
 
 while test -n "$1";  do
   case $1 in
@@ -225,6 +225,27 @@ fi
  
 if test "$f_wizard" = YES; then
   echo -n "  Checking for Qt..."
+  if test -d "/usr/lib/qt3/lib"; then
+    if test -d "/usr/lib/qt3/include"; then
+      if test -x "/usr/lib/qt3/bin/moc"; then
+        QTDIR="/usr/lib/qt3";
+      fi
+    fi
+  fi
+  if test -d "/usr/lib/qt2/lib"; then
+    if test -d "/usr/lib/qt2/include"; then
+      if test -x "/usr/lib/qt2/bin/moc"; then
+        QTDIR="/usr/lib/qt2";
+      fi
+    fi
+  fi
+  if test -d "/usr/lib/qt/lib"; then
+    if test -d "/usr/lib/qt/include"; then
+      if test -x "/usr/lib/qt/bin/moc"; then
+        QTDIR="/usr/lib/qt";
+      fi
+    fi
+  fi
   if test -z "$QTDIR"; then
     echo "QTDIR not set!"
     echo
@@ -486,7 +507,7 @@ done
 echo -n "  Generating src/lang_cfg.h..."
 echo $f_langs | $f_perl -e '@l=split(/,/,<STDIN>); 
         chomp @l; 
-	@allowed=(NL,SE,CZ,FR,IT,DE,JP,JE,ES,FI,RU,HR,PL,PT,HU,KR,RO,SI,CN,NO,BR,
+	@allowed=(NL,SE,CZ,FR,IT,DE,JP,JE,ES,FI,RU,HR,PL,PT,HU,KR,KE,RO,SI,CN,NO,BR,
 		  DK,SK,UA,GR,TW,SR,CA);
 	foreach my $elem (@l){ 
 	     $elem =~ tr/a-z/A-Z/;
diff --git a/doc/index.doc b/doc/index.doc
index 065800c..f74b976 100644
--- a/doc/index.doc
+++ b/doc/index.doc
@@ -178,18 +178,8 @@ Thanks go to:
 <li>Ken Wong for providing the HTML tree view code.
 <li>Petr Prikryl for coordinating the internationalisation support.
     All language maintainers for providing translations into many languages.
-<li>Erik Jan Lingen of <a href="http://www.habanera.nl/">Habanera</a>, Mark
-    Roddy, Paul Schwartz, Charles Duffy, Vadym Voznyuk, Philip Walton,
-    Dwight Browne, Andreas Fredriksson, Karel Lindveld, Ivan Lee, Albert
-    Vernon, Adam McKee, Vijapurapu Anatharac, Ben Hunsberger and 
-    Walter Wartenweiler, Jeff Garbers, David Harris, Terry Brown and
-    Nicolas Reimen for donating money.
-<li>The Comms group of <a href="http://www.symbian.com">Symbian</a> for donating
-    an ultra cool <a href="http://www.psion.com/revoplus">Revo plus</a> 
-    organizer!
-<li>Steve Upstill of <a href="http://www.wetadigital.com/digital/index_flash.htm">
-    Weta Digital</a> for sending me some 
-    <a href="http://www.lordoftherings.net/">Lord of the Rings</a> goodies.
+<li>Gerald Steffens of <a href="http://www.e-trend.de">E-trend</a>
+    for financial support.
 <li>The band <a href="http://www.porcupinetree.com">Porcupine Tree</a> for 
     providing hours of great music to listen to while coding.
 <li>many, many others for suggestions, patches and bug reports.
diff --git a/doc/language.doc b/doc/language.doc
index c2d4ffd..3670cd8 100644
--- a/doc/language.doc
+++ b/doc/language.doc
@@ -25,7 +25,7 @@ Doxygen has built-in support for multiple languages. This means
 that the text fragments that doxygen generates can be produced in
 languages other than English (the default) at configuration time.
 
-Currently (version 1.3.3), 29 languages 
+Currently (version 1.3.5), 29 languages 
 are supported (sorted alphabetically): 
 Brazilian Portuguese, Catalan, Chinese, Chinese Traditional, Croatian, 
 Czech, Danish, Dutch, English, Finnish, 
@@ -157,7 +157,7 @@ when the translator was updated.
       <TD>Korean</TD>  
       <TD>Richard Kim</TD>
       <TD>ryk@NOSPAM.dspwiz.com</TD>
-      <TD>strange</TD>
+      <TD>up-to-date</TD>
   </TR>
   <TR BGCOLOR="#ffffff">
       <TD>Norwegian</TD>  
@@ -274,7 +274,7 @@ when the translator was updated.
   \hline
   JapaneseEn & unknown & {\tt unknown} & obsolete \\
   \hline
-  Korean & Richard Kim & {\tt ryk@dspwiz.com} & strange \\
+  Korean & Richard Kim & {\tt ryk@dspwiz.com} & up-to-date \\
   \hline
   Norwegian & Lars Erik Jordet & {\tt lej@circuitry.no} & 1.2.2 \\
   \hline
diff --git a/make.bat b/make.bat
index a985bea..82c90d2 100644
--- a/make.bat
+++ b/make.bat
@@ -1,60 +1,60 @@
-@echo off
-REM make script for Microsoft Visual C++
-REM ...and MINGW and Borland 5.5 also!
-
-if "%1"=="bcc"   SET CC=borland
-if "%1"=="mingw" SET CC=mingw
-if "%1"=="msvc"  SET CC=msvc
-if "%1"=="" goto USAGE
-
-if "%CC%"=="msvc"     SET MAKE=nmake
-if not "%CC%"=="msvc" SET MAKE=make
-
-SET MODE=release
-if "%2"=="debug" SET MODE=debug
-
-REM use perl to create the config file
-perl wintools\make.pl %CC%
-
-type makeconfig                   > Makefile
-type Makefile.win_%MAKE%.in       >>Makefile
-type makeconfig                   > qtools\Makefile
-type qtools\Makefile.in           >>qtools\Makefile
-type makeconfig                   > libpng\Makefile
-type libpng\Makefile.in           >>libpng\Makefile
-type makeconfig                   > libmd5\Makefile
-type libmd5\Makefile.in           >>libmd5\Makefile
-type makeconfig                   > src\Makefile
-type src\Makefile.in              >>src\Makefile
-type makeconfig                   > examples\Makefile
-type examples\Makefile.win.in     >>examples\Makefile
-type makeconfig                   > doc\Makefile
-type doc\Makefile.win_%MAKE%.in   >>doc\Makefile
-type makeconfig                   > addon\doxywizard\Makefile
-type addon\doxywizard\Makefile.win_%MAKE%.in >>addon\doxywizard\Makefile
-type makeconfig                        > addon\doxmlparser\src\Makefile
-type addon\doxmlparser\src\Makefile.in >>addon\doxmlparser\src\Makefile
-
-REM build in release or debug mode 
-REM sed is used to replace $extraopts by either debug or release while copying
-sed "s/\$extraopts/%MODE%/g" qtools\qtools.pro.in >qtools\qtools.pro
-sed "s/\$extraopts/%MODE%/g" libpng\libpng.pro.in >libpng\libpng.pro
-sed "s/\$extraopts/%MODE%/g" libmd5\libmd5.pro.in >libmd5\libmd5.pro
-sed "s/\$extraopts/%MODE%/g" src\libdoxygen.pro.in >src\libdoxygen.pro
-sed "s/\$extraopts/%MODE%/g" src\libdoxycfg.pro.in >src\libdoxycfg.pro
-sed "s/\$extraopts/%MODE%/g" src\doxygen.pro.in >src\doxygen.pro
-sed "s/\$extraopts/%MODE%/g" src\doxytag.pro.in >src\doxytag.pro
-sed "s/\$extraopts/%MODE%/g" addon\doxywizard\doxywizard.pro.in >addon\doxywizard\doxywizard.pro
-
-REM run make
-%MAKE%.exe
-goto END
-
-:USAGE
-echo "Call with '%0 [bcc|mingw|msvc] [debug]'!"
-echo "  bcc:   compile with Borland C++"
-echo "  mingw: compile with GCC for windows (see www.mingw.org)"
-echo "  msvc:  compile with Microsoft Visual C++"
-
-:END
-
+@echo off
+REM make script for Microsoft Visual C++
+REM ...and MINGW and Borland 5.5 also!
+
+if "%1"=="bcc"   SET CC=borland
+if "%1"=="mingw" SET CC=mingw
+if "%1"=="msvc"  SET CC=msvc
+if "%1"=="" goto USAGE
+
+if "%CC%"=="msvc"     SET MAKE=nmake
+if not "%CC%"=="msvc" SET MAKE=make
+
+SET MODE=release
+if "%2"=="debug" SET MODE=debug
+
+REM use perl to create the config file
+perl wintools\make.pl %CC%
+
+type makeconfig                   > Makefile
+type Makefile.win_%MAKE%.in       >>Makefile
+type makeconfig                   > qtools\Makefile
+type qtools\Makefile.in           >>qtools\Makefile
+type makeconfig                   > libpng\Makefile
+type libpng\Makefile.in           >>libpng\Makefile
+type makeconfig                   > libmd5\Makefile
+type libmd5\Makefile.in           >>libmd5\Makefile
+type makeconfig                   > src\Makefile
+type src\Makefile.in              >>src\Makefile
+type makeconfig                   > examples\Makefile
+type examples\Makefile.win.in     >>examples\Makefile
+type makeconfig                   > doc\Makefile
+type doc\Makefile.win_%MAKE%.in   >>doc\Makefile
+type makeconfig                   > addon\doxywizard\Makefile
+type addon\doxywizard\Makefile.win_%MAKE%.in >>addon\doxywizard\Makefile
+type makeconfig                        > addon\doxmlparser\src\Makefile
+type addon\doxmlparser\src\Makefile.in >>addon\doxmlparser\src\Makefile
+
+REM build in release or debug mode 
+REM sed is used to replace $extraopts by either debug or release while copying
+sed "s/\$extraopts/%MODE%/g" qtools\qtools.pro.in >qtools\qtools.pro
+sed "s/\$extraopts/%MODE%/g" libpng\libpng.pro.in >libpng\libpng.pro
+sed "s/\$extraopts/%MODE%/g" libmd5\libmd5.pro.in >libmd5\libmd5.pro
+sed "s/\$extraopts/%MODE%/g" src\libdoxygen.pro.in >src\libdoxygen.pro
+sed "s/\$extraopts/%MODE%/g" src\libdoxycfg.pro.in >src\libdoxycfg.pro
+sed "s/\$extraopts/%MODE%/g" src\doxygen.pro.in >src\doxygen.pro
+sed "s/\$extraopts/%MODE%/g" src\doxytag.pro.in >src\doxytag.pro
+sed "s/\$extraopts/%MODE%/g" addon\doxywizard\doxywizard.pro.in >addon\doxywizard\doxywizard.pro
+
+REM run make
+%MAKE%.exe
+goto END
+
+:USAGE
+echo "Call with '%0 [bcc|mingw|msvc] [debug]'!"
+echo "  bcc:   compile with Borland C++"
+echo "  mingw: compile with GCC for windows (see www.mingw.org)"
+echo "  msvc:  compile with Microsoft Visual C++"
+
+:END
+
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index 0686547..e69de29 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,153 +0,0 @@
-Summary: A documentation system for C/C++.
-Name: doxygen
-Version: 1.3.5
-Release: 1
-Epoch: 1
-Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz
-Patch: doxygen-1.2.7-redhat.patch
-Patch1: doxygen-1.2.12-qt2.patch
-Group: Development/Tools
-License: GPL
-Url: http://www.stack.nl/~dimitri/doxygen/index.html
-Prefix: %{_prefix}
-BuildPrereq: libstdc++-devel >= 2.96, /usr/bin/perl
-BuildRoot: %{_tmppath}/%{name}-%{version}-root
-
-%description
-Doxygen can generate an online class browser (in HTML) and/or a
-reference manual (in LaTeX) from a set of documented source files. The
-documentation is extracted directly from the sources. Doxygen can
-also be configured to extract the code structure from undocumented
-source files.
-
-%package doxywizard
-Summary: A GUI for creating and editing configuration files.
-Group: User Interface/X
-Requires: %{name} = %{version}
-BuildPrereq: qt-devel => 2.3.0
-Requires: qt >= 2.3.0
-
-%description doxywizard
-Doxywizard is a GUI for creating and editing configuration files that
-are used by doxygen.
-
-%prep
-%setup -q
-%patch -p1 -b .redhat
-%patch1 -p1 -b .qt2
-
-%build
-QTDIR="" && . /etc/profile.d/qt.sh
-export OLD_PO_FILE_INPUT=yes
-
-./configure --prefix %{_prefix} --shared --release --with-doxywizard
-make all docs
-
-%install
-rm -rf ${RPM_BUILD_ROOT}
-
-export OLD_PO_FILE_INPUT=yes
-make install INSTALL=$RPM_BUILD_ROOT%{_prefix}
-
-%clean
-rm -rf ${RPM_BUILD_ROOT}
-
-%files
-%defattr(-,root,root)
-%doc LANGUAGE.HOWTO README examples html
-%{_bindir}/doxygen
-%{_bindir}/doxytag
-
-%files doxywizard
-%defattr(-,root,root)
-%{_bindir}/doxywizard
-
-%changelog
-* Sun Jan 06 2002 Than Ngo <than@redhat.com> 1.2.13.1-1
-- update to 1.2.13.1
-
-* Sun Dec 30 2001 Jeff Johnson <jbj@redhat.com> 1.2.13-1
-- update to 1.2.13
-
-* Sun Nov 18 2001 Than Ngo <than@redhat.com> 1.2.12-1
-- update to 1.2.12
-- s/Copyright/License
-
-* Wed Sep 12 2001 Tim Powers <timp@redhat.com>
-- rebuild with new gcc and binutils
-
-* Wed Jun 13 2001 Than Ngo <than@redhat.com>
-- update tp 1.2.8.1
-- make doxywizard as separat package
-- fix to use install as default
-
-* Tue Jun 05 2001 Than Ngo <than@redhat.com>
-- update to 1.2.8
-
-* Tue May 01 2001 Than Ngo <than@redhat.com>
-- update to 1.2.7
-- clean up specfile
-- patch to use RPM_OPT_FLAG
-
-* Wed Mar 14 2001 Jeff Johnson <jbj@redhat.com>
-- update to 1.2.6
-
-* Wed Feb 28 2001 Trond Eivind Glomsr�d <teg@redhat.com>
-- rebuild
-
-* Tue Dec 26 2000 Than Ngo <than@redhat.com>
-- update to 1.2.4
-- remove excludearch ia64
-- bzip2 sources
-
-* Mon Dec 11 2000 Than Ngo <than@redhat.com>
-- rebuild with the fixed fileutils
-
-* Mon Oct 30 2000 Jeff Johnson <jbj@redhat.com>
-- update to 1.2.3.
-
-* Sun Oct  8 2000 Jeff Johnson <jbj@redhat.com>
-- update to 1.2.2.
-- enable doxywizard.
-
-* Sat Aug 19 2000 Preston Brown <pbrown@redhat.com>
-- 1.2.1 is latest stable, so we upgrade before Winston is released.
-
-* Wed Jul 12 2000 Prospector <bugzilla@redhat.com>
-- automatic rebuild
-
-* Tue Jul  4 2000 Jakub Jelinek <jakub@redhat.com>
-- Rebuild with new C++
-
-* Fri Jun 30 2000 Florian La Roche <laroche@redhat.de>
-- fix QTDIR detection
-
-* Fri Jun 09 2000 Preston Brown <pbrown@redhat.com>
-- compile on x86 w/o optimization, revert when compiler fixed!!
-
-* Wed Jun 07 2000 Preston Brown <pbrown@redhat.com>
-- use newer RPM macros
-
-* Tue Jun  6 2000 Jeff Johnson <jbj@redhat.com>
-- add to distro.
-
-* Tue May  9 2000 Tim Powers <timp@redhat.com>
-- rebuilt for 7.0
-
-* Wed Feb  2 2000 Bernhard Rosenkraenzer <bero@redhat.com>
-- recompile with current Qt (2.1.0/1.45)
-
-* Wed Jan  5 2000 Jeff Johnson <jbj@redhat.com>
-- update to 1.0.0.
-- recompile with qt-2.0.1 if available.
-- relocatable package.
-
-* Mon Nov  8 1999 Tim Powers <timp@redhat.com>
--updated to 0.49-991106
-
-* Tue Jul 13 1999 Tim Powers <timp@redhat.com>
-- updated source
-- cleaned up some stuff in the spec file
-
-* Thu Apr 22 1999 Jeff Johnson <jbj@redhat.com>
-- Create Power Tools 6.0 package.
diff --git a/qtools/qcache.h b/qtools/qcache.h
new file mode 100644
index 0000000..39b9139
--- /dev/null
+++ b/qtools/qcache.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+** 
+**
+** Definition of QCache template class
+**
+** Created : 950209
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QCACHE_H
+#define QCACHE_H
+
+#ifndef QT_H
+#include "qgcache.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QCache : public QGCache
+{
+public:
+    QCache( const QCache<type> &c ) : QGCache(c) {}
+    QCache( int maxCost=100, int size=17, bool caseSensitive=TRUE )
+	: QGCache( maxCost, size, StringKey, caseSensitive, FALSE ) {}
+   ~QCache()				{ clear(); }
+    QCache<type> &operator=( const QCache<type> &c )
+			{ return (QCache<type>&)QGCache::operator=(c); }
+    int	  maxCost()   const		{ return QGCache::maxCost(); }
+    int	  totalCost() const		{ return QGCache::totalCost(); }
+    void  setMaxCost( int m )		{ QGCache::setMaxCost(m); }
+    uint  count()     const		{ return QGCache::count(); }
+    uint  size()      const		{ return QGCache::size(); }
+    bool  isEmpty()   const		{ return QGCache::count() == 0; }
+    void  clear()			{ QGCache::clear(); }
+    bool  insert( const QString &k, const type *d, int c=1, int p=0 )
+			{ return QGCache::insert_string(k,(Item)d,c,p);}
+    bool  remove( const QString &k )
+			{ return QGCache::remove_string(k); }
+    type *take( const QString &k )
+			{ return (type *)QGCache::take_string(k); }
+    type *find( const QString &k, bool ref=TRUE ) const
+			{ return (type *)QGCache::find_string(k,ref);}
+    type *operator[]( const QString &k ) const
+			{ return (type *)QGCache::find_string(k);}
+    void  statistics() const	      { QGCache::statistics(); }
+private:
+    void  deleteItem( Item d )	      { if ( del_item ) delete (type *)d; }
+};
+
+
+
+template<class type> class Q_EXPORT QCacheIterator : public QGCacheIterator
+{
+public:
+    QCacheIterator( const QCache<type> &c ):QGCacheIterator((QGCache &)c) {}
+    QCacheIterator( const QCacheIterator<type> &ci)
+				: QGCacheIterator( (QGCacheIterator &)ci ) {}
+    QCacheIterator<type> &operator=(const QCacheIterator<type>&ci)
+	{ return ( QCacheIterator<type>&)QGCacheIterator::operator=( ci ); }
+    uint  count()   const     { return QGCacheIterator::count(); }
+    bool  isEmpty() const     { return QGCacheIterator::count() == 0; }
+    bool  atFirst() const     { return QGCacheIterator::atFirst(); }
+    bool  atLast()  const     { return QGCacheIterator::atLast(); }
+    type *toFirst()	      { return (type *)QGCacheIterator::toFirst(); }
+    type *toLast()	      { return (type *)QGCacheIterator::toLast(); }
+    operator type *() const   { return (type *)QGCacheIterator::get(); }
+    type *current()   const   { return (type *)QGCacheIterator::get(); }
+    QString currentKey() const{ return QGCacheIterator::getKeyString(); }
+    type *operator()()	      { return (type *)QGCacheIterator::operator()();}
+    type *operator++()	      { return (type *)QGCacheIterator::operator++(); }
+    type *operator+=(uint j)  { return (type *)QGCacheIterator::operator+=(j);}
+    type *operator--()	      { return (type *)QGCacheIterator::operator--(); }
+    type *operator-=(uint j)  { return (type *)QGCacheIterator::operator-=(j);}
+};
+
+
+#endif // QCACHE_H
diff --git a/qtools/qgcache.cpp b/qtools/qgcache.cpp
new file mode 100644
index 0000000..1fd876d
--- /dev/null
+++ b/qtools/qgcache.cpp
@@ -0,0 +1,868 @@
+/****************************************************************************
+** 
+**
+** Implementation of QGCache and QGCacheIterator classes
+**
+** Created : 950208
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qgcache.h"
+#include "qlist.h"
+#include "qdict.h"
+#include "qstring.h"
+
+
+// NOT REVISED
+/*!
+  \class QGCache qgcache.h
+
+  \brief The QGCache class is an internal class for implementing QCache template classes.
+
+  QGCache is a strictly internal class that acts as a base class for the
+  \link collection.html collection classes\endlink QCache and QIntCache.
+*/
+
+
+/*****************************************************************************
+  QGCacheItem class (internal cache item)
+ *****************************************************************************/
+
+struct QCacheItem
+{
+    QCacheItem( void *k, QCollection::Item d, int c, short p )
+	: priority(p), skipPriority(p), cost(c), key(k), data(d), node(0) {}
+    short	priority;
+    short	skipPriority;
+    int		cost;
+    void       *key;
+    QCollection::Item data;
+    QLNode     *node;
+};
+
+
+/*****************************************************************************
+  QCList class (internal list of cache items)
+ *****************************************************************************/
+
+class QCList : private QList<QCacheItem>
+{
+friend class QGCacheIterator;
+friend class QCListIt;
+public:
+    QCList()	{}
+   ~QCList();
+
+    void	insert( QCacheItem * );		// insert according to priority
+    void	insert( int, QCacheItem * );
+    void	take( QCacheItem * );
+    void	reference( QCacheItem * );
+
+    void	setAutoDelete( bool del ) { QCollection::setAutoDelete(del); }
+
+    bool	removeFirst()	{ return QList<QCacheItem>::removeFirst(); }
+    bool	removeLast()	{ return QList<QCacheItem>::removeLast(); }
+
+    QCacheItem *first()		{ return QList<QCacheItem>::first(); }
+    QCacheItem *last()		{ return QList<QCacheItem>::last(); }
+    QCacheItem *prev()		{ return QList<QCacheItem>::prev(); }
+    QCacheItem *next()		{ return QList<QCacheItem>::next(); }
+
+#if defined(DEBUG)
+    int		inserts;			// variables for statistics
+    int		insertCosts;
+    int		insertMisses;
+    int		finds;
+    int		hits;
+    int		hitCosts;
+    int		dumps;
+    int		dumpCosts;
+#endif
+};
+
+
+QCList::~QCList()
+{
+#if defined(DEBUG)
+    ASSERT( count() == 0 );
+#endif
+}
+
+
+void QCList::insert( QCacheItem *ci )
+{
+    QCacheItem *item = first();
+    while( item && item->skipPriority > ci->priority ) {
+	item->skipPriority--;
+	item = next();
+    }
+    if ( item )
+	QList<QCacheItem>::insert( at(), ci );
+    else
+	append( ci );
+#if defined(DEBUG)
+    ASSERT( ci->node == 0 );
+#endif
+    ci->node = currentNode();
+}
+
+inline void QCList::insert( int i, QCacheItem *ci )
+{
+    QList<QCacheItem>::insert( i, ci );
+#if defined(DEBUG)
+    ASSERT( ci->node == 0 );
+#endif
+    ci->node = currentNode();
+}
+
+
+void QCList::take( QCacheItem *ci )
+{
+    if ( ci ) {
+#if defined(DEBUG)
+	ASSERT( ci->node != 0 );
+#endif
+	takeNode( ci->node );
+	ci->node = 0;
+    }
+}
+
+
+inline void QCList::reference( QCacheItem *ci )
+{
+#if defined(DEBUG)
+    ASSERT( ci != 0 && ci->node != 0 );
+#endif
+    ci->skipPriority = ci->priority;
+    relinkNode( ci->node );			// relink as first item
+}
+
+
+class QCListIt: public QListIterator<QCacheItem>
+{
+public:
+    QCListIt( const QCList *p ): QListIterator<QCacheItem>( *p ) {}
+    QCListIt( const QCListIt *p ): QListIterator<QCacheItem>( *p ) {}
+};
+
+
+/*****************************************************************************
+  QCDict class (internal dictionary of cache items)
+ *****************************************************************************/
+
+//
+// Since we need to decide if the dictionary should use an int or const
+// char * key (the "bool trivial" argument in the constructor below)
+// we cannot use the macro/template dict, but inherit directly from QGDict.
+//
+
+class QCDict : public QGDict
+{
+public:
+    QCDict( uint size, uint kt, bool caseSensitive, bool copyKeys )
+	: QGDict( size, (KeyType)kt, caseSensitive, copyKeys ) {}
+
+    QCacheItem *find_string(const QString &key) const
+	{ return (QCacheItem*)((QCDict*)this)->look_string(key, 0, 0); }
+    QCacheItem *find_ascii(const char *key) const
+	{ return (QCacheItem*)((QCDict*)this)->look_ascii(key, 0, 0); }
+    QCacheItem *find_int(long key) const
+	{ return (QCacheItem*)((QCDict*)this)->look_int(key, 0, 0); }
+
+    QCacheItem *take_string(const QString &key)
+	{ return (QCacheItem*)QGDict::take_string(key); }
+    QCacheItem *take_ascii(const char *key)
+	{ return (QCacheItem*)QGDict::take_ascii(key); }
+    QCacheItem *take_int(long key)
+	{ return (QCacheItem*)QGDict::take_int(key); }
+
+    bool  insert_string( const QString &key, const QCacheItem *ci )
+	{ return QGDict::look_string(key,(Item)ci,1)!=0;}
+    bool  insert_ascii( const char *key, const QCacheItem *ci )
+	{ return QGDict::look_ascii(key,(Item)ci,1)!=0;}
+    bool  insert_int( long key, const QCacheItem *ci )
+	{ return QGDict::look_int(key,(Item)ci,1)!=0;}
+
+    bool  remove_string( QCacheItem *item )
+	{ return QGDict::remove_string(*((QString*)(item->key)),item); }
+    bool  remove_ascii( QCacheItem *item )
+	{ return QGDict::remove_ascii((const char *)item->key,item); }
+    bool  remove_int( QCacheItem *item )
+	{ return QGDict::remove_int((long)item->key,item);}
+
+    void  statistics()			{ QGDict::statistics(); }
+};
+
+
+/*****************************************************************************
+  QGDict member functions
+ *****************************************************************************/
+
+/*!
+  \internal
+  Constructs a cache.
+*/
+
+QGCache::QGCache( int maxCost, uint size, KeyType kt, bool caseSensitive,
+		  bool copyKeys )
+{
+    keytype = kt;
+    lruList = new QCList;
+    CHECK_PTR( lruList );
+    lruList->setAutoDelete( TRUE );
+    copyk   = ((keytype == AsciiKey) && copyKeys);
+    dict    = new QCDict( size, kt, caseSensitive, FALSE );
+    CHECK_PTR( dict );
+    mCost   = maxCost;
+    tCost   = 0;
+#if defined(DEBUG)
+    lruList->inserts	  = 0;
+    lruList->insertCosts  = 0;
+    lruList->insertMisses = 0;
+    lruList->finds	  = 0;
+    lruList->hits	  = 0;
+    lruList->hitCosts	  = 0;
+    lruList->dumps	  = 0;
+    lruList->dumpCosts	  = 0;
+#endif
+}
+
+/*!
+  \internal
+  Cannot copy a cache.
+*/
+
+QGCache::QGCache( const QGCache & )
+    : QCollection()
+{
+#if defined(CHECK_NULL)
+    qFatal( "QGCache::QGCache(QGCache &): Cannot copy a cache" );
+#endif
+}
+
+/*!
+  \internal
+  Removes all items from the cache and destroys it.
+*/
+
+QGCache::~QGCache()
+{
+    clear();					// delete everything first
+    delete dict;
+    delete lruList;
+}
+
+/*!
+  \internal
+  Cannot assign a cache.
+*/
+
+QGCache &QGCache::operator=( const QGCache & )
+{
+#if defined(CHECK_NULL)
+    qFatal( "QGCache::operator=: Cannot copy a cache" );
+#endif
+    return *this;				// satisfy the compiler
+}
+
+
+/*!
+  \fn uint QGCache::count() const
+  \internal
+  Returns the number of items in the cache.
+*/
+
+/*!
+  \fn uint QGCache::size() const
+  \internal
+  Returns the size of the hash array.
+*/
+
+/*!
+  \fn int QGCache::maxCost() const
+  \internal
+  Returns the maximum cache cost.
+*/
+
+/*!
+  \fn int QGCache::totalCost() const
+  \internal
+  Returns the total cache cost.
+*/
+
+/*!
+  \internal
+  Sets the maximum cache cost.
+*/
+
+void QGCache::setMaxCost( int maxCost )
+{
+    if ( maxCost < tCost ) {
+	if ( !makeRoomFor(tCost - maxCost) )	// remove excess cost
+	    return;
+    }
+    mCost = maxCost;
+}
+
+
+/*!
+  \internal
+  Inserts an item into the cache.
+
+  \warning If this function returns FALSE, you must delete \a data
+  yourself.  Additionally, be very careful about using \a data after
+  calling this function, as any other insertions into the cache, from
+  anywhere in the application, or within Qt itself, could cause the
+  data to be discarded from the cache, and the pointer to become
+  invalid.
+*/
+
+bool QGCache::insert_string( const QString &key, QCollection::Item data,
+			     int cost, int priority)
+{
+    if ( tCost + cost > mCost ) {
+	if ( !makeRoomFor(tCost + cost - mCost, priority) ) {
+#if defined(DEBUG)
+	    lruList->insertMisses++;
+#endif
+	    return FALSE;
+	}
+    }
+#if defined(DEBUG)
+    ASSERT( keytype == StringKey );
+    lruList->inserts++;
+    lruList->insertCosts += cost;
+#endif
+    if ( priority < -32768 )
+	priority = -32768;
+    else if ( priority > 32767 )
+	priority = 32677;
+    QCacheItem *ci = new QCacheItem( new QString(key), newItem(data),
+				     cost, (short)priority );
+    CHECK_PTR( ci );
+    lruList->insert( 0, ci );
+    dict->insert_string( key, ci );
+    tCost += cost;
+    return TRUE;
+}
+
+
+/*! \internal */
+
+bool QGCache::insert_other( const char *key, QCollection::Item data,
+			    int cost, int priority)
+{
+    if ( tCost + cost > mCost ) {
+	if ( !makeRoomFor(tCost + cost - mCost, priority) ) {
+#if defined(DEBUG)
+	    lruList->insertMisses++;
+#endif
+	    return FALSE;
+	}
+    }
+#if defined(DEBUG)
+    ASSERT( keytype != StringKey );
+    lruList->inserts++;
+    lruList->insertCosts += cost;
+#endif
+    if ( keytype == AsciiKey && copyk )
+	key = qstrdup( key );
+    if ( priority < -32768 )
+	priority = -32768;
+    else if ( priority > 32767 )
+	priority = 32677;
+    QCacheItem *ci = new QCacheItem( (void*)key, newItem(data), cost,
+				     (short)priority );
+    CHECK_PTR( ci );
+    lruList->insert( 0, ci );
+    if ( keytype == AsciiKey )
+	dict->insert_ascii( key, ci );
+    else
+	dict->insert_int( (long)key, ci );
+    tCost += cost;
+    return TRUE;
+}
+
+
+/*!
+  \internal
+  Removes an item from the cache.
+*/
+
+bool QGCache::remove_string( const QString &key )
+{
+    Item d = take_string( key );
+    if ( d )
+	deleteItem( d );
+    return d != 0;
+}
+
+
+/*! \internal */
+
+bool QGCache::remove_other( const char *key )
+{
+    Item d = take_other( key );
+    if ( d )
+	deleteItem( d );
+    return d != 0;
+}
+
+
+/*!
+  \internal
+  Takes an item out of the cache (no delete).
+*/
+
+QCollection::Item QGCache::take_string( const QString &key )
+{
+    QCacheItem *ci = dict->take_string( key );	// take from dict
+    Item d;
+    if ( ci ) {
+	d = ci->data;
+	tCost -= ci->cost;
+	lruList->take( ci );			// take from list
+	delete (QString*)ci->key;
+	delete ci;
+    } else {
+	d = 0;
+    }
+    return d;
+}
+
+/*!
+  \internal
+  Takes an item out of the cache (no delete).
+*/
+
+QCollection::Item QGCache::take_other( const char *key )
+{
+    QCacheItem *ci;
+    if ( keytype == AsciiKey )
+	ci = dict->take_ascii( key );
+    else
+	ci = dict->take_int( (long)key );
+    Item d;
+    if ( ci ) {
+	d = ci->data;
+	tCost -= ci->cost;
+	lruList->take( ci );			// take from list
+	if ( copyk )
+	    delete [] (char *)ci->key;
+	delete ci;
+    } else {
+	d = 0;
+    }
+    return d;
+}
+
+
+/*!
+  \internal
+  Clears the cache.
+*/
+
+void QGCache::clear()
+{
+    QCacheItem *ci;
+    while ( (ci = lruList->first()) ) {
+	switch ( keytype ) {
+	    case StringKey:
+		dict->remove_string( ci );
+		delete (QString*)ci->key;
+		break;
+	    case AsciiKey:
+		dict->remove_ascii( ci );
+		if ( copyk )
+		    delete [] (char*)ci->key;
+		break;
+	    case IntKey:
+		dict->remove_int( ci );
+		break;
+	    case PtrKey:			// unused
+		break;
+	}
+	deleteItem( ci->data );			// delete data
+	lruList->removeFirst();			// remove from list
+    }
+    tCost = 0;
+}
+
+
+/*!
+  \internal
+  Finds an item in the cache.
+*/
+
+QCollection::Item QGCache::find_string( const QString &key, bool ref ) const
+{
+    QCacheItem *ci = dict->find_string( key );
+#if defined(DEBUG)
+    lruList->finds++;
+#endif
+    if ( ci ) {
+#if defined(DEBUG)
+	lruList->hits++;
+	lruList->hitCosts += ci->cost;
+#endif
+	if ( ref )
+	    lruList->reference( ci );
+	return ci->data;
+    }
+    return 0;
+}
+
+
+/*!
+  \internal
+  Finds an item in the cache.
+*/
+
+QCollection::Item QGCache::find_other( const char *key, bool ref ) const
+{
+    QCacheItem *ci = keytype == AsciiKey ? dict->find_ascii(key)
+					 : dict->find_int((long)key);
+#if defined(DEBUG)
+    lruList->finds++;
+#endif
+    if ( ci ) {
+#if defined(DEBUG)
+	lruList->hits++;
+	lruList->hitCosts += ci->cost;
+#endif
+	if ( ref )
+	    lruList->reference( ci );
+	return ci->data;
+    }
+    return 0;
+}
+
+
+/*!
+  \internal
+  Allocates cache space for one or more items.
+*/
+
+bool QGCache::makeRoomFor( int cost, int priority )
+{
+    if ( cost > mCost )				// cannot make room for more
+	return FALSE;				//   than maximum cost
+    if ( priority == -1 )
+	priority = 32767;
+    register QCacheItem *ci = lruList->last();
+    int cntCost = 0;
+    int dumps	= 0;				// number of items to dump
+    while ( cntCost < cost && ci && ci->skipPriority <= priority ) {
+	cntCost += ci->cost;
+	ci	 = lruList->prev();
+	dumps++;
+    }
+    if ( cntCost < cost )			// can enough cost be dumped?
+	return FALSE;				// no
+#if defined(DEBUG)
+    ASSERT( dumps > 0 );
+#endif
+    while ( dumps-- ) {
+	ci = lruList->last();
+#if defined(DEBUG)
+	lruList->dumps++;
+	lruList->dumpCosts += ci->cost;
+#endif
+	switch ( keytype ) {
+	    case StringKey:
+		dict->remove_string( ci );
+		delete (QString*)ci->key;
+		break;
+	    case AsciiKey:
+		dict->remove_ascii( ci );
+		if ( copyk )
+		    delete [] (char *)ci->key;
+		break;
+	    case IntKey:
+		dict->remove_int( ci );
+		break;
+	    case PtrKey:			// unused
+		break;
+	}
+	deleteItem( ci->data );			// delete data
+	lruList->removeLast();			// remove from list
+    }
+    tCost -= cntCost;
+    return TRUE;
+}
+
+
+/*!
+  \internal
+  Outputs debug statistics.
+*/
+
+void QGCache::statistics() const
+{
+#if defined(DEBUG)
+    QString line;
+    line.fill( '*', 80 );
+    qDebug( line.ascii() );
+    qDebug( "CACHE STATISTICS:" );
+    qDebug( "cache contains %d item%s, with a total cost of %d",
+	   count(), count() != 1 ? "s" : "", tCost );
+    qDebug( "maximum cost is %d, cache is %d%% full.",
+	   mCost, (200*tCost + mCost) / (mCost*2) );
+    qDebug( "find() has been called %d time%s",
+	   lruList->finds, lruList->finds != 1 ? "s" : "" );
+    qDebug( "%d of these were hits, items found had a total cost of %d.",
+	   lruList->hits,lruList->hitCosts );
+    qDebug( "%d item%s %s been inserted with a total cost of %d.",
+	   lruList->inserts,lruList->inserts != 1 ? "s" : "",
+	   lruList->inserts != 1 ? "have" : "has", lruList->insertCosts );
+    qDebug( "%d item%s %s too large or had too low priority to be inserted.",
+	   lruList->insertMisses, lruList->insertMisses != 1 ? "s" : "",
+	   lruList->insertMisses != 1 ? "were" : "was" );
+    qDebug( "%d item%s %s been thrown away with a total cost of %d.",
+	   lruList->dumps, lruList->dumps != 1 ? "s" : "",
+	   lruList->dumps != 1 ? "have" : "has", lruList->dumpCosts );
+    qDebug( "Statistics from internal dictionary class:" );
+    dict->statistics();
+    qDebug( line.ascii() );
+#endif
+}
+
+
+/*****************************************************************************
+  QGCacheIterator member functions
+ *****************************************************************************/
+
+/*!
+  \class QGCacheIterator qgcache.h
+
+  \brief An internal class for implementing QCacheIterator and QIntCacheIterator.
+
+  QGCacheIterator is a strictly internal class that does the heavy work for
+  QCacheIterator and QIntCacheIterator.
+*/
+
+/*!
+  \internal
+  Constructs an iterator that operates on the cache \e c.
+*/
+
+QGCacheIterator::QGCacheIterator( const QGCache &c )
+{
+    it = new QCListIt( c.lruList );
+#if defined(DEBUG)
+    ASSERT( it != 0 );
+#endif
+}
+
+/*!
+  \internal
+  Constructs an iterator that operates on the same cache as \e ci.
+*/
+
+QGCacheIterator::QGCacheIterator( const QGCacheIterator &ci )
+{
+    it = new QCListIt( ci.it );
+#if defined(DEBUG)
+    ASSERT( it != 0 );
+#endif
+}
+
+/*!
+  \internal
+  Destroys the iterator.
+*/
+
+QGCacheIterator::~QGCacheIterator()
+{
+    delete it;
+}
+
+/*!
+  \internal
+  Assigns the iterator \e ci to this cache iterator.
+*/
+
+QGCacheIterator &QGCacheIterator::operator=( const QGCacheIterator &ci )
+{
+    *it = *ci.it;
+    return *this;
+}
+
+/*!
+  \internal
+  Returns the number of items in the cache.
+*/
+
+uint QGCacheIterator::count() const
+{
+    return it->count();
+}
+
+/*!
+  \internal
+  Returns TRUE if the iterator points to the first item.
+*/
+
+bool  QGCacheIterator::atFirst() const
+{
+    return it->atFirst();
+}
+
+/*!
+  \internal
+  Returns TRUE if the iterator points to the last item.
+*/
+
+bool QGCacheIterator::atLast() const
+{
+    return it->atLast();
+}
+
+/*!
+  \internal
+  Sets the list iterator to point to the first item in the cache.
+*/
+
+QCollection::Item QGCacheIterator::toFirst()
+{
+    QCacheItem *item = it->toFirst();
+    return item ? item->data : 0;
+}
+
+/*!
+  \internal
+  Sets the list iterator to point to the last item in the cache.
+*/
+
+QCollection::Item QGCacheIterator::toLast()
+{
+    QCacheItem *item = it->toLast();
+    return item ? item->data : 0;
+}
+
+/*!
+  \internal
+  Returns the current item.
+*/
+
+QCollection::Item QGCacheIterator::get() const
+{
+    QCacheItem *item = it->current();
+    return item ? item->data : 0;
+}
+
+/*!
+  \internal
+  Returns the key of the current item.
+*/
+
+QString QGCacheIterator::getKeyString() const
+{
+    QCacheItem *item = it->current();
+    return item ? *((QString*)item->key) : QString::null;
+}
+
+/*!
+  \internal
+  Returns the key of the current item, as a \0-terminated C string.
+*/
+
+const char *QGCacheIterator::getKeyAscii() const
+{
+    QCacheItem *item = it->current();
+    return item ? (const char *)item->key : 0;
+}
+
+/*!
+  \internal
+  Returns the key of the current item, as a long.
+*/
+
+long QGCacheIterator::getKeyInt() const
+{
+    QCacheItem *item = it->current();
+    return item ? (long)item->key : 0;
+}
+
+/*!
+  \internal
+  Moves to the next item (postfix).
+*/
+
+QCollection::Item QGCacheIterator::operator()()
+{
+    QCacheItem *item = it->operator()();
+    return item ? item->data : 0;
+}
+
+/*!
+  \internal
+  Moves to the next item (prefix).
+*/
+
+QCollection::Item QGCacheIterator::operator++()
+{
+    QCacheItem *item = it->operator++();
+    return item ? item->data : 0;
+}
+
+/*!
+  \internal
+  Moves \e jumps positions forward.
+*/
+
+QCollection::Item QGCacheIterator::operator+=( uint jump )
+{
+    QCacheItem *item = it->operator+=(jump);
+    return item ? item->data : 0;
+}
+
+/*!
+  \internal
+  Moves to the previous item (prefix).
+*/
+
+QCollection::Item QGCacheIterator::operator--()
+{
+    QCacheItem *item = it->operator--();
+    return item ? item->data : 0;
+}
+
+/*!
+  \internal
+  Moves \e jumps positions backward.
+*/
+
+QCollection::Item QGCacheIterator::operator-=( uint jump )
+{
+    QCacheItem *item = it->operator-=(jump);
+    return item ? item->data : 0;
+}
diff --git a/qtools/qgcache.h b/qtools/qgcache.h
new file mode 100644
index 0000000..5c3e126
--- /dev/null
+++ b/qtools/qgcache.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+** 
+**
+** Definition of QGCache and QGCacheIterator classes
+**
+** Created : 950208
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+**   information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QGCACHE_H
+#define QGCACHE_H
+
+#ifndef QT_H
+#include "qcollection.h"
+#include "qglist.h"
+#include "qgdict.h"
+#endif // QT_H
+
+
+class QCList;					// internal classes
+class QCListIt;
+class QCDict;
+
+
+class Q_EXPORT QGCache : public QCollection	// generic LRU cache
+{
+friend class QGCacheIterator;
+protected:
+    enum KeyType { StringKey, AsciiKey, IntKey, PtrKey };
+      // identical to QGDict's, but PtrKey is not used at the moment
+
+    QGCache( int maxCost, uint size, KeyType kt, bool caseSensitive,
+	     bool copyKeys );
+    QGCache( const QGCache & );			// not allowed, calls fatal()
+   ~QGCache();
+    QGCache &operator=( const QGCache & );	// not allowed, calls fatal()
+
+    uint    count()	const	{ return ((QGDict*)dict)->count(); }
+    uint    size()	const	{ return ((QGDict*)dict)->size(); }
+    int	    maxCost()	const	{ return mCost; }
+    int	    totalCost() const	{ return tCost; }
+    void    setMaxCost( int maxCost );
+    void    clear();
+
+    bool    insert_string( const QString &key, QCollection::Item,
+			   int cost, int priority );
+    bool    insert_other( const char *key, QCollection::Item,
+			  int cost, int priority );
+    bool    remove_string( const QString &key );
+    bool    remove_other( const char *key );
+    QCollection::Item take_string( const QString &key );
+    QCollection::Item take_other( const char *key );
+
+    QCollection::Item find_string( const QString &key, bool ref=TRUE ) const;
+    QCollection::Item find_other( const char *key, bool ref=TRUE ) const;
+
+    void    statistics() const;
+
+private:
+    bool    makeRoomFor( int cost, int priority = -1 );
+    KeyType keytype;
+    QCList *lruList;
+    QCDict *dict;
+    int	    mCost;
+    int	    tCost;
+    bool    copyk;
+};
+
+
+class Q_EXPORT QGCacheIterator			// generic cache iterator
+{
+protected:
+    QGCacheIterator( const QGCache & );
+    QGCacheIterator( const QGCacheIterator & );
+   ~QGCacheIterator();
+    QGCacheIterator &operator=( const QGCacheIterator & );
+
+    uint	      count()   const;
+    bool	      atFirst() const;
+    bool	      atLast()  const;
+    QCollection::Item toFirst();
+    QCollection::Item toLast();
+
+    QCollection::Item get() const;
+    QString	      getKeyString() const;
+    const char       *getKeyAscii()  const;
+    long	      getKeyInt()    const;
+
+    QCollection::Item operator()();
+    QCollection::Item operator++();
+    QCollection::Item operator+=( uint );
+    QCollection::Item operator--();
+    QCollection::Item operator-=( uint );
+
+protected:
+    QCListIt *it;				// iterator on cache list
+};
+
+
+#endif // QGCACHE_H
diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in
index 1a02797..37fc143 100644
--- a/qtools/qtools.pro.in
+++ b/qtools/qtools.pro.in
@@ -2,6 +2,8 @@ TEMPLATE	= lib
 CONFIG		= warn_on staticlib $extraopts
 HEADERS		= qarray.h \
 		  qbuffer.h \
+                  qcache.h \
+                  qgcache.h \
 		  qcollection.h \
 		  qconfig.h \
 		  qcstring.h \
@@ -50,6 +52,7 @@ SOURCES		= qbuffer.cpp \
 		  qfile.cpp \
 		  qfileinfo.cpp \
 		  qgarray.cpp \
+		  qgcache.cpp \
 		  qgdict.cpp \
 		  qglist.cpp \
 		  qglobal.cpp \
diff --git a/src/config.l b/src/config.l
index cd88d3e..b2f7848 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1316,7 +1316,7 @@ void Config::create()
                     "The default language is English, other supported languages are: \n"
 		    "Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, \n"
 		    "Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en \n"
-		    "(Japanese with English messages), Korean, Norwegian, Polish, Portuguese, \n"
+		    "(Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, \n"
 		    "Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.\n",
 		    "English"
                    );
@@ -1369,6 +1369,7 @@ void Config::create()
 #endif
 #ifdef LANG_KR
   ce->addValue("Korean");
+  ce->addValue("Korean-en");
 #endif
 #ifdef LANG_NO
   ce->addValue("Norwegian");
@@ -2441,7 +2442,7 @@ void Config::create()
                  );
   cb->addDependency("ENABLE_PREPROCESSING");
   //-----------------------------------------------------------------------------------------------
-  addInfo(  "External","Configuration::addtions related to external references   ");
+  addInfo(  "External","Configuration::additions related to external references   ");
   //-----------------------------------------------------------------------------------------------
   cl = addList(
                     "TAGFILES",
@@ -2660,7 +2661,7 @@ void Config::create()
   cb->addDependency("HAVE_DOT");
 
   //-----------------------------------------------------------------------------------------------
-  addInfo(  "Search","Configuration::addtions related to the search engine   ");
+  addInfo(  "Search","Configuration::additions related to the search engine   ");
   //-----------------------------------------------------------------------------------------------
   cb = addBool(
                     "SEARCHENGINE",
diff --git a/src/dot.cpp b/src/dot.cpp
index 06fa924..694b9ef 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -99,10 +99,10 @@ static bool convertMapFile(QTextStream &t,const char *mapName,
   char buf[maxLineLen];
   char url[maxLineLen];
   char ref[maxLineLen];
-  bool isRef = FALSE;
   int x1,y1,x2,y2;
   while (!f.atEnd())
   {
+    bool isRef = FALSE;
     int numBytes = f.readLine(buf,maxLineLen);
     buf[numBytes-1]='\0';
     //printf("ReadLine `%s'\n",buf);
diff --git a/src/entry.cpp b/src/entry.cpp
index 3cb431a..2a729d3 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -87,6 +87,7 @@ Entry::Entry(const Entry &e)
   initializer = e.initializer;
   initLines   = e.initLines;
   callGraph   = e.callGraph;
+  objc        = e.objc;
   //todoId      = e.todoId;
   //testId      = e.testId;
   //bugId       = e.bugId;
@@ -260,6 +261,7 @@ void Entry::reset()
   proto   = FALSE;
   explicitExternal = FALSE;
   memSpec  = 0;
+  objc = FALSE;
   subGrouping = TRUE;
   protection = Public;
   groupDocType = GROUPDOC_NORMAL;
diff --git a/src/entry.h b/src/entry.h
index b796b4e..a15c980 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -293,6 +293,7 @@ class Entry
     QList<ListItemInfo> *sli; //!< special lists (test/todo/bug/deprecated/..) this entry is in
     TagInfo    *tagInfo;      //!< tag file info
     static int  num;          //!< counts the total number of entries
+    bool        objc;         //!< Objective-C construct
     enum 
     {
       GROUPDOC_NORMAL,        //<! defgroup
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 9db76aa..a78c2ba 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -188,14 +188,14 @@ void HtmlDocVisitor::visit(DocVerbatim *s)
   switch(s->type())
   {
     case DocVerbatim::Code: // fall though
-      m_t << "<div class=\"fragment\"><pre>"; 
+      m_t << "<pre class=\"fragment\"><div>"; 
       parseCode(m_ci,s->context(),s->text().latin1(),s->isExample(),s->exampleFile());
-      m_t << "</pre></div>"; 
+      m_t << "</div></pre>"; 
       break;
     case DocVerbatim::Verbatim: 
-      m_t << "<div class=\"fragment\"><pre>";
+      m_t << "<pre class=\"fragment\"><div>";
       filter(s->text());
-      m_t << "</pre></div>"; 
+      m_t << "</div></pre>"; 
       break;
     case DocVerbatim::HtmlOnly: 
       m_t << s->text(); 
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index d247102..fa8af17 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -49,38 +49,66 @@ static const char *defaultStyleSheet =
 "	font-family: Geneva, Arial, Helvetica, sans-serif;\n"
 "}\n"
 "CAPTION { font-weight: bold }\n"
-"DIV.qindex { width: 100%;\n"
-"             background-color: #eeeeff;\n"
-"             border: 4px solid #eeeeff;\n"
-"             text-align: center;\n"
-"             margin-bottom: 2px\n" 
+"DIV.qindex {\n"
+"	width: 100%;\n"
+"	background-color: #eeeeff;\n"
+"	border: 1px solid #B0B0B0;\n"
+"	text-align: center;\n"
+"	margin: 2px;\n"
+"	padding: 2px;\n"
+"}\n"
+"A.qindex { text-decoration: none; font-weight: bold; color: #1A419D}\n"
+"A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D}\n"
+"A.qindex:hover {\n"
+"	text-decoration: none;\n"
+"	background-color: #ddddff;\n"
+"	padding-top: 2px;\n"
+"	padding-right: 2px;\n"
+"	padding-bottom: 2px;\n"
+"	padding-left: 2px;\n"
 "}\n"
-"A.qindex { text-decoration: none; font-weight: bold; color: #0000ee }\n"
-"A.qindex:visited { text-decoration: none; font-weight: bold; color: #0000ee }\n"
-"A.qindex:hover { text-decoration: none; background-color: #ddddff }\n"
-"A.qindexHL { text-decoration: none; font-weight: bold;\n"
-"             background-color: #6666cc;\n"
-"             color: #ffffff\n"
+"A.qindexHL {\n"
+"	text-decoration: none;\n"
+"	font-weight: bold;\n"
+"	background-color: #6666cc;\n"
+"	color: #ffffff;\n"
+"	padding: 2 6px;\n"
+"	border: 1px double #9295C2;\n"
 "           }\n"
-"A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff }\n"
+"A.qindexHL:hover {\n"
+"	text-decoration: none;\n"
+"	background-color: #6666cc;\n"
+"	color: #ffffff;\n"
+"	padding: 2px 6px;\n"
+"}\n"
 "A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }\n"
 "A.el { text-decoration: none; font-weight: bold }\n"
 "A.elRef { font-weight: bold }\n"
-"A.code { text-decoration: none; font-weight: normal; color: #4444ee }\n"
-"A.codeRef { font-weight: normal; color: #4444ee }\n"
+"A.code { text-decoration: none; font-weight: normal; color: #1A419D}\n"
+"A.codeRef { font-weight: normal; color: #1A419D}\n"
 "A:hover { text-decoration: none; background-color: #f2f2ff }\n"
 "DL.el { margin-left: -1cm }\n"
+"PRE.fragment {\n"
+"	border: 1px solid #CCCCCC;\n"
+"	background-color: #f5f5f5;\n"
+"	margin-top: 4px;\n"
+"	margin-bottom: 4px;\n"
+"	margin-left: 2px;\n"
+"	margin-right: 8px;\n"
+"	padding-left: 6px;\n"
+"	padding-right: 6px;\n"
+"	padding-top: 4px;\n"
+"	padding-bottom: 4px;\n"
+"}\n"
 "DIV.fragment {\n"
-"	width: 98%;\n"
 "	border: 1px solid #CCCCCC;\n"
 "	background-color: #f5f5f5;\n"
-"	padding-left: 4px;\n"
-"	margin: 4px;\n"
+"	padding: 6px;\n"
 "}\n"
 "DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }\n"
-"TD.md { background-color: #f2f2ff; font-weight: bold; }\n"
-"TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; }\n"
-"TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; }\n"
+"TD.md { background-color: #F4F4FB; font-weight: bold; }\n"
+"TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }\n"
+"TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }\n"
 "DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }\n"
 "DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }\n"
 "BODY {\n"
@@ -89,29 +117,31 @@ static const char *defaultStyleSheet =
 "	margin-right: 20px;\n"
 "	margin-left: 20px;\n"
 "}\n"
-"TD.indexkey { \n"
-"   background-color: #eeeeff; \n"
-"   font-weight: bold; \n"
-"   padding-right  : 10px; \n"
-"   padding-top    : 2px; \n"
-"   padding-left   : 10px; \n"
-"   padding-bottom : 2px; \n"
-"   margin-left    : 0px; \n"
-"   margin-right   : 0px; \n"
-"   margin-top     : 2px; \n"
-"   margin-bottom  : 2px  \n"
+"TD.indexkey {\n"
+"	background-color: #eeeeff;\n"
+"	font-weight: bold;\n"
+"	padding-right  : 10px;\n"
+"	padding-top    : 2px;\n"
+"	padding-left   : 10px;\n"
+"	padding-bottom : 2px;\n"
+"	margin-left    : 0px;\n"
+"	margin-right   : 0px;\n"
+"	margin-top     : 2px;\n"
+"	margin-bottom  : 2px;\n"
+"	border: 1px solid #CCCCCC;\n"
 "}\n"
-"TD.indexvalue { \n"
-"   background-color: #eeeeff; \n"
-"   font-style: italic; \n"
-"   padding-right  : 10px; \n"
-"   padding-top    : 2px; \n"
-"   padding-left   : 10px; \n"
-"   padding-bottom : 2px; \n"
-"   margin-left    : 0px; \n"
-"   margin-right   : 0px; \n"
-"   margin-top     : 2px; \n"
-"   margin-bottom  : 2px  \n"
+"TD.indexvalue {\n"
+"	background-color: #eeeeff;\n"
+"	font-style: italic;\n"
+"	padding-right  : 10px;\n"
+"	padding-top    : 2px;\n"
+"	padding-left   : 10px;\n"
+"	padding-bottom : 2px;\n"
+"	margin-left    : 0px;\n"
+"	margin-right   : 0px;\n"
+"	margin-top     : 2px;\n"
+"	margin-bottom  : 2px;\n"
+"	border: 1px solid #CCCCCC;\n"
 "}\n"
 "TR.memlist {\n"
 "   background-color: #f0f0f0; \n"
@@ -128,10 +158,10 @@ static const char *defaultStyleSheet =
 "SPAN.charliteral   { color: #008080 }\n"
 ".mdTable {\n"
 "	border: 1px solid #868686;\n"
-"	background-color: #f2f2ff;\n"
+"	background-color: #F4F4FB;\n"
 "}\n"
 ".mdRow {\n"
-"	padding: 8px 20px;\n"
+"	padding: 8px 10px;\n"
 "}\n"
 ".mdescLeft {\n"
 "	font-size: smaller;\n"
@@ -196,7 +226,7 @@ static const char *defaultStyleSheet =
 "	font-family: Geneva, Arial, Helvetica, sans-serif;\n"
 "	font-size: 13px;\n"
 "}\n"
-".search     { color: #0000ee;\n"
+".search     { color: #003399;\n"
 "              font-weight: bold;\n"
 "}\n"
 "FORM.search {\n"
@@ -209,6 +239,12 @@ static const char *defaultStyleSheet =
 "               background-color: #eeeeff;\n"
 "}\n"
 "TD.tiny      { font-size: 75%;\n"
+"}\n"
+"a {\n"
+"	color: #252E78;\n"
+"}\n"
+"a:visited {\n"
+"	color: #3D2185;\n"
 "}\n";
 
 static QCString g_header;
diff --git a/src/lang_cfg.h b/src/lang_cfg.h
index bfd0556..01180c6 100644
--- a/src/lang_cfg.h
+++ b/src/lang_cfg.h
@@ -14,6 +14,7 @@
 #define LANG_PT
 #define LANG_HU
 #define LANG_KR
+#define LANG_KE
 #define LANG_RO
 #define LANG_SI
 #define LANG_CN
diff --git a/src/language.cpp b/src/language.cpp
index 858d307..23034f3 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -67,6 +67,9 @@
 #ifdef LANG_HU
 #include "translator_hu.h"
 #endif
+#ifdef LANG_KE
+#include "translator_ke.h"
+#endif
 #ifdef LANG_KR
 #include "translator_kr.h"
 #endif
@@ -227,6 +230,10 @@ bool setTranslator(const char *langName)
   {
     theTranslator=new TranslatorKorean;
   }
+  else if (L_EQUAL("korean-en"))
+  {
+    theTranslator=new TranslatorKoreanEn;
+  }
 #endif
 #ifdef LANG_RO
   else if (L_EQUAL("romanian"))
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index b80fea0..7b68e71 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -221,7 +221,7 @@ void LatexGenerator::init()
 
   t << endl
     << "clean:" << endl
-    << "\trm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.pdf" << endl;
+    << "\trm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out refman.pdf" << endl;
 }
 
 static void writeDefaultHeaderPart1(QTextStream &t)
@@ -1235,7 +1235,7 @@ void LatexGenerator::codify(const char *str)
           MultiByte = FALSE;
           continue;
         }
-        if ( (uchar)c>=0x80 || (uchar)c<=0xff) // char in range [0x80..0xff]
+        if ((uchar)c>=0x80) // char in range [0x80..0xff]
         {
           t << (char)c;
           MultiByte = TRUE;
diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in
index 53b3341..c9ddb3d 100644
--- a/src/libdoxygen.pro.in
+++ b/src/libdoxygen.pro.in
@@ -101,6 +101,7 @@ HEADERS      =	bufstr.h \
 		translator_it.h \
 		translator_je.h \
 		translator_jp.h \
+		translator_ke.h \
 		translator_kr.h \
 		translator_nl.h \
 		translator_no.h \
@@ -188,7 +189,7 @@ INCLUDEPATH                += ../qtools
 INCLUDEPATH                += ../libpng
 INCLUDEPATH                += ../libmd5
 win32:INCLUDEPATH          += .
-win32-g++:INCLUDEPATH      = ../qtools /usr/include/libpng12
+win32-g++:INCLUDEPATH      = ../qtools /usr/include/libpng12 ../libmd5
 DESTDIR                    =  ../lib
 TARGET                     =  doxygen
 OBJECTS_DIR                =  ../objects
diff --git a/src/pre.l b/src/pre.l
index 2855190..4704a93 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -636,6 +636,23 @@ static int getNextId(const QCString &expr,int p,int *l)
 	p++;
       }
     }
+    else if (c=='/') // skip C Comment
+    {
+      char pc=c;
+      if (p<(int)expr.length()) 
+      {
+	c=expr.at(++p);
+        if (c=='*')  // Start of C comment
+        { 
+  	  while (p<(int)expr.length() && !(pc=='*' && c=='/'))
+	  {
+	    pc=c;
+	    c=expr.at(++p);
+	  }
+	  p++;
+        }
+      }
+    }
   }
   return -1;
 }
@@ -777,6 +794,20 @@ QCString removeIdsAndMarkers(const char *s)
 	p++;
 	while ((c=*p) && isId(c)) p++;
       }
+      else if (c=='/') // skip C comments
+      {
+	char pc=c;
+	c=*++p;
+	if (c=='*') // start of C comment
+	{ 
+	  while (*p && !(pc=='*' && c=='/')) // search end of comment
+	  {
+	    pc=c;
+	    c=*++p;
+	  }
+	  p++;
+	}
+      }
       else 
       {
 	result+=c;
@@ -786,6 +817,7 @@ QCString removeIdsAndMarkers(const char *s)
       }
     }
   }
+  //printf("removeIdsAndMarkers(%s)=%s\n",s,result.data());
   return result;
 }
 
@@ -810,6 +842,23 @@ QCString removeMarkers(const char *s)
 	}
 	p+=2;
       }
+      else if (c=='/') // skip C comments
+      {
+	result+=c;
+	char pc=c;
+	c=*++p;
+	if (c=='*') // start of C comment
+	{ 
+	  while (*p && !(pc=='*' && c=='/')) // search end of comment
+	  {
+	    result+=c;
+	    pc=c;
+	    c=*++p;
+	  }
+	  result+=c;
+	  p++;
+	}
+      }
       else
       {
 	result+=c;
@@ -817,6 +866,7 @@ QCString removeMarkers(const char *s)
       }
     }
   }
+  //printf("RemoveMarkers(%s)=%s\n",s,result.data());
   return result;
 }
 
@@ -1061,6 +1111,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 %x      Ifdef
 %x      Ifndef
 %x	SkipCComment
+%x	CopyCComment
 %x	SkipVerbatim
 %x	SkipCPPComment
 %x	RemoveCComment
@@ -1622,23 +1673,24 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 					  g_argDict->insert(argName,new int(g_defArgs)); 
 					  g_defArgs++;
   					}
-<DefineText>"/**"|"/*!"			{
+  /*
+<DefineText>"/ **"|"/ *!"			{
   					  g_defText+=yytext;
 					  g_defLitText+=yytext;
 					  g_insideComment=TRUE;
   					}
-<DefineText>"*/"			{
+<DefineText>"* /"			{
   					  g_defText+=yytext;
 					  g_defLitText+=yytext;
 					  g_insideComment=FALSE;
   					}
-<DefineText>"/*"|"/**<"|"/*!<"		{
-  					  outputArray(yytext,yyleng);
-					  g_defText+=' ';
-					  g_defLitText+=' ';
+  */
+<DefineText>"/*"			{
+					  g_defText+=yytext;
+					  g_defLitText+=yytext;
 					  g_lastCContext=YY_START;
 					  g_commentCount=1;
-  					  BEGIN(SkipCComment);
+  					  BEGIN(CopyCComment);
   					}
 <DefineText>"//"			{
   				          outputChar('/');outputChar('/');
@@ -1679,6 +1731,24 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 <SkipCComment,SkipVerbatim>.		{
   					  outputChar(*yytext);
   					}
+<CopyCComment>[^*]+			{
+					  g_defLitText+=yytext;
+					  g_defText+=yytext;
+  					}
+<CopyCComment>"*/"			{
+					  g_defLitText+=yytext;
+					  g_defText+=yytext;
+  					  BEGIN(g_lastCContext);
+  					}
+<CopyCComment>\n			{ 
+  					  g_yyLineNr++;
+					  g_defLitText+=yytext;
+					  g_defText+=yytext;
+  					}
+<CopyCComment>.				{
+					  g_defLitText+=yytext;
+					  g_defText+=yytext;
+  					}
 <RemoveCComment>"*/"		        { BEGIN(g_lastCContext); }
 <RemoveCComment>"//"			
 <RemoveCComment>"/*"
diff --git a/src/scanner.l b/src/scanner.l
index e4f12a4..a041063 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -128,6 +128,7 @@ static bool             insideJava = FALSE;		//!< processing Java code?
 static bool             insideCS = FALSE;		//!< processing C# code?
 static bool             insidePHP = FALSE;		//!< processing PHP code?
 static bool             insideCppQuote = FALSE;
+static bool             insideObjC = FALSE;             //!< processing Objective C code?
 
 static int              argRoundCount;
 static int              argSharpCount;
@@ -440,6 +441,7 @@ static void setContext()
   insideCS   = fileName.right(3)==".cs";
   insidePHP  = fileName.right(4)==".php" || fileName.right(5)==".php4" || 
                fileName.right(4)==".inc" || fileName.right(6)==".phtml";
+  insideObjC = fileName.right(2)==".m";
   if ( insidePHP )
   {
     useOverrideCommands = TRUE;
@@ -604,6 +606,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 %x	Array
 %x	ReadBody
 %x	ReadNSBody
+%x	ReadBodyIntf
 %x	Using
 %x	UsingDirective
 %x	NameSpaceDocArg1
@@ -722,6 +725,10 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 %x	DefinePHPEnd
 %x	OldStyleArgs
 %x	SkipVerbString
+%x      ObjCMethod
+%x      ObjCReturnType
+%x      ObjCParams
+%x      ObjCParamType
 
 %%
 
@@ -907,6 +914,102 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					  current->argList->clear();
 					  lineCount() ;
 					}
+<FindMembers>{B}*"@private"{BN}+	{
+  					  current->protection = protection = Private ;
+					  current->mtype = mtype = Method;
+					  current->type.resize(0); 
+					  current->name.resize(0); 
+					  current->args.resize(0);
+					  current->argList->clear();
+					  lineCount() ;
+  					}
+<FindMembers>{B}*"@protected"{BN}+	{
+  					  current->protection = protection = Protected ;
+					  current->mtype = mtype = Method;
+					  current->type.resize(0); 
+					  current->name.resize(0); 
+					  current->args.resize(0);
+					  current->argList->clear();
+					  lineCount() ;
+  					}
+<FindMembers>{B}*"@public"{BN}+	{
+  					  current->protection = protection = Public ;
+					  current->mtype = mtype = Method;
+					  current->type.resize(0); 
+					  current->name.resize(0); 
+					  current->args.resize(0);
+					  current->argList->clear();
+					  lineCount() ;
+  					}
+<FindMembers>[\-+]{BN}*			{
+  					  if (!insideObjC) 
+					  {
+					    REJECT;
+					  }
+					  else
+					  {
+					    current->protection = protection = Public ;
+					    current->stat=yytext[0]=='+';
+					    current->mtype = mtype = Method;
+					    current->type.resize(0); 
+					    current->name.resize(0); 
+					    current->args.resize(0);
+					    current->argList->clear();
+					    BEGIN( ObjCMethod );
+					  }
+  					}
+<ObjCMethod>"("				{ // start of method's return type
+  					  BEGIN( ObjCReturnType );
+  					}
+<ObjCMethod>{ID}			{ // found method name
+  					  if (current->type.isEmpty())
+					  {
+					    current->type = "id";
+					  }
+					  current->name = yytext;
+  					}
+<ObjCMethod>":"				{ // start of parameter list
+  					  Argument *a = new Argument;
+					  current->argList->append(a);
+  					  BEGIN( ObjCParams );
+  					}
+<ObjCReturnType>[^)]*			{ // TODO: check if nested braches are possible.
+  					  current->type = yytext;
+  					}
+<ObjCReturnType>")"			{
+  					  BEGIN( ObjCMethod );
+  					}
+<ObjCParams>{ID}/":"			{ // Keyword of parameter
+  					  current->argList->getLast()->attrib=(QCString)"["+yytext+"]";
+  					}
+<ObjCParams>{ID}			{ // name of parameter
+  					  current->argList->getLast()->name=yytext;
+  					}
+<ObjCParams>":"				{ }
+<ObjCParams>"("				{
+  					  BEGIN( ObjCParamType );
+  					}
+<ObjCParams>{BN}*			{
+  					  lineCount();
+					  if (current->argList->getLast()->type.isEmpty())
+					  {
+					    current->argList->getLast()->type="id";
+					  }
+  					  Argument *a = new Argument;
+					  current->argList->append(a);
+  					}
+<ObjCParamType>[^)]*			{
+  					  current->argList->last()->type=yytext;
+  					}
+<ObjCParamType>")"			{
+  					  BEGIN( ObjCParams );
+  					}
+<ObjCMethod,ObjCParams>";"		{ // end of method declaration
+  					  current->args = argListToString(current->argList);
+					  printf("argList=%s\n",current->args.data());
+  					  unput(';');
+  					  BEGIN( Function );
+  					}
 <FindMembers>{BN}{1,80}			{
   					  lineCount();
   					}
@@ -1035,6 +1138,19 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
 					    current->name = QCString(yytext).stripWhiteSpace();
 					  }
   					}
+<FindMembers>{B}*"@interface"{BN}+	{ // Objective-C interface
+					  lineCount();
+  					  isTypedef=FALSE;
+					  current->section = Entry::INTERFACE_SEC;
+					  current->objc = insideObjC = TRUE;
+					  current->protection = protection = Public ;
+					  addType( current ) ;
+					  current->type += " interface" ;
+					  current->fileName  = yyFileName;
+					  current->startLine = yyLineNr;
+					  current->bodyLine  = yyLineNr;
+					  BEGIN( CompoundName );
+  					}
 <FindMembers>{B}*"exception"{BN}+ 	{ // Corba IDL exception
   					  isTypedef=FALSE;
 					  current->section = Entry::EXCEPTION_SEC;
@@ -1466,7 +1582,7 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					  current->bodyLine = yyLineNr;
   					  BEGIN( Define );
   					}
-<FindMembers,ReadBody,ReadNSBody,SkipCurly,SkipCurlyCpp>{B}*"#"{B}+[0-9]+{B}+/"\""	{ /* line control directive */
+<FindMembers,ReadBody,ReadNSBody,ReadBodyIntf,SkipCurly,SkipCurlyCpp>{B}*"#"{B}+[0-9]+{B}+/"\""	{ /* line control directive */
                                           yyLineNr = atoi(&yytext[1]);
 					  //printf("setting line number to %d\n",yyLineNr);
 					  lastPreLineCtrlContext = YY_START;
@@ -2019,33 +2135,33 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   /*
 <FindFieldArg>","			{ unput(*yytext); BEGIN(FindFields); }
   */
-<ReadBody,ReadNSBody>[^\r\n\#{}"@'/]*	{ current->program += yytext ; }
-<ReadBody,ReadNSBody>"//".*		{ current->program += yytext ; }
-<ReadBody,ReadNSBody>"#".*		{ if (! insidePHP)
+<ReadBody,ReadNSBody,ReadBodyIntf>[^\r\n\#{}"@'/]*	{ current->program += yytext ; }
+<ReadBody,ReadNSBody,ReadBodyIntf>"//".*		{ current->program += yytext ; }
+<ReadBody,ReadNSBody,ReadBodyIntf>"#".*		{ if (! insidePHP)
 					    REJECT;
 					  current->program += yytext ;
 					}
-<ReadBody,ReadNSBody>@\"		{ current->program += yytext ; 
+<ReadBody,ReadNSBody,ReadBodyIntf>@\"	{ current->program += yytext ; 
                                           pSkipVerbString = &current->program;
                                           lastSkipVerbStringContext=YY_START;
                                           BEGIN( SkipVerbString );
 					}
-<ReadBody,ReadNSBody>\"			{ current->program += yytext ; 
+<ReadBody,ReadNSBody,ReadBodyIntf>\"	{ current->program += yytext ; 
                                           pCopyQuotedString = &current->program;
                                           lastStringContext=YY_START;
                                           BEGIN( CopyString );
 					}
-<ReadBody,ReadNSBody>"/*"{B}*		{ current->program += yytext ;
-					  lastContext = ReadBody ;
+<ReadBody,ReadNSBody,ReadBodyIntf>"/*"{B}*		{ current->program += yytext ;
+					  lastContext = YY_START ;
 					  BEGIN( Comment ) ;
 					}
-<ReadBody,ReadNSBody>"/*"{BL}		{ current->program += yytext ;
+<ReadBody,ReadNSBody,ReadBodyIntf>"/*"{BL}		{ current->program += yytext ;
 					  ++yyLineNr ;
-					  lastContext = ReadBody ;
+					  lastContext = YY_START ;
 					  BEGIN( Comment ) ;
 					}
-<ReadBody,ReadNSBody>{CHARLIT}          { current->program += yytext; }
-<ReadBody,ReadNSBody>"{"                { current->program += yytext ;
+<ReadBody,ReadNSBody,ReadBodyIntf>{CHARLIT}          { current->program += yytext; }
+<ReadBody,ReadNSBody,ReadBodyIntf>"{"                { current->program += yytext ;
 					  ++curlyCount ;
 					}
 <ReadBody,ReadNSBody>"}"		{ //err("ReadBody count=%d\n",curlyCount);
@@ -2081,20 +2197,27 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   					      current->type = current->type.simplifyWhiteSpace();
   					      current->name = current->name.stripWhiteSpace();
 					      //printf("adding `%s' `%s' `%s' brief=%s\n",current->type.data(),current->name.data(),current->args.data(),current->brief.data());
-					      current_root->addSubEntry( current ) ;
-					      current = new Entry(*current);
-					      if (current->section==Entry::NAMESPACE_SEC || 
-						  current->section==Entry::INTERFACE_SEC ||
-						  insideJava || insidePHP || insideCS
-						 )
-					      { // namespaces and interfaces and java classes ends with a closing bracket without semicolon
-						current->reset();
-						initEntry();
-						BEGIN( FindMembers ) ;
+					      if (insideObjC) // method definition follows
+					      {
+				                BEGIN( ReadBodyIntf ) ;
 					      }
 					      else
 					      {
-						BEGIN( MemberSpec ) ;
+					        current_root->addSubEntry( current ) ;
+						current = new Entry(*current);
+						if (current->section==Entry::NAMESPACE_SEC || 
+						    current->section==Entry::INTERFACE_SEC ||
+						    insideJava || insidePHP || insideCS
+						   )
+						{ // namespaces and interfaces and java classes ends with a closing bracket without semicolon
+						  current->reset();
+						  initEntry();
+						  BEGIN( FindMembers ) ;
+						}
+						else
+						{
+						  BEGIN( MemberSpec ) ;
+						}
 					      }
 					    }
 					  }
@@ -2262,11 +2385,18 @@ PHPKW	  ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;]
   */
 <MemberSpecSkip>","			{ BEGIN(MemberSpec); }
 <MemberSpecSkip>";"		        { unput(';'); BEGIN(MemberSpec); }
-<ReadBody,ReadNSBody>{BN}+				{ current->program += yytext ;
+<ReadBody,ReadNSBody,ReadBodyIntf>{BN}+	{ current->program += yytext ;
 					  lineCount() ;
 					}
-<ReadBody,ReadNSBody>.			{ current->program += yytext ; }
-<ReadBody,ReadNSBody>"'#"		{ current->program += yytext ; }
+<ReadBodyIntf>"@end"			{ // end of Objective C block
+					  current_root->addSubEntry( current ) ;
+  					  current=new Entry;
+					  initEntry();
+					  insideObjC=FALSE;
+					  BEGIN( FindMembers ); 
+  					}
+<ReadBody,ReadNSBody,ReadBodyIntf>.	{ current->program += yytext ; }
+<ReadBody,ReadNSBody,ReadBodyIntf>"'#"	{ current->program += yytext ; }
 
 <FindMembers>"("/({BN}*{ID}{BN}*"::")*{ID}{BN}*")"{BN}*"(" | /* typedef void (A::func_t)(args...) */
 <FindMembers>("("({BN}*{ID}{BN}*"::")*({BN}*"*"{BN}*)+)+ {   /* typedef void (A::*ptr_t)(args...) */
@@ -5299,6 +5429,7 @@ static void parseCompounds(Entry *rt)
       strcpy( yyFileName, ce->fileName ) ;
       setContext();
       yyLineNr = ce->startLine ;
+      insideObjC = ce->objc;
       //printf("---> Inner block starts at line %d\n",yyLineNr);
       //current->reset();
       current = new Entry;
@@ -5314,7 +5445,7 @@ static void parseCompounds(Entry *rt)
           current->protection = protection = Public ; 
 	else if (ce->fileName.right(5)==".java")
           current->protection = protection = Package ; 
-	else
+	else 
           current->protection = protection = Private ;
       }
       else if (ce->section == Entry::ENUM_SEC ) // enum
@@ -5329,7 +5460,18 @@ static void parseCompounds(Entry *rt)
 	}
 	current->protection = protection = ce->protection;
       }
-      else // named struct, union, or interface
+      else if (ce->section==Entry::INTERFACE_SEC)
+      {
+	if (ce->objc)
+	{
+	  current->protection = protection = Protected ;
+	}
+	else
+	{
+	  current->protection = protection = Public ;
+	}
+      }
+      else // named struct, union
       {
 	current->protection = protection = Public ;
       }
diff --git a/src/translator_ke.h b/src/translator_ke.h
new file mode 100644
index 0000000..31b4bba
--- /dev/null
+++ b/src/translator_ke.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2003 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_KE_H
+#define TRANSLATOR_KE_H
+
+class TranslatorKoreanEn : public TranslatorEnglish
+{
+  public:
+    virtual QCString idLanguage()
+    { return "korean-en"; }
+    virtual QCString latexLanguageSupportCommand()
+      {
+	return "\\usepackage{hfont}\n";
+      }
+    /*! returns the name of the package that is included by LaTeX */
+    virtual QCString idLanguageCharset()
+    {
+		return "euc-kr";
+    }
+
+    virtual QCString trRTFansicp()
+    {
+      return "1252";
+    }
+
+    /*! Used as ansicpg for RTF fcharset
+     *  \see trRTFansicp() for a table of possible values.
+     */
+    virtual QCString trRTFCharSet()
+    {
+      return "0";
+    }
+};
+
+#endif
diff --git a/src/translator_sr.h b/src/translator_sr.h
index 4ee9a12..50f578f 100644
--- a/src/translator_sr.h
+++ b/src/translator_sr.h
@@ -19,8 +19,9 @@
 #define TRANSLATOR_SR_H
 
 // translation by Dejan D. M. Milosavljevic <dmilos@email.com>;<dmilosx@ptt.yu>  
+// // 10x 2 Ivana Miletic for gramatical consutation.
 
-class TranslatorSerbian : public TranslatorAdapter_1_3_3
+class TranslatorSerbian : public Translator
 {                                
 private:
    QCString decode(const QCString& sInput)
@@ -306,7 +307,7 @@ private:
       
       if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C"))
       {
-        result+="funkcija, promenjiva, makro zamena, enum-a, i typedef-va";
+        result+="funkcija, promenjiva, makro zamena, enum-ova, i typedef-ova";
       }
       else
       {
@@ -319,6 +320,7 @@ private:
         result+="datoteke u kojima se nalaze:";
       else 
         result+=" dokumentaciju:";
+
       return decode( result );
     }
 
@@ -491,7 +493,7 @@ private:
      *  of documentation blocks for enumeration types
      */
     virtual QCString trEnumerationTypeDocumentation()
-    { return "Dokumetacija enum tipa"; }
+    { return "Dokumetacija enum-a"; }
 
     /*! This is used in the documentation of a file/namespace before the list 
      *  of documentation blocks for enumeration values
@@ -534,7 +536,7 @@ private:
       QCString result=(QCString)"Napravljeno "+date;
       if (projName) result+=(QCString)" za "+projName;
       result+=(QCString)" od";
-      return result;
+      return decode( result );
     }
     /*! This is part of the sentence used in the standard footer of each page.
      */
@@ -563,7 +565,7 @@ private:
 
     /*! this text is generated when the \\bug command is used. */
     virtual QCString trBugsAndLimitations()
-    { return decode("Gre�ke i ograni�enja"); }
+    { return decode( "Gre�ke i ograni�enja" ); }
 
     /*! this text is generated when the \\version command is used. */
     virtual QCString trVersion()
@@ -971,7 +973,7 @@ private:
     }
     virtual QCString trPrivateTypes()
     {
-      return "Privatni tipovi";
+      return decode( "Privatni tipovi" );
     }
     virtual QCString trPrivateAttribs()
     {
@@ -1011,7 +1013,7 @@ private:
     }
     virtual QCString trAttention()
     {
-      return decode("Pa�nja");;
+      return decode( "Pa�nja" );
     }
     virtual QCString trInclByDepGraph()
     {
@@ -1135,12 +1137,12 @@ private:
     /*! Used as a section header for IDL properties */
     virtual QCString trProperties()
     {
-      return "Osobine";
+      return decode( "Osobine" );
     }
     /*! Used as a section header for IDL property documentation */
     virtual QCString trPropertyDocumentation()
     {
-      return "Dokumentacija osobina";
+      return decode( "Dokumentacija osobina" );
     }
 
 //////////////////////////////////////////////////////////////////////////
@@ -1202,12 +1204,12 @@ private:
     /*! Used as a marker that is put before a \\bug item */
     virtual QCString trBug()
     {
-      return decode("Gre�ka");;
+      return decode( "Gre�ka" );
     }
     /*! Used as the header of the bug list */
     virtual QCString trBugList()
     {
-      return decode("Spisak gre�aka");;
+      return decode( "Spisak gre�aka" );
     }
 
 //////////////////////////////////////////////////////////////////////////
@@ -1256,7 +1258,7 @@ private:
     /*! Used as header RTF general index */
     virtual QCString trRTFGeneralIndex()
     {
-      return decode("Sadr�aj");;
+      return decode( "Sadr�aj" );
     }
    
     /*! This is used for translation of the word that will possibly
@@ -1265,7 +1267,7 @@ private:
      */
     virtual QCString trClass(bool first_capital, bool singular)
     { 
-      QCString result((first_capital ? "Klas" : "klas"));
+      QCString result( (first_capital ? "Klas" : "klas") );
       result+= (singular ? "a" : "e");
       return result; 
     }
@@ -1358,7 +1360,7 @@ private:
     {                                                                         
       QCString result((first_capital ? "Autor" : "autor"));
       result+= (singular ? "" : "i");
-      return result; 
+      return decode( result ); 
     }
 
 //////////////////////////////////////////////////////////////////////////
@@ -1369,7 +1371,7 @@ private:
      */
     virtual QCString trReferences()
     {
-      return "Koristi";
+      return decode( "Koristi" );
     }
 
 //////////////////////////////////////////////////////////////////////////
@@ -1389,7 +1391,7 @@ private:
      */
     virtual QCString trImplementedInList(int numEntries)
     {
-      return "Definisano u " + trWriteList(numEntries) + "." ;
+      return decode( "Definisano u " + trWriteList(numEntries) + "." );
     }
 
 //////////////////////////////////////////////////////////////////////////
@@ -1424,12 +1426,12 @@ private:
      */
     virtual QCString trEvents()
     {
-      return "Doga�aji";
+      return decode( "Doga�aji" );
     }
     /*! Header used for the documentation section of a class' events. */
     virtual QCString trEventDocumentation()
     {
-      return "Dokumentacija doga�aja";
+      return decode( "Dokumentacija doga�aja" );
     }
 //////////////////////////////////////////////////////////////////////////
 // new since 1.3
@@ -1439,35 +1441,35 @@ private:
      */
     virtual QCString trPackageTypes()
     { 
-      return "Tipovi u Paketu";
+      return decode( "Tipovi u Paketu" );
     }
     /*! Used as a heading for a list of Java class functions with package 
      * scope. 
      */
     virtual QCString trPackageMembers()
     { 
-      return "Funkcije u paketu";
+      return decode( "Funkcije u paketu" );
     }
     /*! Used as a heading for a list of static Java class functions with 
      *  package scope.
      */
     virtual QCString trStaticPackageMembers()
     { 
-      return "Stati�ke funkcije u paketu";  // Zajednicke funkcije u paketu
+      return decode( "Stati�ke funkcije u paketu" );  // Zajednicke funkcije u paketu
     }
     /*! Used as a heading for a list of Java class variables with package 
      * scope.
      */
     virtual QCString trPackageAttribs()
     { 
-      return "Atributi u paketu"; // Clanovi u paketu
+      return decode( "Atributi u paketu" ); // Clanovi u paketu
     }
     /*! Used as a heading for a list of static Java class variables with 
      * package scope.
      */
     virtual QCString trStaticPackageAttribs()
     { 
-      return "Stati�ki atributi u paketu";  // Zajednicki clanovi u paketu
+      return  decode( "Stati�ki atributi u paketu" );  // Zajednicki clanovi u paketu
     }
     
 //////////////////////////////////////////////////////////////////////////
@@ -1479,21 +1481,77 @@ private:
      */
     virtual QCString trAll()
     {
-      return "Sve";
+      return decode( "Sve" );
     }
     /*! Put in front of the call graph for a function. */
     virtual QCString trCallGraph()
     {
-      return "Graf pozivanja finkcija:";
+      return decode( "Graf pozivanja funkcija:" );
+    }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.3.3
+//////////////////////////////////////////////////////////////////////////
+
+    /*! When the search engine is enabled this text is put in the header 
+     *  of each page before the field where one can enter the text to search 
+     *  for. 
+     */
+    virtual QCString trSearchForIndex()
+    {
+      return decode("Tra�i");
+    }
+    /*! This string is used as the title for the page listing the search
+     *  results.
+     */
+    virtual QCString trSearchResultsTitle()
+    {
+      return decode( "Rezultati pretra�ivanja" );
+    }
+    /*! This string is put just before listing the search results. The
+     *  text can be different depending on the number of documents found.
+     *  Inside the text you can put the special marker $num to insert
+     *  the number representing the actual number of search results.
+     *  The @a numDocuments parameter can be either 0, 1 or 2, where the 
+     *  value 2 represents 2 or more matches. HTML markup is allowed inside
+     *  the returned string.
+     */
+    virtual QCString trSearchResults(int numDocuments)
+    {
+      if (numDocuments==0)
+      {
+        return decode("Nema dokumenta koji odgovaraju va�em upitu");
+      }
+      else if (numDocuments==1)
+      { // 10x 2 Ivana Miletic 4 gramatical consutation.
+        return decode("Na�en je <b>1</b> dokument koji odgovara va�em upitu.");
+      }
+    else if (numDocuments<5) 
+    {  // 10x 2 Ivana Miletic 4 gramatical consutation.
+      return decode("Na�ena su <b>$num</b> dokumenta koji odgovaraju va�em upitu."
+                    "Najbolji su prikazani prvi.");
+    }
+    else 
+    {  // 10x 2 Ivana Miletic 4 gramatical consutation.
+      return decode("Na�eno je <b>$num</b> dokumenata koji odgovaraju va�em upitu."
+        "Najbolji su prikazani prvi.");
+    }
+    }
+    /*! This string is put before the list of matched words, for each search 
+     *  result. What follows is the list of words that matched the query.
+     */
+    virtual QCString trSearchMatches()
+    {
+      return decode( "Prona�eno:" );
     }
 
  
 };
 
-// sh - � - shashavo
-// dj - � - djordje
-// ch - � - chasha
-// cc - � - cciccifu
-// zz - � - zzaba
+// sh -    � - shashavo  (,�)
+// dj -    � - djordje
+// ch - �, � - chasha
+// cc -    � - cciccifu
+// zz -    � - zzaba     
 
 #endif
diff --git a/src/util.cpp b/src/util.cpp
index d268f8e..fd95766 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -26,6 +26,7 @@
 #include <qfileinfo.h>
 #include <qdir.h>
 #include <qdatetime.h>
+#include <qcache.h>
 
 #include "util.h"
 #include "message.h"
@@ -58,6 +59,17 @@ extern char **environ;
 #endif
 
 //------------------------------------------------------------------------
+
+static QCache<int> g_accessibilityCache(10000,10000); 
+
+class CacheInitializer
+{
+  public:
+    CacheInitializer() { g_accessibilityCache.setAutoDelete(TRUE); }
+} g_cacheInitializer;
+
+
+//------------------------------------------------------------------------
 // TextGeneratorOLImpl implementation
 //------------------------------------------------------------------------
 
@@ -689,7 +701,8 @@ static Definition *followPath(Definition *start,FileDef *fileScope,const QCStrin
 bool accessibleViaUsingClass(const ClassSDict *cl,
                              FileDef *fileScope,
                              Definition *item,
-                             const QCString &explicitScopePart="")
+                             const QCString &explicitScopePart=""
+                            )
 {
   if (cl) // see if the class was imported via a using statement 
   {
@@ -697,6 +710,7 @@ bool accessibleViaUsingClass(const ClassSDict *cl,
     ClassDef *ucd;
     for (cli.toFirst();(ucd=cli.current());++cli)
     {
+      //printf("Trying via used class %s\n",ucd->name().data());
       Definition *sc = explicitScopePart.isEmpty() ? ucd : followPath(ucd,fileScope,explicitScopePart);
       if (item->definitionType()==Definition::TypeMember)
       {
@@ -712,6 +726,7 @@ bool accessibleViaUsingClass(const ClassSDict *cl,
       {
         if (sc && sc==item) return TRUE; 
       }
+      //printf("Try via used class done\n");
     }
   }
   return FALSE;
@@ -728,8 +743,10 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl,
     NamespaceDef *und;
     for (nli.toFirst();(und=nli.current());++nli)
     {
+      //printf("Trying via used namespace %s\n",und->name().data());
       Definition *sc = explicitScopePart.isEmpty() ? und : followPath(und,fileScope,explicitScopePart);
       if (sc && item->getOuterScope()==sc) return TRUE; 
+      //printf("Try via used namespac done\n");
     }
   }
   return FALSE;
@@ -740,24 +757,39 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl,
  */
 int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item)
 {
-  //printf("<isAccesibleFrom(%s,%s)\n",scope?scope->name().data():"<global>",
-  //                                      item?item->name().data():"<none>");
+  //printf("<isAccesibleFrom(%s,%s)\n",scope->name().data(),item->name().data());
+  QCString key=scope->name()+"+"+item->name();
+  int *pval=g_accessibilityCache.find(key);
+  int result=0; // assume we found it
+  int i;
+  if (pval) // value was cached
+  {
+    //printf("> found cached value=%d\n",*pval);
+    return *pval; 
+  }
   if (item->getOuterScope()==scope) 
   {
     //printf("> found it\n");
-    return 0; // found it
   }
   else if (scope==Doxygen::globalScope)
   {
     if (fileScope)
     {
       ClassSDict *cl = fileScope->getUsedClasses();
-      if (accessibleViaUsingClass(cl,fileScope,item)) return 0;
+      if (accessibleViaUsingClass(cl,fileScope,item)) 
+      {
+        //printf("> found via used class\n");
+        goto done;
+      }
       NamespaceSDict *nl = fileScope->getUsedNamespaces();
-      if (accessibleViaUsingNamespace(nl,fileScope,item)) return 0;
+      if (accessibleViaUsingNamespace(nl,fileScope,item)) 
+      {
+        //printf("> found via used namespace\n");
+        goto done;
+      }
     }
-    return -1; // not found in path to globalScope
     //printf("> reached global scope\n");
+    result=-1; // not found in path to globalScope
   }
   else // keep searching
   {
@@ -766,16 +798,26 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item)
     {
       NamespaceDef *nscope = (NamespaceDef*)scope;
       ClassSDict *cl = nscope->getUsedClasses();
-      if (accessibleViaUsingClass(cl,fileScope,item)) return 0;
+      if (accessibleViaUsingClass(cl,fileScope,item)) 
+      {
+        //printf("> found via used class\n");
+        goto done;
+      }
       NamespaceSDict *nl = nscope->getUsedNamespaces();
-      if (accessibleViaUsingNamespace(nl,fileScope,item)) return 0;
+      if (accessibleViaUsingNamespace(nl,fileScope,item)) 
+      {
+        //printf("> found via used namespace\n");
+        goto done;
+      }
     }
-
     // repeat for the parent scope
-    int i=isAccessibleFrom(scope->getOuterScope(),fileScope,item);
-    //printf("> continue\n");
-    return (i==-1) ? -1 : i+1;
+    i=isAccessibleFrom(scope->getOuterScope(),fileScope,item);
+    //printf("> result=%d\n",i);
+    result= (i==-1) ? -1 : i+1;
   }
+done:
+  g_accessibilityCache.insert(key,new int(result));
+  return result;
 }
 
 
@@ -794,6 +836,14 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item,
   //printf("<isAccesibleFrom(%s,%s,%s)\n",scope?scope->name().data():"<global>",
   //                                      item?item->name().data():"<none>",
   //                                      explicitScopePart.data());
+  QCString key=scope->name()+"+"+item->name()+"+"+explicitScopePart;
+  int *pval=g_accessibilityCache.find(key);
+  int result=0; // assume we found it
+  if (pval) // value was cached
+  {
+    //printf("> found cached value=%d\n",*pval);
+    return *pval; 
+  }
   Definition *newScope = followPath(scope,fileScope,explicitScopePart);
   if (newScope)  // explicitScope is inside scope => newScope is the result
   {
@@ -801,7 +851,6 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item,
     if (item->getOuterScope()==newScope) 
     {
       //printf("> found it\n");
-      return 0; // found it
     }
     else 
     {
@@ -811,8 +860,8 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item,
       {
         i = isAccessibleFrom(scope->getOuterScope(),fileScope,item,explicitScopePart);
       }
-      //printf("> continue\n");
-      return (i==-1) ? -1 : i+1;
+      //printf("> result=%d\n",i);
+      result = (i==-1) ? -1 : i+1;
     }
   }
   else // failed to resolve explicitScope
@@ -822,29 +871,48 @@ int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item,
     {
       NamespaceDef *nscope = (NamespaceDef*)scope;
       ClassSDict *cl = nscope->getUsedClasses();
-      if (accessibleViaUsingClass(cl,fileScope,item,explicitScopePart)) return 0;
+      if (accessibleViaUsingClass(cl,fileScope,item,explicitScopePart)) 
+      {
+        //printf("> found in used class\n");
+        goto done;
+      }
       NamespaceSDict *nl = nscope->getUsedNamespaces();
-      if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) return 0;
+      if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) 
+      {
+        //printf("> found in used namespace\n");
+        goto done;
+      }
     }
     if (scope==Doxygen::globalScope)
     {
       if (fileScope)
       {
         ClassSDict *cl = fileScope->getUsedClasses();
-        if (accessibleViaUsingClass(cl,fileScope,item,explicitScopePart)) return 0;
+        if (accessibleViaUsingClass(cl,fileScope,item,explicitScopePart)) 
+        {
+          //printf("> found in used class\n");
+          goto done;
+        }
         NamespaceSDict *nl = fileScope->getUsedNamespaces();
-        if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) return 0;
+        if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart)) 
+        {
+          //printf("> found in used namespace\n");
+          goto done;
+        }
       }
-      //printf("> reached global scope\n");
-      return -1;
+      //printf("> not found\n");
+      result=-1;
     }
     else // continue by looking into the parent scope
     {
       int i=isAccessibleFrom(scope->getOuterScope(),fileScope,item,explicitScopePart);
-      //printf("> continue\n");
-      return (i==-1) ? -1 : i+1;
+      //printf("> result=%d\n",i);
+      result= (i==-1) ? -1 : i+1;
     }
   }
+done:
+  g_accessibilityCache.insert(key,new int(result));
+  return result;
 }
 
 /* Find the fully qualified class name refered to by the input class
@@ -873,11 +941,19 @@ ClassDef *getResolvedClassRec(Definition *scope,
     replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
     name=name.mid(qualifierIndex+2);
   }
-  if (name.isEmpty()) return 0; // empty name
+  if (name.isEmpty()) 
+  {
+    //printf("] empty name\n");
+    return 0; // empty name
+  }
 
   DefinitionList *dl = Doxygen::symbolMap->find(name);
   //printf("Looking for symbol %s result=%p\n",name.data(),dl);
-  if (dl==0) return 0; // symbol not found
+  if (dl==0) 
+  {
+    //printf("] no such symbol\n");
+    return 0; // symbol not found
+  }
 
   //printf(" found %d symbol with name %s\n",dl->count(),name.data());
   // now we look int the list of Definitions and determine which one is the "best"
@@ -889,7 +965,8 @@ ClassDef *getResolvedClassRec(Definition *scope,
   int minDistance=10000; // init at "infinite"
   for (dli.toFirst();(d=dli.current());++dli) // foreach definition
   {
-    //printf("  found type %x name=%s\n",d->definitionType(),d->name().data());
+    //printf("  found type %x name=%s\n",
+    //       d->definitionType(),d->name().data());
     // only look at classes and members
     if (d->definitionType()==Definition::TypeClass ||
         d->definitionType()==Definition::TypeMember)
@@ -930,7 +1007,6 @@ ClassDef *getResolvedClassRec(Definition *scope,
               bestTypedef = md;
               bestTemplSpec = spec;
             }
-
           }
         }
       } // if definition accessible
@@ -944,7 +1020,8 @@ ClassDef *getResolvedClassRec(Definition *scope,
   {
     *pTemplSpec = bestTemplSpec;
   }
-  //printf("] bestMatch=%s\n",bestMatch?bestMatch->name().data():"<none>");
+  //printf("] bestMatch=%s distance=%d\n",
+  //    bestMatch?bestMatch->name().data():"<none>",minDistance);
   return bestMatch;
 }
 
@@ -969,10 +1046,14 @@ ClassDef *getResolvedClass(Definition *scope,
   {
     scope=Doxygen::globalScope;
   }
+  //printf("-------- start\n");
+  //printf("getResolvedClass(%s,%s)\n",scope?scope->name().data():"<global>",n);
   ClassDef *result = getResolvedClassRec(scope,fileScope,n,pTypeDef,pTemplSpec);
   if (result && !result->isLinkable()) result=0; // don't link to artifical classes
   //printf("getResolvedClass(%s,%s)=%s\n",scope?scope->name().data():"<global>",
   //                                  n,result?result->name().data():"<none>");
+  //
+  //printf("-------- end\n");
   return result;
 }
 
@@ -1296,6 +1377,10 @@ QCString argListToString(ArgumentList *al)
   result+="(";
   while (a)
   {
+    if (!a->attrib.isEmpty())
+    {
+      result+=a->attrib+" ";
+    }
     if (!a->name.isEmpty() || !a->array.isEmpty())
     {
       result+= a->type+" "+a->name+a->array;
@@ -4323,7 +4408,8 @@ void filterLatexString(QTextStream &t,const char *str,
   static bool isCzech         = theTranslator->idLanguage()=="czech";
   static bool isJapanese      = theTranslator->idLanguage()=="japanese" ||
                                 theTranslator->idLanguage()=="japanese-en";
-  static bool isKorean        = theTranslator->idLanguage()=="korean";
+  static bool isKorean        = theTranslator->idLanguage()=="korean" ||
+	  							theTranslator->idLanguage()=="korean-en";
   static bool isRussian       = theTranslator->idLanguage()=="russian";
   static bool isUkrainian     = theTranslator->idLanguage()=="ukrainian";
   static bool isChinese       = theTranslator->idLanguage()=="chinese" || 
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 5c0c191..4194a94 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -1377,7 +1377,7 @@ static void generateXMLForGroup(GroupDef *gd,QTextStream &ti)
     GroupDef *sgd;
     for (gli.toFirst();(sgd=gli.current());++gli)
     {
-      t << "    <innergroup refid=\"" << gd->getOutputFileBase()
+      t << "    <innergroup refid=\"" << sgd->getOutputFileBase()
         << "\">" << convertToXML(sgd->groupTitle()) 
         << "</innergroup>" << endl;
     }
diff --git a/wintools/Doxygen.dsp b/wintools/Doxygen.dsp
index 72e41ea..3cfcfc1 100644
--- a/wintools/Doxygen.dsp
+++ b/wintools/Doxygen.dsp
@@ -278,10 +278,6 @@ SOURCE=..\src\outputlist.cpp
 # End Source File
 # Begin Source File
 
-SOURCE=..\src\packagedef.cpp
-# End Source File
-# Begin Source File
-
 SOURCE=..\src\pagedef.cpp
 # End Source File
 # Begin Source File
@@ -550,10 +546,6 @@ SOURCE=..\src\outputlist.h
 # End Source File
 # Begin Source File
 
-SOURCE=..\src\packagedef.h
-# End Source File
-# Begin Source File
-
 SOURCE=..\src\pagedef.h
 # End Source File
 # Begin Source File
-- 
cgit v0.12

