diff --git a/android/sqlite3_android.cpp b/android/sqlite3_android.cpp
index 27334ef..5bae652 100644
--- a/android/sqlite3_android.cpp
+++ b/android/sqlite3_android.cpp
@@ -21,6 +21,11 @@
 #include <string.h>
 #include <unistd.h>
 
+//Add by sunner
+#include <unicode/utrans.h>
+#include <unicode/putil.h>
+//end
+
 #include <unicode/ucol.h>
 #include <unicode/ustring.h>
 #include <cutils/log.h>
@@ -194,6 +199,132 @@ struct SqliteUserData {
 };
 
 /**
+ * Translit the data to Latin chars. The translitor must be already included in 
+ * external/icu4c/stubdata/icudt38l.dat
+ */
+#define TRANS_DATA_LEN	256
+#define TRANSLITERTOR_NAME_LEN	256
+#define WORDS_NUM	32
+
+void TransToLatin(const UChar* origData, UChar *latinData)
+{
+	static bool inited = false;
+	static UTransliterator *tl = NULL;
+	UErrorCode error = U_ZERO_ERROR;
+
+//	UEnumeration* ids = utrans_openIDs(&error);
+//	if (ids == NULL) {
+//		LOGE("openIDs Error: %s", u_errorName(error));
+//	}
+
+//	const char *p;
+//	LOGW("---<<====%d===>>---", uenum_count(ids, &error));
+//	while (p = uenum_next(ids, &len, &error)) {
+//		LOGW(p);
+//	}
+
+	if (!inited) {
+		inited = true;
+        UChar tlID[TRANSLITERTOR_NAME_LEN];
+
+        // Get transliter name from config file. So it can support more languages
+		FILE * cfgfile = fopen("/data/patch/config", "r");
+		if (cfgfile != NULL) {
+            char torname[TRANSLITERTOR_NAME_LEN];
+            while (fgets(torname, TRANSLITERTOR_NAME_LEN, cfgfile)) {
+				if (torname[0] == '#')
+					continue;
+				else {
+					int len = strlen(torname);
+
+					//get rid of \n
+					if (torname[len-1] == '\n') {
+						torname[len-1] = '\0';
+						len--;
+					}
+
+    				//LOGD("Use translitertor: %s (%d)", torname, len);
+
+					u_charsToUChars(torname, tlID, len+1);
+
+					break;
+				}
+			}
+		} else { // Use Han-Latin only
+            u_charsToUChars("Han-Latin", tlID, 9);
+        }
+
+        tl = utrans_openU(tlID, -1, UTRANS_FORWARD, NULL, 0, NULL, &error);
+        if (tl == NULL) {
+            LOGE("Can't open transliterator. Error: %s", u_errorName(error));
+        }
+	}
+
+	u_strncpy(latinData, origData, TRANS_DATA_LEN-1);
+
+	if (tl != NULL) {
+		int limit = u_strlen(origData);
+		int len = limit;
+		utrans_transUChars(tl, latinData, &len, TRANS_DATA_LEN, 0, &limit, &error);
+	}
+
+	// open once and use forever
+	// utrans_close(tl);
+}
+
+/**
+ * Change
+ *     "Dennis M. Ritchie" (data)
+ * To
+ *     "DMRitchie DennisM.Ritchie M.Ritchie Ritchie" (keywords)
+ * 
+ * return the number of keywords
+ */
+int MakeKeywords(UChar * data, const UChar* delim, UChar keywords[][TRANS_DATA_LEN]) {
+	UChar init[TRANS_DATA_LEN] = {0};
+
+    UChar *token = NULL;
+    UChar *prevToken = NULL;
+    UChar *state;
+    
+    token = u_strtok_r(data, delim, &state);
+	if (token == NULL)
+		return 0;
+
+    int numTokens = 0;    
+	do {
+		numTokens++;
+		// If it is not the first token, 
+		// append the first char of previous token
+		if (numTokens > 1 && u_strlen(keywords[0]) < TRANS_DATA_LEN-2) {
+			u_strncat(keywords[0], prevToken, 1);
+        }
+
+		// Store words
+		for (int i=1; i<=numTokens && i<WORDS_NUM; i++) {
+            int len = u_strlen(keywords[i]);
+            if (len < TRANS_DATA_LEN-1)
+    			u_strncat(keywords[i], token, TRANS_DATA_LEN - len - 1);
+		}
+
+		prevToken = token;
+	} while ((token = u_strtok_r(NULL, delim, &state)) != NULL); 
+
+	// Append the last word to initial
+	u_strncat(keywords[0], prevToken, TRANS_DATA_LEN - u_strlen(keywords[0]) - 1);
+
+	if (numTokens == 1) { // One word only
+		return 1;
+	} else {
+        return numTokens + 1;
+    }
+
+	//char b[1024];
+	//u_UCharsToChars(data, b, u_strlen(data));
+	//LOGD("MakeKeywords(): finaldata = %s", b);
+}
+
+/**
  * This function is invoked as:
  *
  *  _TOKENIZE('<token_table>', <data_row_id>, <data>, <delimiter>)
@@ -268,20 +399,21 @@ static void tokenize(sqlite3_context * context, int argc, sqlite3_value ** argv)
         return;
     }
  
-    UChar * token = NULL;
-    UChar *state;
-    int numTokens = 0;    
-    
-    do {
-        if (numTokens == 0) {
-            token = origData;
-        } 
+	//Transform Non-latin chars to latin chars
+	UChar latinData[TRANS_DATA_LEN];
+	TransToLatin(origData, latinData);
 
-        // Reset the program so we can use it to perform the insert
+	UChar keywords[WORDS_NUM+1][TRANS_DATA_LEN] = {{0}};
+	int numKeywords = MakeKeywords(latinData, delim, keywords);
+
+    //The origData should be indexed
+    u_strncpy(keywords[numKeywords], origData, TRANS_DATA_LEN-1);
+
+    for (int i=0; i<numKeywords+1; i++) {
         sqlite3_reset(statement);
         UErrorCode status = U_ZERO_ERROR;
         char keybuf[1024];
-        uint32_t result = ucol_getSortKey(collator, token, -1, (uint8_t*)keybuf, sizeof(keybuf)-1);
+        uint32_t result = ucol_getSortKey(collator, keywords[i], -1, (uint8_t*)keybuf, sizeof(keybuf)-1);
         if (result > sizeof(keybuf)) {
             // TODO allocate memory for this super big string
             LOGE("ucol_getSortKey needs bigger buffer %d", result);
@@ -306,13 +438,8 @@ static void tokenize(sqlite3_context * context, int argc, sqlite3_value ** argv)
             LOGE(" sqlite3_step error %d", err);
             break;
         }
-        numTokens++;
-        if (numTokens == 1) {
-            // first call
-            u_strtok_r(origData, delim, &state);
-        }
-    } while ((token = u_strtok_r(NULL, delim, &state)) != NULL);
-    sqlite3_result_int(context, numTokens);
+    }
+    sqlite3_result_int(context, numKeywords);
 }
 
 static void localized_collator_dtor(UCollator* collator)
