 doc/commands.doc      |  22 ++++++
 src/commentscan.l     |  33 ++++++++-
 src/doxygen.cpp       |  20 ++++++
 src/entry.cpp         |   3 +-
 src/entry.h           |   3 +
 src/groupdef.h        |   9 ++-
 src/index.cpp         |  25 +++----
 src/libdoxygen.pro.in |   6 +-
 src/marshal.cpp       |   2 +
 src/membername.cpp    |  13 ++--
 src/sortkey.cpp       | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/sortkey.h         |  33 +++++++++
 12 files changed, 335 insertions(+), 27 deletions(-)

diff --git a/doc/commands.doc b/doc/commands.doc
index 7054c11..13b8ad6 100644
--- a/doc/commands.doc
+++ b/doc/commands.doc
@@ -192,6 +192,7 @@ documentation:
 \refitem cmdweakgroup \\weakgroup
 \refitem cmdxmlonly \\xmlonly
 \refitem cmdxrefitem \\xrefitem
+\refitem cmdsortkey \\sk
 \refitem cmddollar \\\$
 \refitem cmdat \\\@
 \refitem cmdbackslash \\\\
@@ -2170,6 +2171,27 @@ Commands for displaying examples
   Files or directories that doxygen should look for can be specified using the
   \ref cfg_example_path "EXAMPLE_PATH" tag of doxygen's configuration file.
 
+
+<hr>
+\section cmdsortkey \\sk <HowToReadTheEntry>
+
+  \addindex \\sk
+  This command changes where to place the entry in indices.
+  The entry can be anything the documentationable. Functions, classes, macros,
+  files, varuables or etc. 
+  
+  This command is similar to the sort-key feature in Wikipedia/MediaWiki.
+  
+  The configures \ref cfg_alphabetical_index "ALPHABETICAL_INDEX" or SORT_* commands
+  you want should be YES, otherwise \a \\sk commands makes no effect.
+  
+  For example, consider the class named "OriginalNameClass" exists,
+  but \"\a \\sk renamedClass\" command is also given. This command places the entry 
+  into header group "R" in the indices instead of "O".
+  
+  If you want just snip prefix, like "QXxxx" to "Xxxx", consider to configure
+  \ref cfg_ignore_prefix "IGNORE_PREFIX".
+
 <hr>
 
 \htmlonly <center> \endhtmlonly
diff --git a/src/commentscan.l b/src/commentscan.l
index 886c2dd..0781d50 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -47,6 +47,7 @@
 #include "markdown.h"
 #include "condparser.h"
 #include "formula.h"
+#include "sortkey.h"
 
 #define YY_NO_INPUT 1
 
@@ -118,6 +119,7 @@ static bool handleExtends(const QCString &);
 static bool handleCopyDoc(const QCString &);
 static bool handleCopyBrief(const QCString &);
 static bool handleCopyDetails(const QCString &);
+static bool handleSortKey(const QCString& s);
 
 typedef bool (*DocCmdFunc)(const QCString &name);
 
@@ -247,6 +249,7 @@ static DocCmdMap docCmdMap[] =
   { "sa",              0,                       TRUE  },
   { "see",             0,                       TRUE  },
   { "since",           0,                       TRUE  },
+  { "sk",              &handleSortKey,          FALSE },
   { "throw",           0,                       TRUE  },
   { "throws",          0,                       TRUE  },
   { "until",           0,                       TRUE  },
@@ -847,7 +850,7 @@ DCMD5     ("latexonly"|"li"|"line"|"manonly"|"name")
 DCMD6     ("note"|"par"|"paragraph"|"param"|"post")
 DCMD7     ("pre"|"remarks"|(("relate"[sd])("also")?))
 DCMD8     ("remarks"|("return"[s]?)|"retval"|"sa"|"section")
-DCMD9     ("see"|"since"|"subsection"|"subsubsection")
+DCMD9     ("see"|"since"|"sk"|"subsection"|"subsubsection")
 DCMD10    ("throw"|"until"|"verbatim")
 DCMD11    ("verbinclude"|"version"|"warning")
 DETAILEDCMD {CMD}({DCMD1}|{DCMD2}|{DCMD3}|{DCMD4}|{DCMD5}|{DCMD6}|{DCMD7}|{DCMD8}|{DCMD9}|{DCMD10}|{DCMD11})
@@ -928,6 +931,7 @@ RCSTAG    "$"{ID}":"[^\n$]+"$"
 %x	CiteLabel
 %x	CopyDoc
 %x      GuardExpr
