171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa/*
271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * Copyright (C) 2011 The Android Open Source Project
371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa *
471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License");
571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * you may not use this file except in compliance with the License.
671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * You may obtain a copy of the License at
771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa *
871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa *      http://www.apache.org/licenses/LICENSE-2.0
971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa *
1071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software
1171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS,
1271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * See the License for the specific language governing permissions and
1471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * limitations under the License.
1571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa */
1671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
1771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawapackage com.android.providers.contacts;
1871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
1971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawaimport android.text.TextUtils;
2071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawaimport android.util.Log;
2171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
2271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawaimport java.text.Collator;
2371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawaimport java.util.ArrayList;
2471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawaimport java.util.Locale;
2571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
2671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa/**
2771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * An object to convert Chinese character to its corresponding pinyin string. For characters with
2871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * multiple possible pinyin string, only one is selected according to collator. Polyphone is not
2971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * supported in this implementation. This class is implemented to achieve the best runtime
3071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * performance and minimum runtime resources with tolerable sacrifice of accuracy. This
3171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * implementation highly depends on zh_CN ICU collation data and must be always synchronized with
3271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * ICU.
3371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa *
3471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa * Currently this file is aligned to zh.txt in ICU 4.6
3571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa */
3671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawapublic class HanziToPinyin {
3771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private static final String TAG = "HanziToPinyin";
3871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
3971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    // Turn on this flag when we want to check internal data structure.
4071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private static final boolean DEBUG = false;
4171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
4271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    /**
4371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     * Unihans array. Each unihans is the first one within same pinyin. Use it to determine pinyin
4471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     * for all ~20k unihans.
4571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     */
4671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    public static final char[] UNIHANS = {
4771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5475', '\u54ce', '\u5b89', '\u80ae', '\u51f9',
4871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u516b', '\u6300', '\u6273', '\u90a6', '\u5305', '\u5351', '\u5954', '\u4f3b',
4971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5c44', '\u8fb9', '\u6807', '\u618b', '\u90a0', '\u69df', '\u7676', '\u5cec',
5071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5693', '\u5a47', '\u98e1', '\u4ed3', '\u64cd', '\u518a', '\u5d7e', '\u564c',
5171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u53c9', '\u9497', '\u8fbf', '\u4f25', '\u6284', '\u8f66', '\u62bb', '\u67fd',
5271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5403', '\u5145', '\u62bd', '\u51fa', '\u6b3b', '\u63e3', '\u5ddd', '\u75ae',
5371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5439', '\u6776', '\u9034', '\u75b5', '\u5306', '\u51d1', '\u7c97', '\u6c46',
5471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5d14', '\u90a8', '\u6413', '\u5491', '\u5927', '\u75b8', '\u5f53', '\u5200',
5571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u6dc2', '\u5f97', '\u6265', '\u706f', '\u6c10', '\u55f2', '\u7538', '\u5201',
5671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u7239', '\u4ec3', '\u4e1f', '\u4e1c', '\u5517', '\u561f', '\u5073', '\u5806',
5771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u9413', '\u591a', '\u5a40', '\u8bf6', '\u5940', '\u97a5', '\u800c', '\u53d1',
5871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5e06', '\u65b9', '\u98de', '\u5206', '\u4e30', '\u8985', '\u4ecf', '\u7d11',
5971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u4f15', '\u65ee', '\u8be5', '\u7518', '\u5188', '\u768b', '\u6208', '\u7d66',
6071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u6839', '\u5e9a', '\u5de5', '\u52fe', '\u4f30', '\u74dc', '\u7f6b', '\u5173',
6171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5149', '\u5f52', '\u886e', '\u5459', '\u54c8', '\u54b3', '\u9878', '\u82c0',
6271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u84bf', '\u8bc3', '\u9ed2', '\u62eb', '\u4ea8', '\u5677', '\u543d', '\u9f41',
6371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5322', '\u82b1', '\u6000', '\u72bf', '\u5ddf', '\u7070', '\u660f', '\u5419',
6471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u4e0c', '\u52a0', '\u620b', '\u6c5f', '\u827d', '\u9636', '\u5dfe', '\u52a4',
6571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5182', '\u52fc', '\u530a', '\u5a1f', '\u5658', '\u519b', '\u5494', '\u5f00',
6671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u520a', '\u95f6', '\u5c3b', '\u533c', '\u524b', '\u80af', '\u962c', '\u7a7a',
6771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u62a0', '\u5233', '\u5938', '\u84af', '\u5bbd', '\u5321', '\u4e8f', '\u5764',
6871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u6269', '\u5783', '\u6765', '\u5170', '\u5577', '\u635e', '\u4ec2', '\u52d2',
6971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5844', '\u5215', '\u5006', '\u5941', '\u826f', '\u64a9', '\u5217', '\u62ce',
7071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u3007', '\u6e9c', '\u9f99', '\u779c', '\u565c', '\u5a08', '\u7567', '\u62a1',
7171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u7f57', '\u5463', '\u5988', '\u973e', '\u5ada', '\u9099', '\u732b', '\u9ebc',
7271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u6c92', '\u95e8', '\u753f', '\u54aa', '\u7720', '\u55b5', '\u54a9', '\u6c11',
7371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u540d', '\u8c2c', '\u6478', '\u54de', '\u6bea', '\u62cf', '\u5b7b', '\u56e1',
7471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u56ca', '\u5b6c', '\u8bb7', '\u9981', '\u6041', '\u80fd', '\u59ae', '\u62c8',
7571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5b22', '\u9e1f', '\u634f', '\u60a8', '\u5b81', '\u599e', '\u519c', '\u7fba',
7671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5974', '\u597b', '\u8650', '\u632a', '\u5594', '\u8bb4', '\u8db4', '\u62cd',
7771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u7705', '\u4e53', '\u629b', '\u5478', '\u55b7', '\u5309', '\u4e15', '\u504f',
7871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u527d', '\u6c15', '\u59d8', '\u4e52', '\u948b', '\u5256', '\u4ec6', '\u4e03',
7971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u6390', '\u5343', '\u545b', '\u6084', '\u767f', '\u4fb5', '\u9751', '\u909b',
8071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u4e18', '\u66f2', '\u5f2e', '\u7f3a', '\u590b', '\u5465', '\u7a63', '\u5a06',
8171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u60f9', '\u4eba', '\u6254', '\u65e5', '\u8338', '\u53b9', '\u5982', '\u5827',
8271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u6875', '\u95f0', '\u82e5', '\u4ee8', '\u6be2', '\u4e09', '\u6852', '\u63bb',
8371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u8272', '\u68ee', '\u50e7', '\u6740', '\u7b5b', '\u5c71', '\u4f24', '\u5f30',
8471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5962', '\u7533', '\u5347', '\u5c38', '\u53ce', '\u4e66', '\u5237', '\u6454',
8571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u95e9', '\u53cc', '\u8c01', '\u542e', '\u5981', '\u53b6', '\u5fea', '\u635c',
8671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u82cf', '\u72fb', '\u590a', '\u5b59', '\u5506', '\u4ed6', '\u82d4', '\u574d',
8771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u94f4', '\u5932', '\u5fd1', '\u71a5', '\u5254', '\u5929', '\u4f7b', '\u5e16',
8871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5385', '\u56f2', '\u5077', '\u92c0', '\u6e4d', '\u63a8', '\u541e', '\u6258',
8971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u6316', '\u6b6a', '\u5f2f', '\u5c2a', '\u5371', '\u586d', '\u7fc1', '\u631d',
9071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5140', '\u5915', '\u867e', '\u4eda', '\u4e61', '\u7071', '\u4e9b', '\u5fc3',
9171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u661f', '\u51f6', '\u4f11', '\u65f4', '\u8f69', '\u75b6', '\u52cb', '\u4e2b',
9271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u6079', '\u592e', '\u5e7a', '\u8036', '\u4e00', '\u6b2d', '\u5e94', '\u54df',
9371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u4f63', '\u4f18', '\u625c', '\u9e22', '\u66f0', '\u6655', '\u531d', '\u707d',
9471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u7ccc', '\u7242', '\u50ae', '\u5219', '\u8d3c', '\u600e', '\u5897', '\u5412',
9571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u635a', '\u6cbe', '\u5f20', '\u948a', '\u8707', '\u8d1e', '\u4e89', '\u4e4b',
9671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u4e2d', '\u5dde', '\u6731', '\u6293', '\u8de9', '\u4e13', '\u5986', '\u96b9',
9771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5b92', '\u5353', '\u5b5c', '\u5b97', '\u90b9', '\u79df', '\u94bb', '\u539c',
9871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            '\u5c0a', '\u6628', };
9971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
10071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    /**
10171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     * Pinyin array. Each pinyin is corresponding to unihans of same offset in the unihans array.
10271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     */
10371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    public static final byte[][] PINYINS = {
10471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 65, 0, 0, 0, 0, 0 }, { 65, 73, 0, 0, 0, 0 }, { 65, 78, 0, 0, 0, 0 },
10571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 65, 78, 71, 0, 0, 0 }, { 65, 79, 0, 0, 0, 0 }, { 66, 65, 0, 0, 0, 0 },
10671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 66, 65, 73, 0, 0, 0 }, { 66, 65, 78, 0, 0, 0 }, { 66, 65, 78, 71, 0, 0 },
10771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 66, 65, 79, 0, 0, 0 }, { 66, 69, 73, 0, 0, 0 }, { 66, 69, 78, 0, 0, 0 },
10871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 66, 69, 78, 71, 0, 0 }, { 66, 73, 0, 0, 0, 0 }, { 66, 73, 65, 78, 0, 0 },
10971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 66, 73, 65, 79, 0, 0 }, { 66, 73, 69, 0, 0, 0 }, { 66, 73, 78, 0, 0, 0 },
11071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 66, 73, 78, 71, 0, 0 }, { 66, 79, 0, 0, 0, 0 }, { 66, 85, 0, 0, 0, 0 },
11171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 65, 0, 0, 0, 0 }, { 67, 65, 73, 0, 0, 0 },
11271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 65, 78, 0, 0, 0 }, { 67, 65, 78, 71, 0, 0 }, { 67, 65, 79, 0, 0, 0 },
11371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 69, 0, 0, 0, 0 }, { 67, 69, 78, 0, 0, 0 }, { 67, 69, 78, 71, 0, 0 },
11471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 72, 65, 0, 0, 0 }, { 67, 72, 65, 73, 0, 0 }, { 67, 72, 65, 78, 0, 0 },
11571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 72, 65, 78, 71, 0 }, { 67, 72, 65, 79, 0, 0 }, { 67, 72, 69, 0, 0, 0 },
11671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 72, 69, 78, 0, 0 }, { 67, 72, 69, 78, 71, 0 }, { 67, 72, 73, 0, 0, 0 },
11771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 72, 79, 78, 71, 0 }, { 67, 72, 79, 85, 0, 0 }, { 67, 72, 85, 0, 0, 0 },
11871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 72, 85, 65, 0, 0 }, { 67, 72, 85, 65, 73, 0 }, { 67, 72, 85, 65, 78, 0 },
11971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 72, 85, 65, 78, 71 }, { 67, 72, 85, 73, 0, 0 }, { 67, 72, 85, 78, 0, 0 },
12071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 72, 85, 79, 0, 0 }, { 67, 73, 0, 0, 0, 0 }, { 67, 79, 78, 71, 0, 0 },
12171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 79, 85, 0, 0, 0 }, { 67, 85, 0, 0, 0, 0 }, { 67, 85, 65, 78, 0, 0 },
12271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 67, 85, 73, 0, 0, 0 }, { 67, 85, 78, 0, 0, 0 }, { 67, 85, 79, 0, 0, 0 },
12371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 68, 65, 0, 0, 0, 0 }, { 68, 65, 73, 0, 0, 0 }, { 68, 65, 78, 0, 0, 0 },
12471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 68, 65, 78, 71, 0, 0 }, { 68, 65, 79, 0, 0, 0 }, { 68, 69, 0, 0, 0, 0 },
12571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 68, 69, 73, 0, 0, 0 }, { 68, 69, 78, 0, 0, 0 }, { 68, 69, 78, 71, 0, 0 },
12671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 68, 73, 0, 0, 0, 0 }, { 68, 73, 65, 0, 0, 0 }, { 68, 73, 65, 78, 0, 0 },
12771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 68, 73, 65, 79, 0, 0 }, { 68, 73, 69, 0, 0, 0 }, { 68, 73, 78, 71, 0, 0 },
12871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 68, 73, 85, 0, 0, 0 }, { 68, 79, 78, 71, 0, 0 }, { 68, 79, 85, 0, 0, 0 },
12971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 68, 85, 0, 0, 0, 0 }, { 68, 85, 65, 78, 0, 0 }, { 68, 85, 73, 0, 0, 0 },
13071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 68, 85, 78, 0, 0, 0 }, { 68, 85, 79, 0, 0, 0 }, { 69, 0, 0, 0, 0, 0 },
13171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 69, 73, 0, 0, 0, 0 }, { 69, 78, 0, 0, 0, 0 }, { 69, 78, 71, 0, 0, 0 },
13271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 69, 82, 0, 0, 0, 0 }, { 70, 65, 0, 0, 0, 0 }, { 70, 65, 78, 0, 0, 0 },
13371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 70, 65, 78, 71, 0, 0 }, { 70, 69, 73, 0, 0, 0 }, { 70, 69, 78, 0, 0, 0 },
13471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 70, 69, 78, 71, 0, 0 }, { 70, 73, 65, 79, 0, 0 }, { 70, 79, 0, 0, 0, 0 },
13571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 70, 79, 85, 0, 0, 0 }, { 70, 85, 0, 0, 0, 0 }, { 71, 65, 0, 0, 0, 0 },
13671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 71, 65, 73, 0, 0, 0 }, { 71, 65, 78, 0, 0, 0 }, { 71, 65, 78, 71, 0, 0 },
13771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 71, 65, 79, 0, 0, 0 }, { 71, 69, 0, 0, 0, 0 }, { 71, 69, 73, 0, 0, 0 },
13871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 71, 69, 78, 0, 0, 0 }, { 71, 69, 78, 71, 0, 0 }, { 71, 79, 78, 71, 0, 0 },
13971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 71, 79, 85, 0, 0, 0 }, { 71, 85, 0, 0, 0, 0 }, { 71, 85, 65, 0, 0, 0 },
14071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 71, 85, 65, 73, 0, 0 }, { 71, 85, 65, 78, 0, 0 }, { 71, 85, 65, 78, 71, 0 },
14171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 71, 85, 73, 0, 0, 0 }, { 71, 85, 78, 0, 0, 0 }, { 71, 85, 79, 0, 0, 0 },
14271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 72, 65, 0, 0, 0, 0 }, { 72, 65, 73, 0, 0, 0 }, { 72, 65, 78, 0, 0, 0 },
14371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 72, 65, 78, 71, 0, 0 }, { 72, 65, 79, 0, 0, 0 }, { 72, 69, 0, 0, 0, 0 },
14471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 72, 69, 73, 0, 0, 0 }, { 72, 69, 78, 0, 0, 0 }, { 72, 69, 78, 71, 0, 0 },
14571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 72, 77, 0, 0, 0, 0 }, { 72, 79, 78, 71, 0, 0 }, { 72, 79, 85, 0, 0, 0 },
14671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 72, 85, 0, 0, 0, 0 }, { 72, 85, 65, 0, 0, 0 }, { 72, 85, 65, 73, 0, 0 },
14771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 72, 85, 65, 78, 0, 0 }, { 72, 85, 65, 78, 71, 0 }, { 72, 85, 73, 0, 0, 0 },
14871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 72, 85, 78, 0, 0, 0 }, { 72, 85, 79, 0, 0, 0 }, { 74, 73, 0, 0, 0, 0 },
14971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 74, 73, 65, 0, 0, 0 }, { 74, 73, 65, 78, 0, 0 }, { 74, 73, 65, 78, 71, 0 },
15071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 74, 73, 65, 79, 0, 0 }, { 74, 73, 69, 0, 0, 0 }, { 74, 73, 78, 0, 0, 0 },
15171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 74, 73, 78, 71, 0, 0 }, { 74, 73, 79, 78, 71, 0 }, { 74, 73, 85, 0, 0, 0 },
15271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 74, 85, 0, 0, 0, 0 }, { 74, 85, 65, 78, 0, 0 }, { 74, 85, 69, 0, 0, 0 },
15371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 74, 85, 78, 0, 0, 0 }, { 75, 65, 0, 0, 0, 0 }, { 75, 65, 73, 0, 0, 0 },
15471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 75, 65, 78, 0, 0, 0 }, { 75, 65, 78, 71, 0, 0 }, { 75, 65, 79, 0, 0, 0 },
15571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 75, 69, 0, 0, 0, 0 }, { 75, 69, 73, 0, 0, 0 }, { 75, 69, 78, 0, 0, 0 },
15671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 75, 69, 78, 71, 0, 0 }, { 75, 79, 78, 71, 0, 0 }, { 75, 79, 85, 0, 0, 0 },
15771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 75, 85, 0, 0, 0, 0 }, { 75, 85, 65, 0, 0, 0 }, { 75, 85, 65, 73, 0, 0 },
15871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 75, 85, 65, 78, 0, 0 }, { 75, 85, 65, 78, 71, 0 }, { 75, 85, 73, 0, 0, 0 },
15971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 75, 85, 78, 0, 0, 0 }, { 75, 85, 79, 0, 0, 0 }, { 76, 65, 0, 0, 0, 0 },
16071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 76, 65, 73, 0, 0, 0 }, { 76, 65, 78, 0, 0, 0 }, { 76, 65, 78, 71, 0, 0 },
16171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 76, 65, 79, 0, 0, 0 }, { 76, 69, 0, 0, 0, 0 }, { 76, 69, 73, 0, 0, 0 },
16271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 76, 69, 78, 71, 0, 0 }, { 76, 73, 0, 0, 0, 0 }, { 76, 73, 65, 0, 0, 0 },
16371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 76, 73, 65, 78, 0, 0 }, { 76, 73, 65, 78, 71, 0 }, { 76, 73, 65, 79, 0, 0 },
16471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 76, 73, 69, 0, 0, 0 }, { 76, 73, 78, 0, 0, 0 }, { 76, 73, 78, 71, 0, 0 },
16571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 76, 73, 85, 0, 0, 0 }, { 76, 79, 78, 71, 0, 0 }, { 76, 79, 85, 0, 0, 0 },
16671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 76, 85, 0, 0, 0, 0 }, { 76, 85, 65, 78, 0, 0 }, { 76, 85, 69, 0, 0, 0 },
16771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 76, 85, 78, 0, 0, 0 }, { 76, 85, 79, 0, 0, 0 }, { 77, 0, 0, 0, 0, 0 },
16871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 77, 65, 0, 0, 0, 0 }, { 77, 65, 73, 0, 0, 0 }, { 77, 65, 78, 0, 0, 0 },
16971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 77, 65, 78, 71, 0, 0 }, { 77, 65, 79, 0, 0, 0 }, { 77, 69, 0, 0, 0, 0 },
17071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 77, 69, 73, 0, 0, 0 }, { 77, 69, 78, 0, 0, 0 }, { 77, 69, 78, 71, 0, 0 },
17171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 77, 73, 0, 0, 0, 0 }, { 77, 73, 65, 78, 0, 0 }, { 77, 73, 65, 79, 0, 0 },
17271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 77, 73, 69, 0, 0, 0 }, { 77, 73, 78, 0, 0, 0 }, { 77, 73, 78, 71, 0, 0 },
17371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 77, 73, 85, 0, 0, 0 }, { 77, 79, 0, 0, 0, 0 }, { 77, 79, 85, 0, 0, 0 },
17471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 77, 85, 0, 0, 0, 0 }, { 78, 65, 0, 0, 0, 0 }, { 78, 65, 73, 0, 0, 0 },
17571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 78, 65, 78, 0, 0, 0 }, { 78, 65, 78, 71, 0, 0 }, { 78, 65, 79, 0, 0, 0 },
17671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 78, 69, 0, 0, 0, 0 }, { 78, 69, 73, 0, 0, 0 }, { 78, 69, 78, 0, 0, 0 },
17771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 78, 69, 78, 71, 0, 0 }, { 78, 73, 0, 0, 0, 0 }, { 78, 73, 65, 78, 0, 0 },
17871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 78, 73, 65, 78, 71, 0 }, { 78, 73, 65, 79, 0, 0 }, { 78, 73, 69, 0, 0, 0 },
17971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 78, 73, 78, 0, 0, 0 }, { 78, 73, 78, 71, 0, 0 }, { 78, 73, 85, 0, 0, 0 },
18071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 78, 79, 78, 71, 0, 0 }, { 78, 79, 85, 0, 0, 0 }, { 78, 85, 0, 0, 0, 0 },
18171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 78, 85, 65, 78, 0, 0 }, { 78, 85, 69, 0, 0, 0 }, { 78, 85, 79, 0, 0, 0 },
18271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 79, 0, 0, 0, 0, 0 }, { 79, 85, 0, 0, 0, 0 }, { 80, 65, 0, 0, 0, 0 },
18371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 80, 65, 73, 0, 0, 0 }, { 80, 65, 78, 0, 0, 0 }, { 80, 65, 78, 71, 0, 0 },
18471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 80, 65, 79, 0, 0, 0 }, { 80, 69, 73, 0, 0, 0 }, { 80, 69, 78, 0, 0, 0 },
18571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 80, 69, 78, 71, 0, 0 }, { 80, 73, 0, 0, 0, 0 }, { 80, 73, 65, 78, 0, 0 },
18671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 80, 73, 65, 79, 0, 0 }, { 80, 73, 69, 0, 0, 0 }, { 80, 73, 78, 0, 0, 0 },
18771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 80, 73, 78, 71, 0, 0 }, { 80, 79, 0, 0, 0, 0 }, { 80, 79, 85, 0, 0, 0 },
18871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 80, 85, 0, 0, 0, 0 }, { 81, 73, 0, 0, 0, 0 }, { 81, 73, 65, 0, 0, 0 },
18971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 81, 73, 65, 78, 0, 0 }, { 81, 73, 65, 78, 71, 0 }, { 81, 73, 65, 79, 0, 0 },
19071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 81, 73, 69, 0, 0, 0 }, { 81, 73, 78, 0, 0, 0 }, { 81, 73, 78, 71, 0, 0 },
19171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 81, 73, 79, 78, 71, 0 }, { 81, 73, 85, 0, 0, 0 }, { 81, 85, 0, 0, 0, 0 },
19271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 81, 85, 65, 78, 0, 0 }, { 81, 85, 69, 0, 0, 0 }, { 81, 85, 78, 0, 0, 0 },
19371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 82, 65, 78, 0, 0, 0 }, { 82, 65, 78, 71, 0, 0 }, { 82, 65, 79, 0, 0, 0 },
19471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 82, 69, 0, 0, 0, 0 }, { 82, 69, 78, 0, 0, 0 }, { 82, 69, 78, 71, 0, 0 },
19571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 82, 73, 0, 0, 0, 0 }, { 82, 79, 78, 71, 0, 0 }, { 82, 79, 85, 0, 0, 0 },
19671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 82, 85, 0, 0, 0, 0 }, { 82, 85, 65, 78, 0, 0 }, { 82, 85, 73, 0, 0, 0 },
19771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 82, 85, 78, 0, 0, 0 }, { 82, 85, 79, 0, 0, 0 }, { 83, 65, 0, 0, 0, 0 },
19871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 65, 73, 0, 0, 0 }, { 83, 65, 78, 0, 0, 0 }, { 83, 65, 78, 71, 0, 0 },
19971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 65, 79, 0, 0, 0 }, { 83, 69, 0, 0, 0, 0 }, { 83, 69, 78, 0, 0, 0 },
20071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 69, 78, 71, 0, 0 }, { 83, 72, 65, 0, 0, 0 }, { 83, 72, 65, 73, 0, 0 },
20171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 72, 65, 78, 0, 0 }, { 83, 72, 65, 78, 71, 0 }, { 83, 72, 65, 79, 0, 0 },
20271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 72, 69, 0, 0, 0 }, { 83, 72, 69, 78, 0, 0 }, { 83, 72, 69, 78, 71, 0 },
20371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 72, 73, 0, 0, 0 }, { 83, 72, 79, 85, 0, 0 }, { 83, 72, 85, 0, 0, 0 },
20471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 72, 85, 65, 0, 0 }, { 83, 72, 85, 65, 73, 0 }, { 83, 72, 85, 65, 78, 0 },
20571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 72, 85, 65, 78, 71 }, { 83, 72, 85, 73, 0, 0 }, { 83, 72, 85, 78, 0, 0 },
20671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 72, 85, 79, 0, 0 }, { 83, 73, 0, 0, 0, 0 }, { 83, 79, 78, 71, 0, 0 },
20771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 79, 85, 0, 0, 0 }, { 83, 85, 0, 0, 0, 0 }, { 83, 85, 65, 78, 0, 0 },
20871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 83, 85, 73, 0, 0, 0 }, { 83, 85, 78, 0, 0, 0 }, { 83, 85, 79, 0, 0, 0 },
20971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 84, 65, 0, 0, 0, 0 }, { 84, 65, 73, 0, 0, 0 }, { 84, 65, 78, 0, 0, 0 },
21071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 84, 65, 78, 71, 0, 0 }, { 84, 65, 79, 0, 0, 0 }, { 84, 69, 0, 0, 0, 0 },
21171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 84, 69, 78, 71, 0, 0 }, { 84, 73, 0, 0, 0, 0 }, { 84, 73, 65, 78, 0, 0 },
21271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 84, 73, 65, 79, 0, 0 }, { 84, 73, 69, 0, 0, 0 }, { 84, 73, 78, 71, 0, 0 },
21371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 84, 79, 78, 71, 0, 0 }, { 84, 79, 85, 0, 0, 0 }, { 84, 85, 0, 0, 0, 0 },
21471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 84, 85, 65, 78, 0, 0 }, { 84, 85, 73, 0, 0, 0 }, { 84, 85, 78, 0, 0, 0 },
21571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 84, 85, 79, 0, 0, 0 }, { 87, 65, 0, 0, 0, 0 }, { 87, 65, 73, 0, 0, 0 },
21671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 87, 65, 78, 0, 0, 0 }, { 87, 65, 78, 71, 0, 0 }, { 87, 69, 73, 0, 0, 0 },
21771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 87, 69, 78, 0, 0, 0 }, { 87, 69, 78, 71, 0, 0 }, { 87, 79, 0, 0, 0, 0 },
21871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 87, 85, 0, 0, 0, 0 }, { 88, 73, 0, 0, 0, 0 }, { 88, 73, 65, 0, 0, 0 },
21971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 88, 73, 65, 78, 0, 0 }, { 88, 73, 65, 78, 71, 0 }, { 88, 73, 65, 79, 0, 0 },
22071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 88, 73, 69, 0, 0, 0 }, { 88, 73, 78, 0, 0, 0 }, { 88, 73, 78, 71, 0, 0 },
22171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 88, 73, 79, 78, 71, 0 }, { 88, 73, 85, 0, 0, 0 }, { 88, 85, 0, 0, 0, 0 },
22271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 88, 85, 65, 78, 0, 0 }, { 88, 85, 69, 0, 0, 0 }, { 88, 85, 78, 0, 0, 0 },
22371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 89, 65, 0, 0, 0, 0 }, { 89, 65, 78, 0, 0, 0 }, { 89, 65, 78, 71, 0, 0 },
22471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 89, 65, 79, 0, 0, 0 }, { 89, 69, 0, 0, 0, 0 }, { 89, 73, 0, 0, 0, 0 },
22571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 89, 73, 78, 0, 0, 0 }, { 89, 73, 78, 71, 0, 0 }, { 89, 79, 0, 0, 0, 0 },
22671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 89, 79, 78, 71, 0, 0 }, { 89, 79, 85, 0, 0, 0 }, { 89, 85, 0, 0, 0, 0 },
22771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 89, 85, 65, 78, 0, 0 }, { 89, 85, 69, 0, 0, 0 }, { 89, 85, 78, 0, 0, 0 },
22871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 65, 0, 0, 0, 0 }, { 90, 65, 73, 0, 0, 0 }, { 90, 65, 78, 0, 0, 0 },
22971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 65, 78, 71, 0, 0 }, { 90, 65, 79, 0, 0, 0 }, { 90, 69, 0, 0, 0, 0 },
23071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 69, 73, 0, 0, 0 }, { 90, 69, 78, 0, 0, 0 }, { 90, 69, 78, 71, 0, 0 },
23171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 72, 65, 0, 0, 0 }, { 90, 72, 65, 73, 0, 0 }, { 90, 72, 65, 78, 0, 0 },
23271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 72, 65, 78, 71, 0 }, { 90, 72, 65, 79, 0, 0 }, { 90, 72, 69, 0, 0, 0 },
23371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 72, 69, 78, 0, 0 }, { 90, 72, 69, 78, 71, 0 }, { 90, 72, 73, 0, 0, 0 },
23471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 72, 79, 78, 71, 0 }, { 90, 72, 79, 85, 0, 0 }, { 90, 72, 85, 0, 0, 0 },
23571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 72, 85, 65, 0, 0 }, { 90, 72, 85, 65, 73, 0 }, { 90, 72, 85, 65, 78, 0 },
23671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 72, 85, 65, 78, 71 }, { 90, 72, 85, 73, 0, 0 }, { 90, 72, 85, 78, 0, 0 },
23771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 72, 85, 79, 0, 0 }, { 90, 73, 0, 0, 0, 0 }, { 90, 79, 78, 71, 0, 0 },
23871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 79, 85, 0, 0, 0 }, { 90, 85, 0, 0, 0, 0 }, { 90, 85, 65, 78, 0, 0 },
23971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            { 90, 85, 73, 0, 0, 0 }, { 90, 85, 78, 0, 0, 0 }, { 90, 85, 79, 0, 0, 0 }, };
24071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
24171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    /** First and last Chinese character with known Pinyin according to zh collation */
24271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private static final String FIRST_PINYIN_UNIHAN = "\u963F";
24371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private static final String LAST_PINYIN_UNIHAN = "\u84D9";
24471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    /** The first Chinese character in Unicode block */
24571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private static final char FIRST_UNIHAN = '\u3400';
24671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private static final Collator COLLATOR = Collator.getInstance(Locale.CHINA);
24771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
24871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private static HanziToPinyin sInstance;
24971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private final boolean mHasChinaCollator;
25071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
25171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    public static class Token {
25271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        /**
25371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         * Separator between target string for each source char
25471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         */
25571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public static final String SEPARATOR = " ";
25671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
25771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public static final int LATIN = 1;
25871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public static final int PINYIN = 2;
25971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public static final int UNKNOWN = 3;
26071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
26171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public Token() {
26271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
26371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
26471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public Token(int type, String source, String target) {
26571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            this.type = type;
26671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            this.source = source;
26771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            this.target = target;
26871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
26971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
27071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        /**
27171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         * Type of this token, ASCII, PINYIN or UNKNOWN.
27271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         */
27371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public int type;
27471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        /**
27571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         * Original string before translation.
27671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         */
27771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public String source;
27871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        /**
27971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         * Translated string of source. For Han, target is corresponding Pinyin. Otherwise target is
28071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         * original string in source.
28171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa         */
28271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        public String target;
28371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    }
28471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
28571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    protected HanziToPinyin(boolean hasChinaCollator) {
28671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        mHasChinaCollator = hasChinaCollator;
28771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    }
28871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
28971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    public static HanziToPinyin getInstance() {
29071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        synchronized (HanziToPinyin.class) {
29171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            if (sInstance != null) {
29271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                return sInstance;
29371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            }
29471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            // Check if zh_CN collation data is available
29571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            final Locale locale[] = Collator.getAvailableLocales();
29671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            for (int i = 0; i < locale.length; i++) {
29771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                if (locale[i].equals(Locale.CHINA)) {
29871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    // Do self validation just once.
29971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    if (DEBUG) {
30071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                        Log.d(TAG, "Self validation. Result: " + doSelfValidation());
30171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    }
30271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    sInstance = new HanziToPinyin(true);
30371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    return sInstance;
30471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                }
30571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            }
30671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled");
30771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            sInstance = new HanziToPinyin(false);
30871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            return sInstance;
30971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
31071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    }
31171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
31271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    /**
31371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     * Validate if our internal table has some wrong value.
31471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     *
31571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     * @return true when the table looks correct.
31671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     */
31771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private static boolean doSelfValidation() {
31871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        char lastChar = UNIHANS[0];
31971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        String lastString = Character.toString(lastChar);
32071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        for (char c : UNIHANS) {
32171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            if (lastChar == c) {
32271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                continue;
32371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            }
32471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            final String curString = Character.toString(c);
32571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            int cmp = COLLATOR.compare(lastString, curString);
32671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            if (cmp >= 0) {
32771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                Log.e(TAG, "Internal error in Unihan table. " + "The last string \"" + lastString
32871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                        + "\" is greater than current string \"" + curString + "\".");
32971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                return false;
33071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            }
33171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            lastString = curString;
33271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
33371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        return true;
33471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    }
33571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
33671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private Token getToken(char character) {
33771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        Token token = new Token();
33871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        final String letter = Character.toString(character);
33971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        token.source = letter;
34071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        int offset = -1;
34171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        int cmp;
34271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        if (character < 256) {
34371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            token.type = Token.LATIN;
34471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            token.target = letter;
34571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            return token;
34671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        } else if (character < FIRST_UNIHAN) {
34771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            token.type = Token.UNKNOWN;
34871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            token.target = letter;
34971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            return token;
35071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        } else {
35171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            cmp = COLLATOR.compare(letter, FIRST_PINYIN_UNIHAN);
35271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            if (cmp < 0) {
35371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                token.type = Token.UNKNOWN;
35471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                token.target = letter;
35571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                return token;
35671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            } else if (cmp == 0) {
35771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                token.type = Token.PINYIN;
35871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                offset = 0;
35971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            } else {
36071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                cmp = COLLATOR.compare(letter, LAST_PINYIN_UNIHAN);
36171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                if (cmp > 0) {
36271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    token.type = Token.UNKNOWN;
36371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    token.target = letter;
36471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    return token;
36571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                } else if (cmp == 0) {
36671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    token.type = Token.PINYIN;
36771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    offset = UNIHANS.length - 1;
36871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                }
36971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            }
37071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
37171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
37271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        token.type = Token.PINYIN;
37371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        if (offset < 0) {
37471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            int begin = 0;
37571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            int end = UNIHANS.length - 1;
37671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            while (begin <= end) {
37771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                offset = (begin + end) / 2;
37871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                final String unihan = Character.toString(UNIHANS[offset]);
37971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                cmp = COLLATOR.compare(letter, unihan);
38071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                if (cmp == 0) {
38171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    break;
38271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                } else if (cmp > 0) {
38371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    begin = offset + 1;
38471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                } else {
38571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    end = offset - 1;
38671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                }
38771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            }
38871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
38971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        if (cmp < 0) {
39071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            offset--;
39171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
39271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        StringBuilder pinyin = new StringBuilder();
39371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        for (int j = 0; j < PINYINS[offset].length && PINYINS[offset][j] != 0; j++) {
39471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            pinyin.append((char) PINYINS[offset][j]);
39571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
39671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        token.target = pinyin.toString();
39771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        return token;
39871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    }
39971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
40071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    /**
40171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     * Convert the input to a array of tokens. The sequence of ASCII or Unknown characters without
40271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     * space will be put into a Token, One Hanzi character which has pinyin will be treated as a
40371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     * Token. If these is no China collator, the empty token array is returned.
40471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa     */
40571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    public ArrayList<Token> get(final String input) {
40671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        ArrayList<Token> tokens = new ArrayList<Token>();
40771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        if (!mHasChinaCollator || TextUtils.isEmpty(input)) {
40871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            // return empty tokens.
40971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            return tokens;
41071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
41171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        final int inputLength = input.length();
41271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        final StringBuilder sb = new StringBuilder();
41371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        int tokenType = Token.LATIN;
41471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        // Go through the input, create a new token when
41571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        // a. Token type changed
41671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        // b. Get the Pinyin of current charater.
41771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        // c. current character is space.
41871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        for (int i = 0; i < inputLength; i++) {
41971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            final char character = input.charAt(i);
42071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            if (character == ' ') {
42171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                if (sb.length() > 0) {
42271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    addToken(sb, tokens, tokenType);
42371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                }
42471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            } else if (character < 256) {
42571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                if (tokenType != Token.LATIN && sb.length() > 0) {
42671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    addToken(sb, tokens, tokenType);
42771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                }
42871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                tokenType = Token.LATIN;
42971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                sb.append(character);
43071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            } else if (character < FIRST_UNIHAN) {
43171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                if (tokenType != Token.UNKNOWN && sb.length() > 0) {
43271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    addToken(sb, tokens, tokenType);
43371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                }
43471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                tokenType = Token.UNKNOWN;
43571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                sb.append(character);
43671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            } else {
43771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                Token t = getToken(character);
43871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                if (t.type == Token.PINYIN) {
43971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    if (sb.length() > 0) {
44071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                        addToken(sb, tokens, tokenType);
44171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    }
44271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    tokens.add(t);
44371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    tokenType = Token.PINYIN;
44471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                } else {
44571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    if (tokenType != t.type && sb.length() > 0) {
44671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                        addToken(sb, tokens, tokenType);
44771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    }
44871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    tokenType = t.type;
44971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                    sb.append(character);
45071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa                }
45171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            }
45271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
45371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        if (sb.length() > 0) {
45471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            addToken(sb, tokens, tokenType);
45571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        }
45671340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        return tokens;
45771340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    }
45871340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa
45971340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    private void addToken(
46071340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa            final StringBuilder sb, final ArrayList<Token> tokens, final int tokenType) {
46171340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        String str = sb.toString();
46271340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        tokens.add(new Token(tokenType, str, str));
46371340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa        sb.setLength(0);
46471340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa    }
46571340347b4862d4b1368a5d69d1667e2245952e4Daisuke Miyakawa}
466