+%x  SortKeyArg1
 
 %%
 
@@ -2143,6 +2147,27 @@ RCSTAG    "$"{ID}":"[^\n$]+"$"
 					  addOutput(yytext);
   					}
 
+  /* ----- handle arguments of the sk(sortkey) command ------- */
+
+<SortKeyArg1>({ID}("::"|"."))*{ID}	{ // argument
+					  //printf("Catch \\sk command %s\n", yytext);
+					  current->sortKey = yytext;
+					  BEGIN( Comment );
+					}
+<SortKeyArg1>{LC}			{ // line continuation
+                                          yyLineNr++; 
+					  addOutput('\n');
+  					}
+<SortKeyArg1>{DOCNL}			{ // missing argument
+  					  warn(yyFileName,yyLineNr,
+					      "Missing argument of \\sk command"
+					      );
+  					  if (*yytext=='\n') yyLineNr++;
+					  addOutput('\n');
+					  BEGIN( Comment );
+  					}
+<SortKeyArg1>.			{ // ignore other stuff
+  					}
 
 %%
 
@@ -2732,6 +2757,12 @@ static bool handleCopyDoc(const QCString &)
   return FALSE;
 }
 
+static bool handleSortKey(const QCString& )
+{
+	BEGIN( SortKeyArg1 );
+	return FALSE;
+}
+
 //----------------------------------------------------------------------------
 
 static void checkFormula()
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 972d758..0141438 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -97,6 +97,7 @@
 #include "docsets.h"
 #include "formula.h"
 #include "settings.h"
+#include "sortkey.h"
 
 #define RECURSE_ENTRYTREE(func,var) \
   do { if (var->children()) { \
@@ -8798,6 +8799,19 @@ static void buildExampleList(EntryNav *rootNav)
   RECURSE_ENTRYTREE(buildExampleList,rootNav);
 }
 
+
+//----------------------------------------------------------------------
+static void buildSortKeyRelatedList(EntryNav *rootNav)
+{
+  QCString sortKey = rootNav->sortKey();
+  //printf("buildSortKeyRelatedList(%s, %s)\n",rootNav->name().data(), sortKey.data());
+  if (!rootNav->name().isEmpty() && !sortKey.isEmpty()) 
+  {
+    addSortKey( sortKey, rootNav->name() );
+  }
+  RECURSE_ENTRYTREE( buildSortKeyRelatedList, rootNav );
+}
+
 //----------------------------------------------------------------------------
 // prints the Entry tree (for debugging)
 
@@ -10811,6 +10825,12 @@ void parseInput()
    *             Gather information                                         * 
    **************************************************************************/
 
+
+  g_s.begin("Building sortkey related list...\n");
+  buildSortKeyRelatedList(rootNav);
+  //dumpSortKey();
+  g_s.end();
+
   g_s.begin("Building group list...\n");
   buildGroupList(rootNav);
   organizeSubGroups(rootNav);
diff --git a/src/entry.cpp b/src/entry.cpp
index 15263ab..0547eca 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -134,6 +134,7 @@ Entry::Entry(const Entry &e)
   artificial  = e.artificial;
   groupDocType = e.groupDocType;
   id          = e.id;
+  sortKey     = e.sortKey;
 
   m_parent    = e.m_parent;
   m_sublist   = new QList<Entry>;
@@ -343,7 +344,7 @@ Entry *Entry::removeSubEntry(Entry *e)
 EntryNav::EntryNav(EntryNav *parent, Entry *e)
              : m_parent(parent), m_subList(0), m_section(e->section), m_type(e->type),
               m_name(e->name), m_fileDef(0), m_lang(e->lang), 
-              m_info(0), m_offset(-1), m_noLoad(FALSE) 
+              m_info(0), m_offset(-1), m_noLoad(FALSE), m_sortKey(e->sortKey)
 {
   if (e->tagInfo)
   {
diff --git a/src/entry.h b/src/entry.h
index cecd095..8876573 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -283,6 +283,7 @@ class Entry
     bool        artificial;   //!< Artificially introduced item
     GroupDocType groupDocType;
     QCString    id;           //!< libclang id
+    QCString    sortKey;      //!< sortkey given with \\sk command
 
 
     static int  num;          //!< counts the total number of entries
@@ -347,6 +348,7 @@ class EntryNav
     const QList<EntryNav> *children() const { return m_subList; }
     EntryNav *parent() const { return m_parent; }
     FileDef *fileDef() const { return m_fileDef; }
+    const QCString sortKey() const { return m_sortKey; }
 
   private:
 
@@ -358,6 +360,7 @@ class EntryNav
     int          m_section;     //!< entry type (see Sections);
     QCString	 m_type;        //!< member type 
     QCString	 m_name;        //!< member name
+    QCString	 m_sortKey;     //!< sortkey given with \\sk command
     TagInfo     *m_tagInfo;      //!< tag file info
     FileDef     *m_fileDef;
     SrcLangExt   m_lang;         //!< programming language in which this entry was found
diff --git a/src/groupdef.h b/src/groupdef.h
index bd53ff5..a7e046c 100644
--- a/src/groupdef.h
+++ b/src/groupdef.h
@@ -20,6 +20,7 @@
 
 #include "sortdict.h"
 #include "definition.h"
+#include "sortkey.h"
 
 class MemberList;
 class FileList;
@@ -161,7 +162,9 @@ class GroupSDict : public SDict<GroupDef>
     virtual ~GroupSDict() {}
     int compareItems(QCollection::Item item1,QCollection::Item item2)
     {
-      return qstrcmp(((GroupDef*)item1)->groupTitle(),((GroupDef*)item2)->groupTitle());
+      return sortKeyAppliedStrcmp(
+               ((GroupDef*)item1)->groupTitle(),
+               ((GroupDef*)item2)->groupTitle());
     }
 };
 
@@ -171,7 +174,9 @@ class GroupList : public QList<GroupDef>
   public:
     int compareItems(QCollection::Item item1,QCollection::Item item2)
     {
-      return qstrcmp(((GroupDef*)item1)->groupTitle(),((GroupDef*)item2)->groupTitle());
+      return sortKeyAppliedStrcmp(
+               ((GroupDef*)item1)->groupTitle(),
+               ((GroupDef*)item2)->groupTitle());
     }
 };
 
diff --git a/src/index.cpp b/src/index.cpp
index 68897f0..5c2ca75 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -49,6 +49,7 @@
 #include "namespacedef.h"
 #include "filename.h"
 #include "codepointmap.h"
+#include "sortkey.h"
 
 #define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
 #define MAX_ITEMS_BEFORE_QUICK_INDEX 30
@@ -1745,7 +1746,7 @@ public:
 
     QCString n1 = c1->className();
     QCString n2 = c2->className();
-    return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2));
+    return prefixSkippedAndSortKeyAppliedStricmp(n1, n2);
   }
 };
 
@@ -1844,7 +1845,7 @@ static void writeAlphabeticalClassList(OutputList &ol)
 
       int index = getPrefixIndex(cd->className());
       //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection());
-      startLetter=getNextUtf8OrToUpper( cd->className(), index );
+      startLetter = prefixSkippedAndSortKeyAppliedStartLetter( cd->className() );
       indexLetterUsed.uniqueInSort( startLetter );
     }
   }
@@ -1889,8 +1890,7 @@ static void writeAlphabeticalClassList(OutputList &ol)
     
     if (cd->isLinkableInProject() && cd->templateMaster()==0)
     {
-      int index = getPrefixIndex(cd->className());
-      startLetter=getNextUtf8OrToUpper(cd->className(),index);
+      startLetter = prefixSkippedAndSortKeyAppliedStartLetter( cd->className() );
       // Do some sorting again, since the classes are sorted by name with 
       // prefix, which should be ignored really.
       if (cd->getLanguage()==SrcLangExt_VHDL)
@@ -2257,10 +2257,10 @@ static void writeMemberList(OutputList &ol,bool useSections,int page,
       bool isFunc=!md->isObjCMethod() && 
         (md->isFunction() || md->isSlot() || md->isSignal()); 
       QCString name=md->name();
-      int startIndex = getPrefixIndex(name);
-      if (QCString(name.data()+startIndex)!=prevName) // new entry
+      QCString idxName = getPrefixSkippedAndSortKeyApplied(name);
+      if (idxName!=prevName) // new entry
       {
-        const uint newHeadChar = getNextUtf8OrToLower( name, startIndex );
+        const uint newHeadChar = getNextUtf8OrToLower( idxName, 0 );
         if ((prevName.isEmpty() || 
             newHeadChar != getNextUtf8OrToLower(prevName , 0) ) && 
             useSections) // new section
@@ -2294,7 +2294,7 @@ static void writeMemberList(OutputList &ol,bool useSections,int page,
         // link to class
         prevDefName="";
         sep = ": ";
-        prevName = name.data()+startIndex;
+        prevName = idxName;
       }
       else // same entry
       {
@@ -2334,8 +2334,7 @@ void addClassMemberNameToIndex(MemberDef *md)
       cd->templateMaster()==0)
   {
     QCString n = md->name();
-    int index = getPrefixIndex(n);
-    uint letter = getNextUtf8OrToLower( n, index );
+    uint letter = prefixSkippedAndSortKeyAppliedStartLetter( n );
     if (!n.isEmpty()) 
     {
       bool isFriendToHide = hideFriendCompounds &&
@@ -2410,8 +2409,7 @@ void addNamespaceMemberNameToIndex(MemberDef *md)
   if (nd && nd->isLinkableInProject() && md->isLinkableInProject())
   {
     QCString n = md->name();
-    int index = getPrefixIndex(n);
-    uint letter = getNextUtf8OrToLower( n, index );
+    uint letter = prefixSkippedAndSortKeyAppliedStartLetter( n );
     if (!n.isEmpty()) 
     {
       g_namespaceIndexLetterUsed[NMHL_All][letter].append(md);
@@ -2464,8 +2462,7 @@ void addFileMemberNameToIndex(MemberDef *md)
   if (fd && fd->isLinkableInProject() && md->isLinkableInProject())
   {
     QCString n = md->name();
-    int index = getPrefixIndex(n);
-    uint letter = getNextUtf8OrToLower( n, index );
+    uint letter = prefixSkippedAndSortKeyAppliedStartLetter( n );
     if (!n.isEmpty()) 
     {
       g_fileIndexLetterUsed[FMHL_All][letter].append(md);
diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in
index c4e79da..25a8dad 100644
--- a/src/libdoxygen.pro.in
+++ b/src/libdoxygen.pro.in
@@ -176,7 +176,8 @@ HEADERS      =	arguments.h \
 		xmldocvisitor.h \
                 xmlgen.h \
                 docbookvisitor.h \
-                docbookgen.h
+                docbookgen.h \
+                sortkey.h
 
 SOURCES      =	arguments.cpp \
                 ce_lex.cpp \
@@ -269,7 +270,8 @@ SOURCES      =	arguments.cpp \
 		xmldocvisitor.cpp \
                 xmlgen.cpp \
                 docbookvisitor.cpp \
-                docbookgen.cpp
+                docbookgen.cpp \
+                sortkey.cpp
 
 win32:TMAKE_CXXFLAGS       += -DQT_NODLL 
 win32-msvc:TMAKE_CXXFLAGS  += -Zm200
diff --git a/src/marshal.cpp b/src/marshal.cpp
index a6b3e75..e42dcd2 100644
--- a/src/marshal.cpp
+++ b/src/marshal.cpp
@@ -398,6 +398,7 @@ void marshalEntry(StorageIntf *s,Entry *e)
   marshalBool(s,e->artificial);
   marshalInt(s,(int)e->groupDocType);
   marshalQCString(s,e->id);
+  marshalQCString(s,e->sortKey);
 }
 
 void marshalEntryTree(StorageIntf *s,Entry *e)
@@ -783,6 +784,7 @@ Entry * unmarshalEntry(StorageIntf *s)
   e->artificial       = unmarshalBool(s);
   e->groupDocType     = (Entry::GroupDocType)unmarshalInt(s);
   e->id               = unmarshalQCString(s);
+  e->sortKey          = unmarshalQCString(s);
   return e;
 }
 
diff --git a/src/membername.cpp b/src/membername.cpp
index 58eaf8c..c75e1ac 100644
--- a/src/membername.cpp
+++ b/src/membername.cpp
@@ -19,6 +19,7 @@
 #include "classdef.h"
 #include "util.h"
 #include "filedef.h"
+#include "sortkey.h"
 
 MemberName::MemberName(const char *n) : QList<MemberDef>()
 {
@@ -39,9 +40,9 @@ int MemberName::compareItems(QCollection::Item item1, QCollection::Item item2)
   FileDef  *f1=m1->getFileDef();
   FileDef  *f2=m2->getFileDef();
   if (c1 && c2)
-    return qstrcmp(c1->name(),c2->name());
+    return sortKeyAppliedStrcmp(c1->name(),c2->name());
   else if (f1 && f2)
-    return qstrcmp(f1->name(),f2->name());
+    return sortKeyAppliedStrcmp(f1->name(),f2->name());
   else 
     return 0;
 }
@@ -61,9 +62,9 @@ int MemberNameInfo::compareItems(QCollection::Item item1, QCollection::Item item
   FileDef  *f1=m1->memberDef->getFileDef();
   FileDef  *f2=m2->memberDef->getFileDef();
   if (c1 && c2)
-    return qstrcmp(c1->name(),c2->name());
+    return sortKeyAppliedStrcmp(c1->name(),c2->name());
   else if (f1 && f2)
-    return qstrcmp(f1->name(),f2->name());
+    return sortKeyAppliedStrcmp(f1->name(),f2->name());
   else 
     return 0;
 }
@@ -76,8 +77,6 @@ int MemberNameSDict::compareItems(QCollection::Item item1, QCollection::Item ite
 {
   MemberName *n1=(MemberName *)item1;
   MemberName *n2=(MemberName *)item2;
-  return qstricmp(n1->memberName()+getPrefixIndex(n1->memberName()),
-                 n2->memberName()+getPrefixIndex(n2->memberName())
-                );
+  return sortKeyAppliedStrcmp(n1->memberName(), n2->memberName());
 }
 
diff --git a/src/sortkey.cpp b/src/sortkey.cpp
new file mode 100644
index 0000000..fe4d95a
--- /dev/null
+++ b/src/sortkey.cpp
@@ -0,0 +1,193 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 2013 by Suzumizaki-Kimitaka
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <qmap.h>
+#include "qregexp.h"
+#include "sortkey.h"
+#include "util.h"
+
+static const QRegExp sc_lastComponentFinder("[A-Z_a-z\\x80-\\xFF][0-9A-Z_a-z\\x80-\\xFF]*$");
+static const QRegExp sc_lastSeparatorFinder("[^0-9A-Z_a-z\\x80-\\xFF]+$");
+
+/*! @file sortkey.cpp
+@brief defines sortkey related functions
+
+The sortkeys are used to notify how to read another string.
+
+When you use kanji characters to name your functions or any entries,
+the doxygen will generate headers to indices by each kanji characters.
+As you know we have thousands of kanji characters, the headers can be
+nonsense to find entries you want.
+
+With the doxygen, you can use \\sortKey &lt;TheStringHowToRead&gt; command.
+Given string with the command is used to sort within indices instead of 
+the name of the functions, classes, files or so.
+
+The behavior is similar to \ref cfg_ignore_prefix "IGNORE_PREFIX" configure.
+But you can give any character to reorder within indices.
+*/
+
+typedef QMap<QCString, QCString> SortKeyFromBaseMap;
+
+static SortKeyFromBaseMap g_sortKeyFromBase;
+
+/*! @brief get internal recorded sortkey from given identifier
+
+@param i_base the identifier string used to sort in indices.
+@return the string used to sort instead of \a i_base. if not exist, returns \a i_base.
+*/
+static QCString getSortKeyApplied(const QCString& i_base)
+{
+	if ( g_sortKeyFromBase.count() == 0 )
+	{
+		return i_base;
+	}
+	QCString base = i_base;
+	QCString retVal;
+	QRegExp componentFinder( sc_lastComponentFinder );
+	QRegExp separatorFinder( sc_lastSeparatorFinder );
+	while ( true )
+	{
+		const int componentStartsAt = componentFinder.find( base, 0 );
+		if ( componentStartsAt == -1 )
+		{
+			break;
+		}
+		const QCString component = base.mid( componentStartsAt );
+		SortKeyFromBaseMap::ConstIterator it = g_sortKeyFromBase.find( component );
+		if ( it != g_sortKeyFromBase.end() )
+		{
+			retVal.prepend( it.data() );
+		}
+		else
+		{
+			retVal.prepend( component );
+		}
+		base = base.mid( 0, componentStartsAt );
+		const int separatorStartsAt = separatorFinder.find( base, 0 );
+		if ( separatorStartsAt == -1 )
+		{
+			break;
+		}
+		retVal.prepend( base.mid( separatorStartsAt ) );
+		base = base.mid( 0, separatorStartsAt );
+	}
+	retVal.prepend( base );
+	return retVal;
+}
+
+QCString getPrefixSkippedAndSortKeyApplied(const QCString& base)
+{
+	const int idx = getPrefixIndex( base );
+	if ( idx == 0 && g_sortKeyFromBase.count() == 0 )
+	{
+		return base;
+	}
+	return getSortKeyApplied( base.mid( idx ) );
+}
+
+int prefixSkippedAndSortKeyAppliedStricmp(const QCString& left, const QCString& right)
+{
+	QCString l1 = getPrefixSkippedAndSortKeyApplied( left );
+	QCString r1 = getPrefixSkippedAndSortKeyApplied( right );
+	return qstricmp( l1, r1 );
+}
+
+int sortKeyAppliedStrcmp(const QCString& left, const QCString& right)
+{
+	QCString l1 = getSortKeyApplied( left );
+	QCString r1 = getSortKeyApplied( right );
+	return qstrcmp( l1, r1 );
+}
+
+uint prefixSkippedAndSortKeyAppliedStartLetter(const QCString& given)
+{
+	QCString s = getPrefixSkippedAndSortKeyApplied( given );
+	return getNextUtf8OrToUpper( s, 0 );
+}
+
+/*! @brief Register the relationship between sortkey and original strings
+
+The pair of the base name and its sortkey is registered by each component.
+Both \a i_sortKey and \a i_base are splitted as the components from their tails.
+
+The users can give only last part of the sortkey, but note the component
+can be the extension of the file. When \a i_base have the extension, 
+\a i_sortKey must have one. Otherwise the sortkey isn't registered correctly.
+
+When the component and its sortkey is completely same, they are not registered.
+
+When the base name of the component is already exists, simply overwrited.
+
+@param i_sortKey the string used to sort in indices instead of i_base.
+@param i_base the original name of entry like functions, classes or files.
+*/
+void addSortKey(const QCString& i_sortKey, const QCString& i_base)
+{
+	QCString sortKey = i_sortKey;
+	QCString base = i_base;
+	QRegExp componentFinder( sc_lastComponentFinder );
+	QRegExp separatorFinder( sc_lastSeparatorFinder );
+	while ( true )
+	{
+		const int lastComponentOfSortKeyStartsAt = componentFinder.match( sortKey );
+		if ( lastComponentOfSortKeyStartsAt == -1 )
+		{
+			break;
+		}
+		const int lastComponentOfBaseStartsAt = componentFinder.match( base );
+		if ( lastComponentOfBaseStartsAt == -1 )
+		{
+			break;
+		}
+		const QCString sortKeyPart = sortKey.mid( lastComponentOfSortKeyStartsAt );
+		const QCString basePart = base.mid( lastComponentOfBaseStartsAt );
+		if ( sortKeyPart != basePart )
+		{
+			g_sortKeyFromBase.insert( basePart, sortKeyPart );
+		}
+		sortKey = sortKey.mid( 0, lastComponentOfSortKeyStartsAt );
+		base = base.mid( 0, lastComponentOfBaseStartsAt );
+		int lastSeparatorStartsAt = separatorFinder.find( sortKey, 0 );
+		if ( lastSeparatorStartsAt == -1 )
+		{
+			break;
+		}
+		sortKey = sortKey.mid( 0, lastSeparatorStartsAt );
+		lastSeparatorStartsAt = separatorFinder.find( base, 0 );
+		if ( lastSeparatorStartsAt == -1 )
+		{
+			break;
+		}
+		base = base.mid( 0, lastSeparatorStartsAt );
+	}
+}
+
+/*! @brief (for debug purpose)
+
+*/
+void dumpSortKey()
+{
+	printf("Enter dumpSortKey function.\n");
+	SortKeyFromBaseMap::Iterator it = g_sortKeyFromBase.begin();
+	for (; it != g_sortKeyFromBase.end(); it++ )
+	{
+		printf("%s is sortkey of %s\n", it.data().data(), it.key().data() );
+	}
+	printf("Leave dumpSortKey function.\n");
+}
diff --git a/src/sortkey.h b/src/sortkey.h
new file mode 100644
index 0000000..4720fd3
--- /dev/null
+++ b/src/sortkey.h
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2013 by Suzumizaki-Kimitaka
+ *
+ * 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 SORTKEY_H
+#define SORTKEY_H
+
+/*! @file sortkey.h
+*   @brief \ref sortkey.cpp to see detail
+*
+*/
+
+#include <qcstring.h>
+
+void addSortKey(const QCString& sortkey, const QCString& base);
+void dumpSortKey();
+QCString getPrefixSkippedAndSortKeyApplied(const QCString& base);
+int prefixSkippedAndSortKeyAppliedStricmp(const QCString& left, const QCString& right);
+int sortKeyAppliedStrcmp(const QCString& left, const QCString& right);
+uint prefixSkippedAndSortKeyAppliedStartLetter(const QCString& s);
+
+#endif
