001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020
021package org.apache.directory.api.ldap.model.schema;
022
023
024import java.io.IOException;
025
026import org.apache.directory.api.util.Strings;
027import org.apache.directory.api.util.exception.InvalidCharacterException;
028
029
030/**
031 * 
032 * This class implements the 6 steps described in RFC 4518
033 *
034 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
035 */
036public final class PrepareString
037{
038    /** A flag used to lowercase chars during the map process */
039    private static final boolean CASE_SENSITIVE = true;
040
041    /** A flag used to keep casing during the map process */
042    private static final boolean IGNORE_CASE = false;
043
044    /** All the possible combining marks */
045    private static final char[][] COMBINING_MARKS = new char[][]
046        {
047            { 0x0300, 0x034F },
048            { 0x0360, 0x036F },
049            { 0x0483, 0x0486 },
050            { 0x0488, 0x0489 },
051            { 0x0591, 0x05A1 },
052            { 0x05A3, 0x05B9 },
053            { 0x05BB, 0x05BC },
054            { 0x05BF, 0x05BF },
055            { 0x05C1, 0x05C2 },
056            { 0x05C4, 0x05C4 },
057            { 0x064B, 0x0655 },
058            { 0x0670, 0x0670 },
059            { 0x06D6, 0x06DC },
060            { 0x06DE, 0x06E4 },
061            { 0x06E7, 0x06E8 },
062            { 0x06EA, 0x06ED },
063            { 0x0711, 0x0711 },
064            { 0x0730, 0x074A },
065            { 0x07A6, 0x07B0 },
066            { 0x0901, 0x0903 },
067            { 0x093C, 0x093C },
068            { 0x093E, 0x094F },
069            { 0x0951, 0x0954 },
070            { 0x0962, 0x0963 },
071            { 0x0981, 0x0983 },
072            { 0x09BC, 0x09BC },
073            { 0x09BE, 0x09C4 },
074            { 0x09C7, 0x09C8 },
075            { 0x09CB, 0x09CD },
076            { 0x09D7, 0x09D7 },
077            { 0x09E2, 0x09E3 },
078            { 0x0A02, 0x0A02 },
079            { 0x0A3C, 0x0A3C },
080            { 0x0A3E, 0x0A42 },
081            { 0x0A47, 0x0A48 },
082            { 0x0A4B, 0x0A4D },
083            { 0x0A70, 0x0A71 },
084            { 0x0A81, 0x0A83 },
085            { 0x0ABC, 0x0ABC },
086            { 0x0ABE, 0x0AC5 },
087            { 0x0AC7, 0x0AC9 },
088            { 0x0ACB, 0x0ACD },
089            { 0x0B01, 0x0B03 },
090            { 0x0B3C, 0x0B3C },
091            { 0x0B3E, 0x0B43 },
092            { 0x0B47, 0x0B48 },
093            { 0x0B4B, 0x0B4D },
094            { 0x0B56, 0x0B57 },
095            { 0x0B82, 0x0B82 },
096            { 0x0BBE, 0x0BC2 },
097            { 0x0BC6, 0x0BC8 },
098            { 0x0BCA, 0x0BCD },
099            { 0x0BD7, 0x0BD7 },
100            { 0x0C01, 0x0C03 },
101            { 0x0C3E, 0x0C44 },
102            { 0x0C46, 0x0C48 },
103            { 0x0C4A, 0x0C4D },
104            { 0x0C55, 0x0C56 },
105            { 0x0C82, 0x0C83 },
106            { 0x0CBE, 0x0CC4 },
107            { 0x0CC6, 0x0CC8 },
108            { 0x0CCA, 0x0CCD },
109            { 0x0CD5, 0x0CD6 },
110            { 0x0D02, 0x0D03 },
111            { 0x0D3E, 0x0D43 },
112            { 0x0D46, 0x0D48 },
113            { 0x0D4A, 0x0D4D },
114            { 0x0D57, 0x0D57 },
115            { 0x0D82, 0x0D83 },
116            { 0x0DCA, 0x0DCA },
117            { 0x0DCF, 0x0DD4 },
118            { 0x0DD6, 0x0DD6 },
119            { 0x0DD8, 0x0DDF },
120            { 0x0DF2, 0x0DF3 },
121            { 0x0E31, 0x0E31 },
122            { 0x0E34, 0x0E3A },
123            { 0x0E47, 0x0E4E },
124            { 0x0EB1, 0x0EB1 },
125            { 0x0EB4, 0x0EB9 },
126            { 0x0EBB, 0x0EBC },
127            { 0x0EC8, 0x0ECD },
128            { 0x0F18, 0x0F19 },
129            { 0x0F35, 0x0F35 },
130            { 0x0F37, 0x0F37 },
131            { 0x0F39, 0x0F39 },
132            { 0x0F3E, 0x0F3F },
133            { 0x0F71, 0x0F84 },
134            { 0x0F86, 0x0F87 },
135            { 0x0F90, 0x0F97 },
136            { 0x0F99, 0x0FBC },
137            { 0x0FC6, 0x0FC6 },
138            { 0x102C, 0x1032 },
139            { 0x1036, 0x1039 },
140            { 0x1056, 0x1059 },
141            { 0x1712, 0x1714 },
142            { 0x1732, 0x1734 },
143            { 0x1752, 0x1753 },
144            { 0x1772, 0x1773 },
145            { 0x17B4, 0x17D3 },
146            { 0x180B, 0x180D },
147            { 0x18A9, 0x18A9 },
148            { 0x20D0, 0x20EA },
149            { 0x302A, 0x302F },
150            { 0x3099, 0x309A },
151            { 0xFB1E, 0xFB1E },
152            { 0xFE00, 0xFE0F },
153            { 0xFE20, 0xFE23 }
154    };
155
156    /**
157     * The type of String we have to normalize
158     */
159    public enum StringType
160    {
161        NOT_STRING,
162        NUMERIC_STRING,
163        CASE_EXACT,
164        CASE_EXACT_IA5,
165        CASE_IGNORE_IA5,
166        CASE_IGNORE_LIST,
167        CASE_IGNORE,
168        DIRECTORY_STRING,
169        TELEPHONE_NUMBER,
170        WORD
171    }
172
173
174    /**
175     * A private constructor, to avoid instance creation of this static class.
176     */
177    private PrepareString()
178    {
179        // Do nothing
180    }
181
182
183    /**
184     * Tells if a char is a combining mark.
185     *
186     * @param c The char to check
187     * @return true if the char is a combining mark, false otherwise
188     */
189    private static boolean isCombiningMark( char c )
190    {
191        if ( c < COMBINING_MARKS[0][0] )
192        {
193            return false;
194        }
195
196        for ( char[] interval : COMBINING_MARKS )
197        {
198            if ( ( c >= interval[0] ) && ( c <= interval[1] ) )
199            {
200                return true;
201            }
202        }
203
204        return false;
205    }
206
207
208    /**
209    *
210    * We have to go through 6 steps :
211    *
212    * 1) Transcode
213    * 2) Map
214    * 3) Normalize
215    * 4) Prohibit
216    * 5) Bidi
217    * 6) Insignifiant Character Handling
218    *
219    * The first step is already done, the step (3) is not done.
220    *
221    * @param str The String to normalize
222    * @param type The string type
223    * @return A normalized string.
224    * @throws IOException
225    */
226    public static String normalize( String str, StringType type ) throws IOException
227    {
228        switch ( type )
229        {
230            case NUMERIC_STRING:
231                return insignifiantCharNumericString( str );
232
233            case TELEPHONE_NUMBER:
234                return insignifiantCharTelephoneNumber( str );
235
236            case CASE_EXACT:
237            case CASE_EXACT_IA5:
238            case DIRECTORY_STRING:
239                try
240                {
241                    return insignifiantSpacesStringAscii( str, CASE_SENSITIVE );
242                }
243                catch ( Exception e )
244                {
245                    return insignifiantSpacesString( str, CASE_SENSITIVE );
246                }
247
248            case CASE_IGNORE_IA5:
249            case CASE_IGNORE_LIST:
250            case CASE_IGNORE:
251                try
252                {
253                    return insignifiantSpacesStringAscii( str, IGNORE_CASE );
254                }
255                catch ( Exception e )
256                {
257                    return insignifiantSpacesString( str, IGNORE_CASE );
258                }
259
260            case WORD:
261                return str;
262
263            default:
264                return str;
265
266        }
267    }
268
269
270    /**
271     * Execute the mapping step of the string preparation :
272     * - suppress useless chars
273     * - transform to spaces
274     * - lowercase
275     * 
276     * @param c The char to map
277     * @param array The array which will collect the transformed char
278     * @param pos The current position in the target
279     * @param lowerCase A mask to lowercase the char, if necessary
280     * @return The transformed StringBuilder
281     */
282    // CHECKSTYLE:OFF
283    private static int map( char c, char[] target, int pos, char lowerCase )
284    {
285        int start = pos;
286
287        switch ( c )
288        {
289            case 0x0000:
290            case 0x0001:
291            case 0x0002:
292            case 0x0003:
293            case 0x0004:
294            case 0x0005:
295            case 0x0006:
296            case 0x0007:
297            case 0x0008:
298                break;
299
300            case 0x0009:
301            case 0x000A:
302            case 0x000B:
303            case 0x000C:
304            case 0x000D:
305                target[pos++] = ( char ) 0x20;
306                break;
307
308            case 0x000E:
309            case 0x000F:
310            case 0x0010:
311            case 0x0011:
312            case 0x0012:
313            case 0x0013:
314            case 0x0014:
315            case 0x0015:
316            case 0x0016:
317            case 0x0017:
318            case 0x0018:
319            case 0x0019:
320            case 0x001A:
321            case 0x001B:
322            case 0x001C:
323            case 0x001D:
324            case 0x001E:
325            case 0x001F:
326                break;
327
328            case 0x0041:
329            case 0x0042:
330            case 0x0043:
331            case 0x0044:
332            case 0x0045:
333            case 0x0046:
334            case 0x0047:
335            case 0x0048:
336            case 0x0049:
337            case 0x004A:
338            case 0x004B:
339            case 0x004C:
340            case 0x004D:
341            case 0x004E:
342            case 0x004F:
343            case 0x0050:
344            case 0x0051:
345            case 0x0052:
346            case 0x0053:
347            case 0x0054:
348            case 0x0055:
349            case 0x0056:
350            case 0x0057:
351            case 0x0058:
352            case 0x0059:
353            case 0x005A:
354                target[pos++] = ( char ) ( c | lowerCase );
355                break;
356
357            case 0x007F:
358            case 0x0080:
359            case 0x0081:
360            case 0x0082:
361            case 0x0083:
362            case 0x0084:
363                break;
364
365            case 0x0085:
366                target[pos++] = ( char ) 0x20;
367                break;
368
369            case 0x0086:
370            case 0x0087:
371            case 0x0088:
372            case 0x0089:
373            case 0x008A:
374            case 0x008B:
375            case 0x008C:
376            case 0x008D:
377            case 0x008E:
378            case 0x008F:
379            case 0x0090:
380            case 0x0091:
381            case 0x0092:
382            case 0x0093:
383            case 0x0094:
384            case 0x0095:
385            case 0x0096:
386            case 0x0097:
387            case 0x0098:
388            case 0x0099:
389            case 0x009A:
390            case 0x009B:
391            case 0x009C:
392            case 0x009D:
393            case 0x009E:
394            case 0x009F:
395                break;
396
397            case 0x00A0:
398                target[pos++] = ( char ) 0x20;
399                break;
400
401            case 0x00AD:
402                break;
403
404            case 0x00B5:
405                target[pos++] = ( char ) 0x03BC;
406                break;
407
408            case 0x00C0:
409            case 0x00C1:
410            case 0x00C2:
411            case 0x00C3:
412            case 0x00C4:
413            case 0x00C5:
414            case 0x00C6:
415            case 0x00C7:
416            case 0x00C8:
417            case 0x00C9:
418            case 0x00CA:
419            case 0x00CB:
420            case 0x00CC:
421            case 0x00CD:
422            case 0x00CE:
423            case 0x00CF:
424            case 0x00D0:
425            case 0x00D1:
426            case 0x00D2:
427            case 0x00D3:
428            case 0x00D4:
429            case 0x00D5:
430            case 0x00D6:
431            case 0x00D8:
432            case 0x00D9:
433            case 0x00DA:
434            case 0x00DB:
435            case 0x00DC:
436            case 0x00DD:
437            case 0x00DE:
438                target[pos++] = ( char ) ( c | lowerCase );
439                break;
440
441            case 0x00DF:
442                target[pos++] = ( char ) 0x0073;
443                target[pos++] = ( char ) 0x0073;
444                break;
445
446            case 0x0100:
447                target[pos++] = ( char ) 0x0101;
448                break;
449
450            case 0x0102:
451                target[pos++] = ( char ) 0x0103;
452                break;
453
454            case 0x0104:
455                target[pos++] = 0x0105;
456                break;
457
458            case 0x0106:
459                target[pos++] = 0x0107;
460                break;
461
462            case 0x0108:
463                target[pos++] = 0x0109;
464                break;
465
466            case 0x010A:
467                target[pos++] = 0x010B;
468                break;
469
470            case 0x010C:
471                target[pos++] = 0x010D;
472                break;
473
474            case 0x010E:
475                target[pos++] = 0x010F;
476                break;
477
478            case 0x0110:
479                target[pos++] = 0x0111;
480                break;
481
482            case 0x0112:
483                target[pos++] = 0x0113;
484                break;
485
486            case 0x0114:
487                target[pos++] = 0x0115;
488                break;
489
490            case 0x0116:
491                target[pos++] = 0x0117;
492                break;
493
494            case 0x0118:
495                target[pos++] = 0x0119;
496                break;
497
498            case 0x011A:
499                target[pos++] = 0x011B;
500                break;
501
502            case 0x011C:
503                target[pos++] = 0x011D;
504                break;
505
506            case 0x011E:
507                target[pos++] = 0x011F;
508                break;
509
510            case 0x0120:
511                target[pos++] = 0x0121;
512                break;
513
514            case 0x0122:
515                target[pos++] = 0x0123;
516                break;
517
518            case 0x0124:
519                target[pos++] = 0x0125;
520                break;
521
522            case 0x0126:
523                target[pos++] = 0x0127;
524                break;
525
526            case 0x0128:
527                target[pos++] = 0x0129;
528                break;
529
530            case 0x012A:
531                target[pos++] = 0x012B;
532                break;
533
534            case 0x012C:
535                target[pos++] = 0x012D;
536                break;
537
538            case 0x012E:
539                target[pos++] = 0x012F;
540                break;
541
542            case 0x0130:
543                target[pos++] = 0x0069;
544                target[pos++] = 0x0307;
545                break;
546
547            case 0x0132:
548                target[pos++] = 0x0133;
549                break;
550
551            case 0x0134:
552                target[pos++] = 0x0135;
553                break;
554
555            case 0x0136:
556                target[pos++] = 0x0137;
557                break;
558
559            case 0x0139:
560                target[pos++] = 0x013A;
561                break;
562
563            case 0x013B:
564                target[pos++] = 0x013C;
565                break;
566
567            case 0x013D:
568                target[pos++] = 0x013E;
569                break;
570
571            case 0x013F:
572                target[pos++] = 0x0140;
573                break;
574
575            case 0x0141:
576                target[pos++] = 0x0142;
577                break;
578
579            case 0x0143:
580                target[pos++] = 0x0144;
581                break;
582
583            case 0x0145:
584                target[pos++] = 0x0146;
585                break;
586
587            case 0x0147:
588                target[pos++] = 0x0148;
589                break;
590
591            case 0x0149:
592                target[pos++] = 0x02BC;
593                target[pos++] = 0x006E;
594                break;
595
596            case 0x014A:
597                target[pos++] = 0x014B;
598                break;
599
600            case 0x014C:
601                target[pos++] = 0x014D;
602                break;
603
604            case 0x014E:
605                target[pos++] = 0x014F;
606                break;
607
608            case 0x0150:
609                target[pos++] = 0x0151;
610                break;
611
612            case 0x0152:
613                target[pos++] = 0x0153;
614                break;
615
616            case 0x0154:
617                target[pos++] = 0x0155;
618                break;
619
620            case 0x0156:
621                target[pos++] = 0x0157;
622                break;
623
624            case 0x0158:
625                target[pos++] = 0x0159;
626                break;
627
628            case 0x015A:
629                target[pos++] = 0x015B;
630                break;
631
632            case 0x015C:
633                target[pos++] = 0x015D;
634                break;
635
636            case 0x015E:
637                target[pos++] = 0x015F;
638                break;
639
640            case 0x0160:
641                target[pos++] = 0x0161;
642                break;
643
644            case 0x0162:
645                target[pos++] = 0x0163;
646                break;
647
648            case 0x0164:
649                target[pos++] = 0x0165;
650                break;
651
652            case 0x0166:
653                target[pos++] = 0x0167;
654                break;
655
656            case 0x0168:
657                target[pos++] = 0x0169;
658                break;
659
660            case 0x016A:
661                target[pos++] = 0x016B;
662                break;
663
664            case 0x016C:
665                target[pos++] = 0x016D;
666                break;
667
668            case 0x016E:
669                target[pos++] = 0x016F;
670                break;
671
672            case 0x0170:
673                target[pos++] = 0x0171;
674                break;
675
676            case 0x0172:
677                target[pos++] = 0x0173;
678                break;
679
680            case 0x0174:
681                target[pos++] = 0x0175;
682                break;
683
684            case 0x0176:
685                target[pos++] = 0x0177;
686                break;
687
688            case 0x0178:
689                target[pos++] = 0x00FF;
690                break;
691
692            case 0x0179:
693                target[pos++] = 0x017A;
694                break;
695
696            case 0x017B:
697                target[pos++] = 0x017C;
698                break;
699
700            case 0x017D:
701                target[pos++] = 0x017E;
702                break;
703
704            case 0x017F:
705                target[pos++] = 0x0073;
706                break;
707
708            case 0x0181:
709                target[pos++] = 0x0253;
710                break;
711
712            case 0x0182:
713                target[pos++] = 0x0183;
714                break;
715
716            case 0x0184:
717                target[pos++] = 0x0185;
718                break;
719
720            case 0x0186:
721                target[pos++] = 0x0254;
722                break;
723
724            case 0x0187:
725                target[pos++] = 0x0188;
726                break;
727
728            case 0x0189:
729                target[pos++] = 0x0256;
730                break;
731
732            case 0x018A:
733                target[pos++] = 0x0257;
734                break;
735
736            case 0x018B:
737                target[pos++] = 0x018C;
738                break;
739
740            case 0x018E:
741                target[pos++] = 0x01DD;
742                break;
743
744            case 0x018F:
745                target[pos++] = 0x0259;
746                break;
747
748            case 0x0190:
749                target[pos++] = 0x025B;
750                break;
751
752            case 0x0191:
753                target[pos++] = 0x0192;
754                break;
755
756            case 0x0193:
757                target[pos++] = 0x0260;
758                break;
759
760            case 0x0194:
761                target[pos++] = 0x0263;
762                break;
763
764            case 0x0196:
765                target[pos++] = 0x0269;
766                break;
767
768            case 0x0197:
769                target[pos++] = 0x0268;
770                break;
771
772            case 0x0198:
773                target[pos++] = 0x0199;
774                break;
775
776            case 0x019C:
777                target[pos++] = 0x026F;
778                break;
779
780            case 0x019D:
781                target[pos++] = 0x0272;
782                break;
783
784            case 0x019F:
785                target[pos++] = 0x0275;
786                break;
787
788            case 0x01A0:
789                target[pos++] = 0x01A1;
790                break;
791
792            case 0x01A2:
793                target[pos++] = 0x01A3;
794                break;
795
796            case 0x01A4:
797                target[pos++] = 0x01A5;
798                break;
799
800            case 0x01A6:
801                target[pos++] = 0x0280;
802                break;
803
804            case 0x01A7:
805                target[pos++] = 0x01A8;
806                break;
807
808            case 0x01A9:
809                target[pos++] = 0x0283;
810                break;
811
812            case 0x01AC:
813                target[pos++] = 0x01AD;
814                break;
815
816            case 0x01AE:
817                target[pos++] = 0x0288;
818                break;
819
820            case 0x01AF:
821                target[pos++] = 0x01B0;
822                break;
823
824            case 0x01B1:
825                target[pos++] = 0x028A;
826                break;
827
828            case 0x01B2:
829                target[pos++] = 0x028B;
830                break;
831
832            case 0x01B3:
833                target[pos++] = 0x01B4;
834                break;
835
836            case 0x01B5:
837                target[pos++] = 0x01B6;
838                break;
839
840            case 0x01B7:
841                target[pos++] = 0x0292;
842                break;
843
844            case 0x01B8:
845                target[pos++] = 0x01B9;
846                break;
847
848            case 0x01BC:
849                target[pos++] = 0x01BD;
850                break;
851
852            case 0x01C4:
853                target[pos++] = 0x01C6;
854                break;
855
856            case 0x01C5:
857                target[pos++] = 0x01C6;
858                break;
859
860            case 0x01C7:
861                target[pos++] = 0x01C9;
862                break;
863
864            case 0x01C8:
865                target[pos++] = 0x01C9;
866                break;
867
868            case 0x01CA:
869                target[pos++] = 0x01CC;
870                break;
871
872            case 0x01CB:
873                target[pos++] = 0x01CC;
874                break;
875
876            case 0x01CD:
877                target[pos++] = 0x01CE;
878                break;
879
880            case 0x01CF:
881                target[pos++] = 0x01D0;
882                break;
883
884            case 0x01D1:
885                target[pos++] = 0x01D2;
886                break;
887
888            case 0x01D3:
889                target[pos++] = 0x01D4;
890                break;
891
892            case 0x01D5:
893                target[pos++] = 0x01D6;
894                break;
895
896            case 0x01D7:
897                target[pos++] = 0x01D8;
898                break;
899
900            case 0x01D9:
901                target[pos++] = 0x01DA;
902                break;
903
904            case 0x01DB:
905                target[pos++] = 0x01DC;
906                break;
907
908            case 0x01DE:
909                target[pos++] = 0x01DF;
910                break;
911
912            case 0x01E0:
913                target[pos++] = 0x01E1;
914                break;
915
916            case 0x01E2:
917                target[pos++] = 0x01E3;
918                break;
919
920            case 0x01E4:
921                target[pos++] = 0x01E5;
922                break;
923
924            case 0x01E6:
925                target[pos++] = 0x01E7;
926                break;
927
928            case 0x01E8:
929                target[pos++] = 0x01E9;
930                break;
931
932            case 0x01EA:
933                target[pos++] = 0x01EB;
934                break;
935
936            case 0x01EC:
937                target[pos++] = 0x01ED;
938                break;
939
940            case 0x01EE:
941                target[pos++] = 0x01EF;
942                break;
943
944            case 0x01F0:
945                target[pos++] = 0x006A;
946                target[pos++] = 0x030C;
947                break;
948
949            case 0x01F1:
950                target[pos++] = 0x01F3;
951                break;
952
953            case 0x01F2:
954                target[pos++] = 0x01F3;
955                break;
956
957            case 0x01F4:
958                target[pos++] = 0x01F5;
959                break;
960
961            case 0x01F6:
962                target[pos++] = 0x0195;
963                break;
964
965            case 0x01F7:
966                target[pos++] = 0x01BF;
967                break;
968
969            case 0x01F8:
970                target[pos++] = 0x01F9;
971                break;
972
973            case 0x01FA:
974                target[pos++] = 0x01FB;
975                break;
976
977            case 0x01FC:
978                target[pos++] = 0x01FD;
979                break;
980
981            case 0x01FE:
982                target[pos++] = 0x01FF;
983                break;
984
985            case 0x0200:
986                target[pos++] = 0x0201;
987                break;
988
989            case 0x0202:
990                target[pos++] = 0x0203;
991                break;
992
993            case 0x0204:
994                target[pos++] = 0x0205;
995                break;
996
997            case 0x0206:
998                target[pos++] = 0x0207;
999                break;
1000
1001            case 0x0208:
1002                target[pos++] = 0x0209;
1003                break;
1004
1005            case 0x020A:
1006                target[pos++] = 0x020B;
1007                break;
1008
1009            case 0x020C:
1010                target[pos++] = 0x020D;
1011                break;
1012
1013            case 0x020E:
1014                target[pos++] = 0x020F;
1015                break;
1016
1017            case 0x0210:
1018                target[pos++] = 0x0211;
1019                break;
1020
1021            case 0x0212:
1022                target[pos++] = 0x0213;
1023                break;
1024
1025            case 0x0214:
1026                target[pos++] = 0x0215;
1027                break;
1028
1029            case 0x0216:
1030                target[pos++] = 0x0217;
1031                break;
1032
1033            case 0x0218:
1034                target[pos++] = 0x0219;
1035                break;
1036
1037            case 0x021A:
1038                target[pos++] = 0x021B;
1039                break;
1040
1041            case 0x021C:
1042                target[pos++] = 0x021D;
1043                break;
1044
1045            case 0x021E:
1046                target[pos++] = 0x021F;
1047                break;
1048
1049            case 0x0220:
1050                target[pos++] = 0x019E;
1051                break;
1052
1053            case 0x0222:
1054                target[pos++] = 0x0223;
1055                break;
1056
1057            case 0x0224:
1058                target[pos++] = 0x0225;
1059                break;
1060
1061            case 0x0226:
1062                target[pos++] = 0x0227;
1063                break;
1064
1065            case 0x0228:
1066                target[pos++] = 0x0229;
1067                break;
1068
1069            case 0x022A:
1070                target[pos++] = 0x022B;
1071                break;
1072
1073            case 0x022C:
1074                target[pos++] = 0x022D;
1075                break;
1076
1077            case 0x022E:
1078                target[pos++] = 0x022F;
1079                break;
1080
1081            case 0x0230:
1082                target[pos++] = 0x0231;
1083                break;
1084
1085            case 0x0232:
1086                target[pos++] = 0x0233;
1087                break;
1088
1089            case 0x0345:
1090                target[pos++] = 0x03B9;
1091                break;
1092
1093            case 0x034F:
1094                break;
1095
1096            case 0x037A:
1097                target[pos++] = 0x0020;
1098                target[pos++] = 0x03B9;
1099                break;
1100
1101            case 0x0386:
1102                target[pos++] = 0x03AC;
1103                break;
1104
1105            case 0x0388:
1106                target[pos++] = 0x03AD;
1107                break;
1108
1109            case 0x0389:
1110                target[pos++] = 0x03AE;
1111                break;
1112
1113            case 0x038A:
1114                target[pos++] = 0x03AF;
1115                break;
1116
1117            case 0x038C:
1118                target[pos++] = 0x03CC;
1119                break;
1120
1121            case 0x038E:
1122                target[pos++] = 0x03CD;
1123                break;
1124
1125            case 0x038F:
1126                target[pos++] = 0x03CE;
1127                break;
1128
1129            case 0x0390:
1130                target[pos++] = 0x03B9;
1131                target[pos++] = 0x0308;
1132                target[pos++] = 0x0301;
1133                break;
1134
1135            case 0x0391:
1136                target[pos++] = 0x03B1;
1137                break;
1138
1139            case 0x0392:
1140                target[pos++] = 0x03B2;
1141                break;
1142
1143            case 0x0393:
1144                target[pos++] = 0x03B3;
1145                break;
1146
1147            case 0x0394:
1148                target[pos++] = 0x03B4;
1149                break;
1150
1151            case 0x0395:
1152                target[pos++] = 0x03B5;
1153                break;
1154
1155            case 0x0396:
1156                target[pos++] = 0x03B6;
1157                break;
1158
1159            case 0x0397:
1160                target[pos++] = 0x03B7;
1161                break;
1162
1163            case 0x0398:
1164                target[pos++] = 0x03B8;
1165                break;
1166
1167            case 0x0399:
1168                target[pos++] = 0x03B9;
1169                break;
1170
1171            case 0x039A:
1172                target[pos++] = 0x03BA;
1173                break;
1174
1175            case 0x039B:
1176                target[pos++] = 0x03BB;
1177                break;
1178
1179            case 0x039C:
1180                target[pos++] = 0x03BC;
1181                break;
1182
1183            case 0x039D:
1184                target[pos++] = 0x03BD;
1185                break;
1186
1187            case 0x039E:
1188                target[pos++] = 0x03BE;
1189                break;
1190
1191            case 0x039F:
1192                target[pos++] = 0x03BF;
1193                break;
1194
1195            case 0x03A0:
1196                target[pos++] = 0x03C0;
1197                break;
1198
1199            case 0x03A1:
1200                target[pos++] = 0x03C1;
1201                break;
1202
1203            case 0x03A3:
1204                target[pos++] = 0x03C3;
1205                break;
1206
1207            case 0x03A4:
1208                target[pos++] = 0x03C4;
1209                break;
1210
1211            case 0x03A5:
1212                target[pos++] = 0x03C5;
1213                break;
1214
1215            case 0x03A6:
1216                target[pos++] = 0x03C6;
1217                break;
1218
1219            case 0x03A7:
1220                target[pos++] = 0x03C7;
1221                break;
1222
1223            case 0x03A8:
1224                target[pos++] = 0x03C8;
1225                break;
1226
1227            case 0x03A9:
1228                target[pos++] = 0x03C9;
1229                break;
1230
1231            case 0x03AA:
1232                target[pos++] = 0x03CA;
1233                break;
1234
1235            case 0x03AB:
1236                target[pos++] = 0x03CB;
1237                break;
1238
1239            case 0x03B0:
1240                target[pos++] = 0x03C5;
1241                target[pos++] = 0x0308;
1242                target[pos++] = 0x0301;
1243                break;
1244
1245            case 0x03C2:
1246                target[pos++] = 0x03C3;
1247                break;
1248
1249            case 0x03D0:
1250                target[pos++] = 0x03B2;
1251                break;
1252
1253            case 0x03D1:
1254                target[pos++] = 0x03B8;
1255                break;
1256
1257            case 0x03D2:
1258                target[pos++] = 0x03C5;
1259                break;
1260
1261            case 0x03D3:
1262                target[pos++] = 0x03CD;
1263                break;
1264
1265            case 0x03D4:
1266                target[pos++] = 0x03CB;
1267                break;
1268
1269            case 0x03D5:
1270                target[pos++] = 0x03C6;
1271                break;
1272
1273            case 0x03D6:
1274                target[pos++] = 0x03C0;
1275                break;
1276
1277            case 0x03D8:
1278                target[pos++] = 0x03D9;
1279                break;
1280
1281            case 0x03DA:
1282                target[pos++] = 0x03DB;
1283                break;
1284
1285            case 0x03DC:
1286                target[pos++] = 0x03DD;
1287                break;
1288
1289            case 0x03DE:
1290                target[pos++] = 0x03DF;
1291                break;
1292
1293            case 0x03E0:
1294                target[pos++] = 0x03E1;
1295                break;
1296
1297            case 0x03E2:
1298                target[pos++] = 0x03E3;
1299                break;
1300
1301            case 0x03E4:
1302                target[pos++] = 0x03E5;
1303                break;
1304
1305            case 0x03E6:
1306                target[pos++] = 0x03E7;
1307                break;
1308
1309            case 0x03E8:
1310                target[pos++] = 0x03E9;
1311                break;
1312
1313            case 0x03EA:
1314                target[pos++] = 0x03EB;
1315                break;
1316
1317            case 0x03EC:
1318                target[pos++] = 0x03ED;
1319                break;
1320
1321            case 0x03EE:
1322                target[pos++] = 0x03EF;
1323                break;
1324
1325            case 0x03F0:
1326                target[pos++] = 0x03BA;
1327                break;
1328
1329            case 0x03F1:
1330                target[pos++] = 0x03C1;
1331                break;
1332
1333            case 0x03F2:
1334                target[pos++] = 0x03C3;
1335                break;
1336
1337            case 0x03F4:
1338                target[pos++] = 0x03B8;
1339                break;
1340
1341            case 0x03F5:
1342                target[pos++] = 0x03B5;
1343                break;
1344
1345            case 0x0400:
1346                target[pos++] = 0x0450;
1347                break;
1348
1349            case 0x0401:
1350                target[pos++] = 0x0451;
1351                break;
1352
1353            case 0x0402:
1354                target[pos++] = 0x0452;
1355                break;
1356
1357            case 0x0403:
1358                target[pos++] = 0x0453;
1359                break;
1360
1361            case 0x0404:
1362                target[pos++] = 0x0454;
1363                break;
1364
1365            case 0x0405:
1366                target[pos++] = 0x0455;
1367                break;
1368
1369            case 0x0406:
1370                target[pos++] = 0x0456;
1371                break;
1372
1373            case 0x0407:
1374                target[pos++] = 0x0457;
1375                break;
1376
1377            case 0x0408:
1378                target[pos++] = 0x0458;
1379                break;
1380
1381            case 0x0409:
1382                target[pos++] = 0x0459;
1383                break;
1384
1385            case 0x040A:
1386                target[pos++] = 0x045A;
1387                break;
1388
1389            case 0x040B:
1390                target[pos++] = 0x045B;
1391                break;
1392
1393            case 0x040C:
1394                target[pos++] = 0x045C;
1395                break;
1396
1397            case 0x040D:
1398                target[pos++] = 0x045D;
1399                break;
1400
1401            case 0x040E:
1402                target[pos++] = 0x045E;
1403                break;
1404
1405            case 0x040F:
1406                target[pos++] = 0x045F;
1407                break;
1408
1409            case 0x0410:
1410                target[pos++] = 0x0430;
1411                break;
1412
1413            case 0x0411:
1414                target[pos++] = 0x0431;
1415                break;
1416
1417            case 0x0412:
1418                target[pos++] = 0x0432;
1419                break;
1420
1421            case 0x0413:
1422                target[pos++] = 0x0433;
1423                break;
1424
1425            case 0x0414:
1426                target[pos++] = 0x0434;
1427                break;
1428
1429            case 0x0415:
1430                target[pos++] = 0x0435;
1431                break;
1432
1433            case 0x0416:
1434                target[pos++] = 0x0436;
1435                break;
1436
1437            case 0x0417:
1438                target[pos++] = 0x0437;
1439                break;
1440
1441            case 0x0418:
1442                target[pos++] = 0x0438;
1443                break;
1444
1445            case 0x0419:
1446                target[pos++] = 0x0439;
1447                break;
1448
1449            case 0x041A:
1450                target[pos++] = 0x043A;
1451                break;
1452
1453            case 0x041B:
1454                target[pos++] = 0x043B;
1455                break;
1456
1457            case 0x041C:
1458                target[pos++] = 0x043C;
1459                break;
1460
1461            case 0x041D:
1462                target[pos++] = 0x043D;
1463                break;
1464
1465            case 0x041E:
1466                target[pos++] = 0x043E;
1467                break;
1468
1469            case 0x041F:
1470                target[pos++] = 0x043F;
1471                break;
1472
1473            case 0x0420:
1474                target[pos++] = 0x0440;
1475                break;
1476
1477            case 0x0421:
1478                target[pos++] = 0x0441;
1479                break;
1480
1481            case 0x0422:
1482                target[pos++] = 0x0442;
1483                break;
1484
1485            case 0x0423:
1486                target[pos++] = 0x0443;
1487                break;
1488
1489            case 0x0424:
1490                target[pos++] = 0x0444;
1491                break;
1492
1493            case 0x0425:
1494                target[pos++] = 0x0445;
1495                break;
1496
1497            case 0x0426:
1498                target[pos++] = 0x0446;
1499                break;
1500
1501            case 0x0427:
1502                target[pos++] = 0x0447;
1503                break;
1504
1505            case 0x0428:
1506                target[pos++] = 0x0448;
1507                break;
1508
1509            case 0x0429:
1510                target[pos++] = 0x0449;
1511                break;
1512
1513            case 0x042A:
1514                target[pos++] = 0x044A;
1515                break;
1516
1517            case 0x042B:
1518                target[pos++] = 0x044B;
1519                break;
1520
1521            case 0x042C:
1522                target[pos++] = 0x044C;
1523                break;
1524
1525            case 0x042D:
1526                target[pos++] = 0x044D;
1527                break;
1528
1529            case 0x042E:
1530                target[pos++] = 0x044E;
1531                break;
1532
1533            case 0x042F:
1534                target[pos++] = 0x044F;
1535                break;
1536
1537            case 0x0460:
1538                target[pos++] = 0x0461;
1539                break;
1540
1541            case 0x0462:
1542                target[pos++] = 0x0463;
1543                break;
1544
1545            case 0x0464:
1546                target[pos++] = 0x0465;
1547                break;
1548
1549            case 0x0466:
1550                target[pos++] = 0x0467;
1551                break;
1552
1553            case 0x0468:
1554                target[pos++] = 0x0469;
1555                break;
1556
1557            case 0x046A:
1558                target[pos++] = 0x046B;
1559                break;
1560
1561            case 0x046C:
1562                target[pos++] = 0x046D;
1563                break;
1564
1565            case 0x046E:
1566                target[pos++] = 0x046F;
1567                break;
1568
1569            case 0x0470:
1570                target[pos++] = 0x0471;
1571                break;
1572
1573            case 0x0472:
1574                target[pos++] = 0x0473;
1575                break;
1576
1577            case 0x0474:
1578                target[pos++] = 0x0475;
1579                break;
1580
1581            case 0x0476:
1582                target[pos++] = 0x0477;
1583                break;
1584
1585            case 0x0478:
1586                target[pos++] = 0x0479;
1587                break;
1588
1589            case 0x047A:
1590                target[pos++] = 0x047B;
1591                break;
1592
1593            case 0x047C:
1594                target[pos++] = 0x047D;
1595                break;
1596
1597            case 0x047E:
1598                target[pos++] = 0x047F;
1599                break;
1600
1601            case 0x0480:
1602                target[pos++] = 0x0481;
1603                break;
1604
1605            case 0x048A:
1606                target[pos++] = 0x048B;
1607                break;
1608
1609            case 0x048C:
1610                target[pos++] = 0x048D;
1611                break;
1612
1613            case 0x048E:
1614                target[pos++] = 0x048F;
1615                break;
1616
1617            case 0x0490:
1618                target[pos++] = 0x0491;
1619                break;
1620
1621            case 0x0492:
1622                target[pos++] = 0x0493;
1623                break;
1624
1625            case 0x0494:
1626                target[pos++] = 0x0495;
1627                break;
1628
1629            case 0x0496:
1630                target[pos++] = 0x0497;
1631                break;
1632
1633            case 0x0498:
1634                target[pos++] = 0x0499;
1635                break;
1636
1637            case 0x049A:
1638                target[pos++] = 0x049B;
1639                break;
1640
1641            case 0x049C:
1642                target[pos++] = 0x049D;
1643                break;
1644
1645            case 0x049E:
1646                target[pos++] = 0x049F;
1647                break;
1648
1649            case 0x04A0:
1650                target[pos++] = 0x04A1;
1651                break;
1652
1653            case 0x04A2:
1654                target[pos++] = 0x04A3;
1655                break;
1656
1657            case 0x04A4:
1658                target[pos++] = 0x04A5;
1659                break;
1660
1661            case 0x04A6:
1662                target[pos++] = 0x04A7;
1663                break;
1664
1665            case 0x04A8:
1666                target[pos++] = 0x04A9;
1667                break;
1668
1669            case 0x04AA:
1670                target[pos++] = 0x04AB;
1671                break;
1672
1673            case 0x04AC:
1674                target[pos++] = 0x04AD;
1675                break;
1676
1677            case 0x04AE:
1678                target[pos++] = 0x04AF;
1679                break;
1680
1681            case 0x04B0:
1682                target[pos++] = 0x04B1;
1683                break;
1684
1685            case 0x04B2:
1686                target[pos++] = 0x04B3;
1687                break;
1688
1689            case 0x04B4:
1690                target[pos++] = 0x04B5;
1691                break;
1692
1693            case 0x04B6:
1694                target[pos++] = 0x04B7;
1695                break;
1696
1697            case 0x04B8:
1698                target[pos++] = 0x04B9;
1699                break;
1700
1701            case 0x04BA:
1702                target[pos++] = 0x04BB;
1703                break;
1704
1705            case 0x04BC:
1706                target[pos++] = 0x04BD;
1707                break;
1708
1709            case 0x04BE:
1710                target[pos++] = 0x04BF;
1711                break;
1712
1713            case 0x04C1:
1714                target[pos++] = 0x04C2;
1715                break;
1716
1717            case 0x04C3:
1718                target[pos++] = 0x04C4;
1719                break;
1720
1721            case 0x04C5:
1722                target[pos++] = 0x04C6;
1723                break;
1724
1725            case 0x04C7:
1726                target[pos++] = 0x04C8;
1727                break;
1728
1729            case 0x04C9:
1730                target[pos++] = 0x04CA;
1731                break;
1732
1733            case 0x04CB:
1734                target[pos++] = 0x04CC;
1735                break;
1736
1737            case 0x04CD:
1738                target[pos++] = 0x04CE;
1739                break;
1740
1741            case 0x04D0:
1742                target[pos++] = 0x04D1;
1743                break;
1744
1745            case 0x04D2:
1746                target[pos++] = 0x04D3;
1747                break;
1748
1749            case 0x04D4:
1750                target[pos++] = 0x04D5;
1751                break;
1752
1753            case 0x04D6:
1754                target[pos++] = 0x04D7;
1755                break;
1756
1757            case 0x04D8:
1758                target[pos++] = 0x04D9;
1759                break;
1760
1761            case 0x04DA:
1762                target[pos++] = 0x04DB;
1763                break;
1764
1765            case 0x04DC:
1766                target[pos++] = 0x04DD;
1767                break;
1768
1769            case 0x04DE:
1770                target[pos++] = 0x04DF;
1771                break;
1772
1773            case 0x04E0:
1774                target[pos++] = 0x04E1;
1775                break;
1776
1777            case 0x04E2:
1778                target[pos++] = 0x04E3;
1779                break;
1780
1781            case 0x04E4:
1782                target[pos++] = 0x04E5;
1783                break;
1784
1785            case 0x04E6:
1786                target[pos++] = 0x04E7;
1787                break;
1788
1789            case 0x04E8:
1790                target[pos++] = 0x04E9;
1791                break;
1792
1793            case 0x04EA:
1794                target[pos++] = 0x04EB;
1795                break;
1796
1797            case 0x04EC:
1798                target[pos++] = 0x04ED;
1799                break;
1800
1801            case 0x04EE:
1802                target[pos++] = 0x04EF;
1803                break;
1804
1805            case 0x04F0:
1806                target[pos++] = 0x04F1;
1807                break;
1808
1809            case 0x04F2:
1810                target[pos++] = 0x04F3;
1811                break;
1812
1813            case 0x04F4:
1814                target[pos++] = 0x04F5;
1815                break;
1816
1817            case 0x04F8:
1818                target[pos++] = 0x04F9;
1819                break;
1820
1821            case 0x0500:
1822                target[pos++] = 0x0501;
1823                break;
1824
1825            case 0x0502:
1826                target[pos++] = 0x0503;
1827                break;
1828
1829            case 0x0504:
1830                target[pos++] = 0x0505;
1831                break;
1832
1833            case 0x0506:
1834                target[pos++] = 0x0507;
1835                break;
1836
1837            case 0x0508:
1838                target[pos++] = 0x0509;
1839                break;
1840
1841            case 0x050A:
1842                target[pos++] = 0x050B;
1843                break;
1844
1845            case 0x050C:
1846                target[pos++] = 0x050D;
1847                break;
1848
1849            case 0x050E:
1850                target[pos++] = 0x050F;
1851                break;
1852
1853            case 0x0531:
1854                target[pos++] = 0x0561;
1855                break;
1856
1857            case 0x0532:
1858                target[pos++] = 0x0562;
1859                break;
1860
1861            case 0x0533:
1862                target[pos++] = 0x0563;
1863                break;
1864
1865            case 0x0534:
1866                target[pos++] = 0x0564;
1867                break;
1868
1869            case 0x0535:
1870                target[pos++] = 0x0565;
1871                break;
1872
1873            case 0x0536:
1874                target[pos++] = 0x0566;
1875                break;
1876
1877            case 0x0537:
1878                target[pos++] = 0x0567;
1879                break;
1880
1881            case 0x0538:
1882                target[pos++] = 0x0568;
1883                break;
1884
1885            case 0x0539:
1886                target[pos++] = 0x0569;
1887                break;
1888
1889            case 0x053A:
1890                target[pos++] = 0x056A;
1891                break;
1892
1893            case 0x053B:
1894                target[pos++] = 0x056B;
1895                break;
1896
1897            case 0x053C:
1898                target[pos++] = 0x056C;
1899                break;
1900
1901            case 0x053D:
1902                target[pos++] = 0x056D;
1903                break;
1904
1905            case 0x053E:
1906                target[pos++] = 0x056E;
1907                break;
1908
1909            case 0x053F:
1910                target[pos++] = 0x056F;
1911                break;
1912
1913            case 0x0540:
1914                target[pos++] = 0x0570;
1915                break;
1916
1917            case 0x0541:
1918                target[pos++] = 0x0571;
1919                break;
1920
1921            case 0x0542:
1922                target[pos++] = 0x0572;
1923                break;
1924
1925            case 0x0543:
1926                target[pos++] = 0x0573;
1927                break;
1928
1929            case 0x0544:
1930                target[pos++] = 0x0574;
1931                break;
1932
1933            case 0x0545:
1934                target[pos++] = 0x0575;
1935                break;
1936
1937            case 0x0546:
1938                target[pos++] = 0x0576;
1939                break;
1940
1941            case 0x0547:
1942                target[pos++] = 0x0577;
1943                break;
1944
1945            case 0x0548:
1946                target[pos++] = 0x0578;
1947                break;
1948
1949            case 0x0549:
1950                target[pos++] = 0x0579;
1951                break;
1952
1953            case 0x054A:
1954                target[pos++] = 0x057A;
1955                break;
1956
1957            case 0x054B:
1958                target[pos++] = 0x057B;
1959                break;
1960
1961            case 0x054C:
1962                target[pos++] = 0x057C;
1963                break;
1964
1965            case 0x054D:
1966                target[pos++] = 0x057D;
1967                break;
1968
1969            case 0x054E:
1970                target[pos++] = 0x057E;
1971                break;
1972
1973            case 0x054F:
1974                target[pos++] = 0x057F;
1975                break;
1976
1977            case 0x0550:
1978                target[pos++] = 0x0580;
1979                break;
1980
1981            case 0x0551:
1982                target[pos++] = 0x0581;
1983                break;
1984
1985            case 0x0552:
1986                target[pos++] = 0x0582;
1987                break;
1988
1989            case 0x0553:
1990                target[pos++] = 0x0583;
1991                break;
1992
1993            case 0x0554:
1994                target[pos++] = 0x0584;
1995                break;
1996
1997            case 0x0555:
1998                target[pos++] = 0x0585;
1999                break;
2000
2001            case 0x0556:
2002                target[pos++] = 0x0586;
2003                break;
2004
2005            case 0x0587:
2006                target[pos++] = 0x0565;
2007                target[pos++] = 0x0582;
2008                break;
2009
2010            case 0x06DD:
2011                break;
2012
2013            case 0x070F:
2014                break;
2015
2016            case 0x1680:
2017                target[pos++] = 0x0020;
2018                break;
2019
2020            case 0x1806:
2021                break;
2022
2023            case 0x180B:
2024            case 0x180C:
2025            case 0x180D:
2026            case 0x180E:
2027                break;
2028
2029            case 0x1E00:
2030                target[pos++] = 0x1E01;
2031                break;
2032
2033            case 0x1E02:
2034                target[pos++] = 0x1E03;
2035                break;
2036
2037            case 0x1E04:
2038                target[pos++] = 0x1E05;
2039                break;
2040
2041            case 0x1E06:
2042                target[pos++] = 0x1E07;
2043                break;
2044
2045            case 0x1E08:
2046                target[pos++] = 0x1E09;
2047                break;
2048
2049            case 0x1E0A:
2050                target[pos++] = 0x1E0B;
2051                break;
2052
2053            case 0x1E0C:
2054                target[pos++] = 0x1E0D;
2055                break;
2056
2057            case 0x1E0E:
2058                target[pos++] = 0x1E0F;
2059                break;
2060
2061            case 0x1E10:
2062                target[pos++] = 0x1E11;
2063                break;
2064
2065            case 0x1E12:
2066                target[pos++] = 0x1E13;
2067                break;
2068
2069            case 0x1E14:
2070                target[pos++] = 0x1E15;
2071                break;
2072
2073            case 0x1E16:
2074                target[pos++] = 0x1E17;
2075                break;
2076
2077            case 0x1E18:
2078                target[pos++] = 0x1E19;
2079                break;
2080
2081            case 0x1E1A:
2082                target[pos++] = 0x1E1B;
2083                break;
2084
2085            case 0x1E1C:
2086                target[pos++] = 0x1E1D;
2087                break;
2088
2089            case 0x1E1E:
2090                target[pos++] = 0x1E1F;
2091                break;
2092
2093            case 0x1E20:
2094                target[pos++] = 0x1E21;
2095                break;
2096
2097            case 0x1E22:
2098                target[pos++] = 0x1E23;
2099                break;
2100
2101            case 0x1E24:
2102                target[pos++] = 0x1E25;
2103                break;
2104
2105            case 0x1E26:
2106                target[pos++] = 0x1E27;
2107                break;
2108
2109            case 0x1E28:
2110                target[pos++] = 0x1E29;
2111                break;
2112
2113            case 0x1E2A:
2114                target[pos++] = 0x1E2B;
2115                break;
2116
2117            case 0x1E2C:
2118                target[pos++] = 0x1E2D;
2119                break;
2120
2121            case 0x1E2E:
2122                target[pos++] = 0x1E2F;
2123                break;
2124
2125            case 0x1E30:
2126                target[pos++] = 0x1E31;
2127                break;
2128
2129            case 0x1E32:
2130                target[pos++] = 0x1E33;
2131                break;
2132
2133            case 0x1E34:
2134                target[pos++] = 0x1E35;
2135                break;
2136
2137            case 0x1E36:
2138                target[pos++] = 0x1E37;
2139                break;
2140
2141            case 0x1E38:
2142                target[pos++] = 0x1E39;
2143                break;
2144
2145            case 0x1E3A:
2146                target[pos++] = 0x1E3B;
2147                break;
2148
2149            case 0x1E3C:
2150                target[pos++] = 0x1E3D;
2151                break;
2152
2153            case 0x1E3E:
2154                target[pos++] = 0x1E3F;
2155                break;
2156
2157            case 0x1E40:
2158                target[pos++] = 0x1E41;
2159                break;
2160
2161            case 0x1E42:
2162                target[pos++] = 0x1E43;
2163                break;
2164
2165            case 0x1E44:
2166                target[pos++] = 0x1E45;
2167                break;
2168
2169            case 0x1E46:
2170                target[pos++] = 0x1E47;
2171                break;
2172
2173            case 0x1E48:
2174                target[pos++] = 0x1E49;
2175                break;
2176
2177            case 0x1E4A:
2178                target[pos++] = 0x1E4B;
2179                break;
2180
2181            case 0x1E4C:
2182                target[pos++] = 0x1E4D;
2183                break;
2184
2185            case 0x1E4E:
2186                target[pos++] = 0x1E4F;
2187                break;
2188
2189            case 0x1E50:
2190                target[pos++] = 0x1E51;
2191                break;
2192
2193            case 0x1E52:
2194                target[pos++] = 0x1E53;
2195                break;
2196
2197            case 0x1E54:
2198                target[pos++] = 0x1E55;
2199                break;
2200
2201            case 0x1E56:
2202                target[pos++] = 0x1E57;
2203                break;
2204
2205            case 0x1E58:
2206                target[pos++] = 0x1E59;
2207                break;
2208
2209            case 0x1E5A:
2210                target[pos++] = 0x1E5B;
2211                break;
2212
2213            case 0x1E5C:
2214                target[pos++] = 0x1E5D;
2215                break;
2216
2217            case 0x1E5E:
2218                target[pos++] = 0x1E5F;
2219                break;
2220
2221            case 0x1E60:
2222                target[pos++] = 0x1E61;
2223                break;
2224
2225            case 0x1E62:
2226                target[pos++] = 0x1E63;
2227                break;
2228
2229            case 0x1E64:
2230                target[pos++] = 0x1E65;
2231                break;
2232
2233            case 0x1E66:
2234                target[pos++] = 0x1E67;
2235                break;
2236
2237            case 0x1E68:
2238                target[pos++] = 0x1E69;
2239                break;
2240
2241            case 0x1E6A:
2242                target[pos++] = 0x1E6B;
2243                break;
2244
2245            case 0x1E6C:
2246                target[pos++] = 0x1E6D;
2247                break;
2248
2249            case 0x1E6E:
2250                target[pos++] = 0x1E6F;
2251                break;
2252
2253            case 0x1E70:
2254                target[pos++] = 0x1E71;
2255                break;
2256
2257            case 0x1E72:
2258                target[pos++] = 0x1E73;
2259                break;
2260
2261            case 0x1E74:
2262                target[pos++] = 0x1E75;
2263                break;
2264
2265            case 0x1E76:
2266                target[pos++] = 0x1E77;
2267                break;
2268
2269            case 0x1E78:
2270                target[pos++] = 0x1E79;
2271                break;
2272
2273            case 0x1E7A:
2274                target[pos++] = 0x1E7B;
2275                break;
2276
2277            case 0x1E7C:
2278                target[pos++] = 0x1E7D;
2279                break;
2280
2281            case 0x1E7E:
2282                target[pos++] = 0x1E7F;
2283                break;
2284
2285            case 0x1E80:
2286                target[pos++] = 0x1E81;
2287                break;
2288
2289            case 0x1E82:
2290                target[pos++] = 0x1E83;
2291                break;
2292
2293            case 0x1E84:
2294                target[pos++] = 0x1E85;
2295                break;
2296
2297            case 0x1E86:
2298                target[pos++] = 0x1E87;
2299                break;
2300
2301            case 0x1E88:
2302                target[pos++] = 0x1E89;
2303                break;
2304
2305            case 0x1E8A:
2306                target[pos++] = 0x1E8B;
2307                break;
2308
2309            case 0x1E8C:
2310                target[pos++] = 0x1E8D;
2311                break;
2312
2313            case 0x1E8E:
2314                target[pos++] = 0x1E8F;
2315                break;
2316
2317            case 0x1E90:
2318                target[pos++] = 0x1E91;
2319                break;
2320
2321            case 0x1E92:
2322                target[pos++] = 0x1E93;
2323                break;
2324
2325            case 0x1E94:
2326                target[pos++] = 0x1E95;
2327                break;
2328
2329            case 0x1E96:
2330                target[pos++] = 0x0068;
2331                target[pos++] = 0x0331;
2332                break;
2333
2334            case 0x1E97:
2335                target[pos++] = 0x0074;
2336                target[pos++] = 0x0308;
2337                break;
2338
2339            case 0x1E98:
2340                target[pos++] = 0x0077;
2341                target[pos++] = 0x030A;
2342                break;
2343
2344            case 0x1E99:
2345                target[pos++] = 0x0079;
2346                target[pos++] = 0x030A;
2347                break;
2348
2349            case 0x1E9A:
2350                target[pos++] = 0x0061;
2351                target[pos++] = 0x02BE;
2352                break;
2353
2354            case 0x1E9B:
2355                target[pos++] = 0x1E61;
2356                break;
2357
2358            case 0x1EA0:
2359                target[pos++] = 0x1EA1;
2360                break;
2361
2362            case 0x1EA2:
2363                target[pos++] = 0x1EA3;
2364                break;
2365
2366            case 0x1EA4:
2367                target[pos++] = 0x1EA5;
2368                break;
2369
2370            case 0x1EA6:
2371                target[pos++] = 0x1EA7;
2372                break;
2373
2374            case 0x1EA8:
2375                target[pos++] = 0x1EA9;
2376                break;
2377
2378            case 0x1EAA:
2379                target[pos++] = 0x1EAB;
2380                break;
2381
2382            case 0x1EAC:
2383                target[pos++] = 0x1EAD;
2384                break;
2385
2386            case 0x1EAE:
2387                target[pos++] = 0x1EAF;
2388                break;
2389
2390            case 0x1EB0:
2391                target[pos++] = 0x1EB1;
2392                break;
2393
2394            case 0x1EB2:
2395                target[pos++] = 0x1EB3;
2396                break;
2397
2398            case 0x1EB4:
2399                target[pos++] = 0x1EB5;
2400                break;
2401
2402            case 0x1EB6:
2403                target[pos++] = 0x1EB7;
2404                break;
2405
2406            case 0x1EB8:
2407                target[pos++] = 0x1EB9;
2408                break;
2409
2410            case 0x1EBA:
2411                target[pos++] = 0x1EBB;
2412                break;
2413
2414            case 0x1EBC:
2415                target[pos++] = 0x1EBD;
2416                break;
2417
2418            case 0x1EBE:
2419                target[pos++] = 0x1EBF;
2420                break;
2421
2422            case 0x1EC0:
2423                target[pos++] = 0x1EC1;
2424                break;
2425
2426            case 0x1EC2:
2427                target[pos++] = 0x1EC3;
2428                break;
2429
2430            case 0x1EC4:
2431                target[pos++] = 0x1EC5;
2432                break;
2433
2434            case 0x1EC6:
2435                target[pos++] = 0x1EC7;
2436                break;
2437
2438            case 0x1EC8:
2439                target[pos++] = 0x1EC9;
2440                break;
2441
2442            case 0x1ECA:
2443                target[pos++] = 0x1ECB;
2444                break;
2445
2446            case 0x1ECC:
2447                target[pos++] = 0x1ECD;
2448                break;
2449
2450            case 0x1ECE:
2451                target[pos++] = 0x1ECF;
2452                break;
2453
2454            case 0x1ED0:
2455                target[pos++] = 0x1ED1;
2456                break;
2457
2458            case 0x1ED2:
2459                target[pos++] = 0x1ED3;
2460                break;
2461
2462            case 0x1ED4:
2463                target[pos++] = 0x1ED5;
2464                break;
2465
2466            case 0x1ED6:
2467                target[pos++] = 0x1ED7;
2468                break;
2469
2470            case 0x1ED8:
2471                target[pos++] = 0x1ED9;
2472                break;
2473
2474            case 0x1EDA:
2475                target[pos++] = 0x1EDB;
2476                break;
2477
2478            case 0x1EDC:
2479                target[pos++] = 0x1EDD;
2480                break;
2481
2482            case 0x1EDE:
2483                target[pos++] = 0x1EDF;
2484                break;
2485
2486            case 0x1EE0:
2487                target[pos++] = 0x1EE1;
2488                break;
2489
2490            case 0x1EE2:
2491                target[pos++] = 0x1EE3;
2492                break;
2493
2494            case 0x1EE4:
2495                target[pos++] = 0x1EE5;
2496                break;
2497
2498            case 0x1EE6:
2499                target[pos++] = 0x1EE7;
2500                break;
2501
2502            case 0x1EE8:
2503                target[pos++] = 0x1EE9;
2504                break;
2505
2506            case 0x1EEA:
2507                target[pos++] = 0x1EEB;
2508                break;
2509
2510            case 0x1EEC:
2511                target[pos++] = 0x1EED;
2512                break;
2513
2514            case 0x1EEE:
2515                target[pos++] = 0x1EEF;
2516                break;
2517
2518            case 0x1EF0:
2519                target[pos++] = 0x1EF1;
2520                break;
2521
2522            case 0x1EF2:
2523                target[pos++] = 0x1EF3;
2524                break;
2525
2526            case 0x1EF4:
2527                target[pos++] = 0x1EF5;
2528                break;
2529
2530            case 0x1EF6:
2531                target[pos++] = 0x1EF7;
2532                break;
2533
2534            case 0x1EF8:
2535                target[pos++] = 0x1EF9;
2536                break;
2537
2538            case 0x1F08:
2539                target[pos++] = 0x1F00;
2540                break;
2541
2542            case 0x1F09:
2543                target[pos++] = 0x1F01;
2544                break;
2545
2546            case 0x1F0A:
2547                target[pos++] = 0x1F02;
2548                break;
2549
2550            case 0x1F0B:
2551                target[pos++] = 0x1F03;
2552                break;
2553
2554            case 0x1F0C:
2555                target[pos++] = 0x1F04;
2556                break;
2557
2558            case 0x1F0D:
2559                target[pos++] = 0x1F05;
2560                break;
2561
2562            case 0x1F0E:
2563                target[pos++] = 0x1F06;
2564                break;
2565
2566            case 0x1F0F:
2567                target[pos++] = 0x1F07;
2568                break;
2569
2570            case 0x1F18:
2571                target[pos++] = 0x1F10;
2572                break;
2573
2574            case 0x1F19:
2575                target[pos++] = 0x1F11;
2576                break;
2577
2578            case 0x1F1A:
2579                target[pos++] = 0x1F12;
2580                break;
2581
2582            case 0x1F1B:
2583                target[pos++] = 0x1F13;
2584                break;
2585
2586            case 0x1F1C:
2587                target[pos++] = 0x1F14;
2588                break;
2589
2590            case 0x1F1D:
2591                target[pos++] = 0x1F15;
2592                break;
2593
2594            case 0x1F28:
2595                target[pos++] = 0x1F20;
2596                break;
2597
2598            case 0x1F29:
2599                target[pos++] = 0x1F21;
2600                break;
2601
2602            case 0x1F2A:
2603                target[pos++] = 0x1F22;
2604                break;
2605
2606            case 0x1F2B:
2607                target[pos++] = 0x1F23;
2608                break;
2609
2610            case 0x1F2C:
2611                target[pos++] = 0x1F24;
2612                break;
2613
2614            case 0x1F2D:
2615                target[pos++] = 0x1F25;
2616                break;
2617
2618            case 0x1F2E:
2619                target[pos++] = 0x1F26;
2620                break;
2621
2622            case 0x1F2F:
2623                target[pos++] = 0x1F27;
2624                break;
2625
2626            case 0x1F38:
2627                target[pos++] = 0x1F30;
2628                break;
2629
2630            case 0x1F39:
2631                target[pos++] = 0x1F31;
2632                break;
2633
2634            case 0x1F3A:
2635                target[pos++] = 0x1F32;
2636                break;
2637
2638            case 0x1F3B:
2639                target[pos++] = 0x1F33;
2640                break;
2641
2642            case 0x1F3C:
2643                target[pos++] = 0x1F34;
2644                break;
2645
2646            case 0x1F3D:
2647                target[pos++] = 0x1F35;
2648                break;
2649
2650            case 0x1F3E:
2651                target[pos++] = 0x1F36;
2652                break;
2653
2654            case 0x1F3F:
2655                target[pos++] = 0x1F37;
2656                break;
2657
2658            case 0x1F48:
2659                target[pos++] = 0x1F40;
2660                break;
2661
2662            case 0x1F49:
2663                target[pos++] = 0x1F41;
2664                break;
2665
2666            case 0x1F4A:
2667                target[pos++] = 0x1F42;
2668                break;
2669
2670            case 0x1F4B:
2671                target[pos++] = 0x1F43;
2672                break;
2673
2674            case 0x1F4C:
2675                target[pos++] = 0x1F44;
2676                break;
2677
2678            case 0x1F4D:
2679                target[pos++] = 0x1F45;
2680                break;
2681
2682            case 0x1F50:
2683                target[pos++] = 0x03C5;
2684                target[pos++] = 0x0313;
2685                break;
2686
2687            case 0x1F52:
2688                target[pos++] = 0x03C5;
2689                target[pos++] = 0x0313;
2690                target[pos++] = 0x0300;
2691                break;
2692
2693            case 0x1F54:
2694                target[pos++] = 0x03C5;
2695                target[pos++] = 0x0313;
2696                target[pos++] = 0x0301;
2697                break;
2698
2699            case 0x1F56:
2700                target[pos++] = 0x03C5;
2701                target[pos++] = 0x0313;
2702                target[pos++] = 0x0342;
2703                break;
2704
2705            case 0x1F59:
2706                target[pos++] = 0x1F51;
2707                break;
2708
2709            case 0x1F5B:
2710                target[pos++] = 0x1F53;
2711                break;
2712
2713            case 0x1F5D:
2714                target[pos++] = 0x1F55;
2715                break;
2716
2717            case 0x1F5F:
2718                target[pos++] = 0x1F57;
2719                break;
2720
2721            case 0x1F68:
2722                target[pos++] = 0x1F60;
2723                break;
2724
2725            case 0x1F69:
2726                target[pos++] = 0x1F61;
2727                break;
2728
2729            case 0x1F6A:
2730                target[pos++] = 0x1F62;
2731                break;
2732
2733            case 0x1F6B:
2734                target[pos++] = 0x1F63;
2735                break;
2736
2737            case 0x1F6C:
2738                target[pos++] = 0x1F64;
2739                break;
2740
2741            case 0x1F6D:
2742                target[pos++] = 0x1F65;
2743                break;
2744
2745            case 0x1F6E:
2746                target[pos++] = 0x1F66;
2747                break;
2748
2749            case 0x1F6F:
2750                target[pos++] = 0x1F67;
2751                break;
2752
2753            case 0x1F80:
2754                target[pos++] = 0x1F00;
2755                target[pos++] = 0x03B9;
2756                break;
2757
2758            case 0x1F81:
2759                target[pos++] = 0x1F01;
2760                target[pos++] = 0x03B9;
2761                break;
2762
2763            case 0x1F82:
2764                target[pos++] = 0x1F02;
2765                target[pos++] = 0x03B9;
2766                break;
2767
2768            case 0x1F83:
2769                target[pos++] = 0x1F03;
2770                target[pos++] = 0x03B9;
2771                break;
2772
2773            case 0x1F84:
2774                target[pos++] = 0x1F04;
2775                target[pos++] = 0x03B9;
2776                break;
2777
2778            case 0x1F85:
2779                target[pos++] = 0x1F05;
2780                target[pos++] = 0x03B9;
2781                break;
2782
2783            case 0x1F86:
2784                target[pos++] = 0x1F06;
2785                target[pos++] = 0x03B9;
2786                break;
2787
2788            case 0x1F87:
2789                target[pos++] = 0x1F07;
2790                target[pos++] = 0x03B9;
2791                break;
2792
2793            case 0x1F88:
2794                target[pos++] = 0x1F00;
2795                target[pos++] = 0x03B9;
2796                break;
2797
2798            case 0x1F89:
2799                target[pos++] = 0x1F01;
2800                target[pos++] = 0x03B9;
2801                break;
2802
2803            case 0x1F8A:
2804                target[pos++] = 0x1F02;
2805                target[pos++] = 0x03B9;
2806                break;
2807
2808            case 0x1F8B:
2809                target[pos++] = 0x1F03;
2810                target[pos++] = 0x03B9;
2811                break;
2812
2813            case 0x1F8C:
2814                target[pos++] = 0x1F04;
2815                target[pos++] = 0x03B9;
2816                break;
2817
2818            case 0x1F8D:
2819                target[pos++] = 0x1F05;
2820                target[pos++] = 0x03B9;
2821                break;
2822
2823            case 0x1F8E:
2824                target[pos++] = 0x1F06;
2825                target[pos++] = 0x03B9;
2826                break;
2827
2828            case 0x1F8F:
2829                target[pos++] = 0x1F07;
2830                target[pos++] = 0x03B9;
2831                break;
2832
2833            case 0x1F90:
2834                target[pos++] = 0x1F20;
2835                target[pos++] = 0x03B9;
2836                break;
2837
2838            case 0x1F91:
2839                target[pos++] = 0x1F21;
2840                target[pos++] = 0x03B9;
2841                break;
2842
2843            case 0x1F92:
2844                target[pos++] = 0x1F22;
2845                target[pos++] = 0x03B9;
2846                break;
2847
2848            case 0x1F93:
2849                target[pos++] = 0x1F23;
2850                target[pos++] = 0x03B9;
2851                break;
2852
2853            case 0x1F94:
2854                target[pos++] = 0x1F24;
2855                target[pos++] = 0x03B9;
2856                break;
2857
2858            case 0x1F95:
2859                target[pos++] = 0x1F25;
2860                target[pos++] = 0x03B9;
2861                break;
2862
2863            case 0x1F96:
2864                target[pos++] = 0x1F26;
2865                target[pos++] = 0x03B9;
2866                break;
2867
2868            case 0x1F97:
2869                target[pos++] = 0x1F27;
2870                target[pos++] = 0x03B9;
2871                break;
2872
2873            case 0x1F98:
2874                target[pos++] = 0x1F20;
2875                target[pos++] = 0x03B9;
2876                break;
2877
2878            case 0x1F99:
2879                target[pos++] = 0x1F21;
2880                target[pos++] = 0x03B9;
2881                break;
2882
2883            case 0x1F9A:
2884                target[pos++] = 0x1F22;
2885                target[pos++] = 0x03B9;
2886                break;
2887
2888            case 0x1F9B:
2889                target[pos++] = 0x1F23;
2890                target[pos++] = 0x03B9;
2891                break;
2892
2893            case 0x1F9C:
2894                target[pos++] = 0x1F24;
2895                target[pos++] = 0x03B9;
2896                break;
2897
2898            case 0x1F9D:
2899                target[pos++] = 0x1F25;
2900                target[pos++] = 0x03B9;
2901                break;
2902
2903            case 0x1F9E:
2904                target[pos++] = 0x1F26;
2905                target[pos++] = 0x03B9;
2906                break;
2907
2908            case 0x1F9F:
2909                target[pos++] = 0x1F27;
2910                target[pos++] = 0x03B9;
2911                break;
2912
2913            case 0x1FA0:
2914                target[pos++] = 0x1F60;
2915                target[pos++] = 0x03B9;
2916                break;
2917
2918            case 0x1FA1:
2919                target[pos++] = 0x1F61;
2920                target[pos++] = 0x03B9;
2921                break;
2922
2923            case 0x1FA2:
2924                target[pos++] = 0x1F62;
2925                target[pos++] = 0x03B9;
2926                break;
2927
2928            case 0x1FA3:
2929                target[pos++] = 0x1F63;
2930                target[pos++] = 0x03B9;
2931                break;
2932
2933            case 0x1FA4:
2934                target[pos++] = 0x1F64;
2935                target[pos++] = 0x03B9;
2936                break;
2937
2938            case 0x1FA5:
2939                target[pos++] = 0x1F65;
2940                target[pos++] = 0x03B9;
2941                break;
2942
2943            case 0x1FA6:
2944                target[pos++] = 0x1F66;
2945                target[pos++] = 0x03B9;
2946                break;
2947
2948            case 0x1FA7:
2949                target[pos++] = 0x1F67;
2950                target[pos++] = 0x03B9;
2951                break;
2952
2953            case 0x1FA8:
2954                target[pos++] = 0x1F60;
2955                target[pos++] = 0x03B9;
2956                break;
2957
2958            case 0x1FA9:
2959                target[pos++] = 0x1F61;
2960                target[pos++] = 0x03B9;
2961                break;
2962
2963            case 0x1FAA:
2964                target[pos++] = 0x1F62;
2965                target[pos++] = 0x03B9;
2966                break;
2967
2968            case 0x1FAB:
2969                target[pos++] = 0x1F63;
2970                target[pos++] = 0x03B9;
2971                break;
2972
2973            case 0x1FAC:
2974                target[pos++] = 0x1F64;
2975                target[pos++] = 0x03B9;
2976                break;
2977
2978            case 0x1FAD:
2979                target[pos++] = 0x1F65;
2980                target[pos++] = 0x03B9;
2981                break;
2982
2983            case 0x1FAE:
2984                target[pos++] = 0x1F66;
2985                target[pos++] = 0x03B9;
2986                break;
2987
2988            case 0x1FAF:
2989                target[pos++] = 0x1F67;
2990                target[pos++] = 0x03B9;
2991                break;
2992
2993            case 0x1FB2:
2994                target[pos++] = 0x1F70;
2995                target[pos++] = 0x03B9;
2996                break;
2997
2998            case 0x1FB3:
2999                target[pos++] = 0x03B1;
3000                target[pos++] = 0x03B9;
3001                break;
3002
3003            case 0x1FB4:
3004                target[pos++] = 0x03AC;
3005                target[pos++] = 0x03B9;
3006                break;
3007
3008            case 0x1FB6:
3009                target[pos++] = 0x03B1;
3010                target[pos++] = 0x0342;
3011                break;
3012
3013            case 0x1FB7:
3014                target[pos++] = 0x03B1;
3015                target[pos++] = 0x0342;
3016                target[pos++] = 0x03B9;
3017                break;
3018
3019            case 0x1FB8:
3020                target[pos++] = 0x1FB0;
3021                break;
3022
3023            case 0x1FB9:
3024                target[pos++] = 0x1FB1;
3025                break;
3026
3027            case 0x1FBA:
3028                target[pos++] = 0x1F70;
3029                break;
3030
3031            case 0x1FBB:
3032                target[pos++] = 0x1F71;
3033                break;
3034
3035            case 0x1FBC:
3036                target[pos++] = 0x03B1;
3037                target[pos++] = 0x03B9;
3038                break;
3039
3040            case 0x1FBE:
3041                target[pos++] = 0x03B9;
3042                break;
3043
3044            case 0x1FC2:
3045                target[pos++] = 0x1F74;
3046                target[pos++] = 0x03B9;
3047                break;
3048
3049            case 0x1FC3:
3050                target[pos++] = 0x03B7;
3051                target[pos++] = 0x03B9;
3052                break;
3053
3054            case 0x1FC4:
3055                target[pos++] = 0x03AE;
3056                target[pos++] = 0x03B9;
3057                break;
3058
3059            case 0x1FC6:
3060                target[pos++] = 0x03B7;
3061                target[pos++] = 0x0342;
3062                break;
3063
3064            case 0x1FC7:
3065                target[pos++] = 0x03B7;
3066                target[pos++] = 0x0342;
3067                target[pos++] = 0x03B9;
3068                break;
3069
3070            case 0x1FC8:
3071                target[pos++] = 0x1F72;
3072                break;
3073
3074            case 0x1FC9:
3075                target[pos++] = 0x1F73;
3076                break;
3077
3078            case 0x1FCA:
3079                target[pos++] = 0x1F74;
3080                break;
3081
3082            case 0x1FCB:
3083                target[pos++] = 0x1F75;
3084                break;
3085
3086            case 0x1FCC:
3087                target[pos++] = 0x03B7;
3088                target[pos++] = 0x03B9;
3089                break;
3090
3091            case 0x1FD2:
3092                target[pos++] = 0x03B9;
3093                target[pos++] = 0x0308;
3094                target[pos++] = 0x0300;
3095                break;
3096
3097            case 0x1FD3:
3098                target[pos++] = 0x03B9;
3099                target[pos++] = 0x0308;
3100                target[pos++] = 0x0301;
3101                break;
3102
3103            case 0x1FD6:
3104                target[pos++] = 0x03B9;
3105                target[pos++] = 0x0342;
3106                break;
3107
3108            case 0x1FD7:
3109                target[pos++] = 0x03B9;
3110                target[pos++] = 0x0308;
3111                target[pos++] = 0x0342;
3112                break;
3113
3114            case 0x1FD8:
3115                target[pos++] = 0x1FD0;
3116                break;
3117
3118            case 0x1FD9:
3119                target[pos++] = 0x1FD1;
3120                break;
3121
3122            case 0x1FDA:
3123                target[pos++] = 0x1F76;
3124                break;
3125
3126            case 0x1FDB:
3127                target[pos++] = 0x1F77;
3128                break;
3129
3130            case 0x1FE2:
3131                target[pos++] = 0x03C5;
3132                target[pos++] = 0x0308;
3133                target[pos++] = 0x0300;
3134                break;
3135
3136            case 0x1FE3:
3137                target[pos++] = 0x03C5;
3138                target[pos++] = 0x0308;
3139                target[pos++] = 0x0301;
3140                break;
3141
3142            case 0x1FE4:
3143                target[pos++] = 0x03C1;
3144                target[pos++] = 0x0313;
3145                break;
3146
3147            case 0x1FE6:
3148                target[pos++] = 0x03C5;
3149                target[pos++] = 0x0342;
3150                break;
3151
3152            case 0x1FE7:
3153                target[pos++] = 0x03C5;
3154                target[pos++] = 0x0308;
3155                target[pos++] = 0x0342;
3156                break;
3157
3158            case 0x1FE8:
3159                target[pos++] = 0x1FE0;
3160                break;
3161
3162            case 0x1FE9:
3163                target[pos++] = 0x1FE1;
3164                break;
3165
3166            case 0x1FEA:
3167                target[pos++] = 0x1F7A;
3168                break;
3169
3170            case 0x1FEB:
3171                target[pos++] = 0x1F7B;
3172                break;
3173
3174            case 0x1FEC:
3175                target[pos++] = 0x1FE5;
3176                break;
3177
3178            case 0x1FF2:
3179                target[pos++] = 0x1F7C;
3180                target[pos++] = 0x03B9;
3181                break;
3182
3183            case 0x1FF3:
3184                target[pos++] = 0x03C9;
3185                target[pos++] = 0x03B9;
3186                break;
3187
3188            case 0x1FF4:
3189                target[pos++] = 0x03CE;
3190                target[pos++] = 0x03B9;
3191                break;
3192
3193            case 0x1FF6:
3194                target[pos++] = 0x03C9;
3195                target[pos++] = 0x0342;
3196                break;
3197
3198            case 0x1FF7:
3199                target[pos++] = 0x03C9;
3200                target[pos++] = 0x0342;
3201                target[pos++] = 0x03B9;
3202                break;
3203
3204            case 0x1FF8:
3205                target[pos++] = 0x1F78;
3206                break;
3207
3208            case 0x1FF9:
3209                target[pos++] = 0x1F79;
3210                break;
3211
3212            case 0x1FFA:
3213                target[pos++] = 0x1F7C;
3214                break;
3215
3216            case 0x1FFB:
3217                target[pos++] = 0x1F7D;
3218                break;
3219
3220            case 0x1FFC:
3221                target[pos++] = 0x03C9;
3222                target[pos++] = 0x03B9;
3223                break;
3224
3225            case 0x2000:
3226            case 0x2001:
3227            case 0x2002:
3228            case 0x2003:
3229            case 0x2004:
3230            case 0x2005:
3231            case 0x2006:
3232            case 0x2007:
3233            case 0x2008:
3234            case 0x2009:
3235            case 0x200A:
3236                target[pos++] = 0x0020;
3237                break;
3238
3239            case 0x200B:
3240            case 0x200C:
3241            case 0x200D:
3242            case 0x200E:
3243            case 0x200F:
3244                break;
3245
3246            case 0x2028:
3247            case 0x2029:
3248                target[pos++] = 0x0020;
3249                break;
3250
3251            case 0x202A:
3252            case 0x202B:
3253            case 0x202C:
3254            case 0x202D:
3255            case 0x202E:
3256                break;
3257
3258            case 0x202F:
3259                target[pos++] = 0x0020;
3260                break;
3261
3262            case 0x205F:
3263                target[pos++] = 0x0020;
3264                break;
3265
3266            case 0x2060:
3267            case 0x2061:
3268            case 0x2062:
3269            case 0x2063:
3270                break;
3271
3272            case 0x206A:
3273            case 0x206B:
3274            case 0x206C:
3275            case 0x206D:
3276            case 0x206E:
3277            case 0x206F:
3278                break;
3279
3280            case 0x20A8:
3281                target[pos++] = 0x0072;
3282                target[pos++] = 0x0073;
3283                break;
3284
3285            case 0x2102:
3286                target[pos++] = 0x0063;
3287                break;
3288
3289            case 0x2103:
3290                target[pos++] = 0x00B0;
3291                target[pos++] = 0x0063;
3292                break;
3293
3294            case 0x2107:
3295                target[pos++] = 0x025B;
3296                break;
3297
3298            case 0x2109:
3299                target[pos++] = 0x00B0;
3300                target[pos++] = 0x0066;
3301                break;
3302
3303            case 0x210B:
3304                target[pos++] = 0x0068;
3305                break;
3306
3307            case 0x210C:
3308                target[pos++] = 0x0068;
3309                break;
3310
3311            case 0x210D:
3312                target[pos++] = 0x0068;
3313                break;
3314
3315            case 0x2110:
3316                target[pos++] = 0x0069;
3317                break;
3318
3319            case 0x2111:
3320                target[pos++] = 0x0069;
3321                break;
3322
3323            case 0x2112:
3324                target[pos++] = 0x006C;
3325                break;
3326
3327            case 0x2115:
3328                target[pos++] = 0x006E;
3329                break;
3330
3331            case 0x2116:
3332                target[pos++] = 0x006E;
3333                target[pos++] = 0x006F;
3334                break;
3335
3336            case 0x2119:
3337                target[pos++] = 0x0070;
3338                break;
3339
3340            case 0x211A:
3341                target[pos++] = 0x0071;
3342                break;
3343
3344            case 0x211B:
3345                target[pos++] = 0x0072;
3346                break;
3347
3348            case 0x211C:
3349                target[pos++] = 0x0072;
3350                break;
3351
3352            case 0x211D:
3353                target[pos++] = 0x0072;
3354                break;
3355
3356            case 0x2120:
3357                target[pos++] = 0x0073;
3358                target[pos++] = 0x006D;
3359                break;
3360
3361            case 0x2121:
3362                target[pos++] = 0x0074;
3363                target[pos++] = 0x0065;
3364                target[pos++] = 0x006C;
3365                break;
3366
3367            case 0x2122:
3368                target[pos++] = 0x0074;
3369                target[pos++] = 0x006D;
3370                break;
3371
3372            case 0x2124:
3373                target[pos++] = 0x007A;
3374                break;
3375
3376            case 0x2126:
3377                target[pos++] = 0x03C9;
3378                break;
3379
3380            case 0x2128:
3381                target[pos++] = 0x007A;
3382                break;
3383
3384            case 0x212A:
3385                target[pos++] = 0x006B;
3386                break;
3387
3388            case 0x212B:
3389                target[pos++] = 0x00E5;
3390                break;
3391
3392            case 0x212C:
3393                target[pos++] = 0x0062;
3394                break;
3395
3396            case 0x212D:
3397                target[pos++] = 0x0063;
3398                break;
3399
3400            case 0x2130:
3401                target[pos++] = 0x0065;
3402                break;
3403
3404            case 0x2131:
3405                target[pos++] = 0x0066;
3406                break;
3407
3408            case 0x2133:
3409                target[pos++] = 0x006D;
3410                break;
3411
3412            case 0x213E:
3413                target[pos++] = 0x03B3;
3414                break;
3415
3416            case 0x213F:
3417                target[pos++] = 0x03C0;
3418                break;
3419
3420            case 0x2145:
3421                target[pos++] = 0x0064;
3422                break;
3423
3424            case 0x2160:
3425                target[pos++] = 0x2170;
3426                break;
3427
3428            case 0x2161:
3429                target[pos++] = 0x2171;
3430                break;
3431
3432            case 0x2162:
3433                target[pos++] = 0x2172;
3434                break;
3435
3436            case 0x2163:
3437                target[pos++] = 0x2173;
3438                break;
3439
3440            case 0x2164:
3441                target[pos++] = 0x2174;
3442                break;
3443
3444            case 0x2165:
3445                target[pos++] = 0x2175;
3446                break;
3447
3448            case 0x2166:
3449                target[pos++] = 0x2176;
3450                break;
3451
3452            case 0x2167:
3453                target[pos++] = 0x2177;
3454                break;
3455
3456            case 0x2168:
3457                target[pos++] = 0x2178;
3458                break;
3459
3460            case 0x2169:
3461                target[pos++] = 0x2179;
3462                break;
3463
3464            case 0x216A:
3465                target[pos++] = 0x217A;
3466                break;
3467
3468            case 0x216B:
3469                target[pos++] = 0x217B;
3470                break;
3471
3472            case 0x216C:
3473                target[pos++] = 0x217C;
3474                break;
3475
3476            case 0x216D:
3477                target[pos++] = 0x217D;
3478                break;
3479
3480            case 0x216E:
3481                target[pos++] = 0x217E;
3482                break;
3483
3484            case 0x216F:
3485                target[pos++] = 0x217F;
3486                break;
3487
3488            case 0x24B6:
3489                target[pos++] = 0x24D0;
3490                break;
3491
3492            case 0x24B7:
3493                target[pos++] = 0x24D1;
3494                break;
3495
3496            case 0x24B8:
3497                target[pos++] = 0x24D2;
3498                break;
3499
3500            case 0x24B9:
3501                target[pos++] = 0x24D3;
3502                break;
3503
3504            case 0x24BA:
3505                target[pos++] = 0x24D4;
3506                break;
3507
3508            case 0x24BB:
3509                target[pos++] = 0x24D5;
3510                break;
3511
3512            case 0x24BC:
3513                target[pos++] = 0x24D6;
3514                break;
3515
3516            case 0x24BD:
3517                target[pos++] = 0x24D7;
3518                break;
3519
3520            case 0x24BE:
3521                target[pos++] = 0x24D8;
3522                break;
3523
3524            case 0x24BF:
3525                target[pos++] = 0x24D9;
3526                break;
3527
3528            case 0x24C0:
3529                target[pos++] = 0x24DA;
3530                break;
3531
3532            case 0x24C1:
3533                target[pos++] = 0x24DB;
3534                break;
3535
3536            case 0x24C2:
3537                target[pos++] = 0x24DC;
3538                break;
3539
3540            case 0x24C3:
3541                target[pos++] = 0x24DD;
3542                break;
3543
3544            case 0x24C4:
3545                target[pos++] = 0x24DE;
3546                break;
3547
3548            case 0x24C5:
3549                target[pos++] = 0x24DF;
3550                break;
3551
3552            case 0x24C6:
3553                target[pos++] = 0x24E0;
3554                break;
3555
3556            case 0x24C7:
3557                target[pos++] = 0x24E1;
3558                break;
3559
3560            case 0x24C8:
3561                target[pos++] = 0x24E2;
3562                break;
3563
3564            case 0x24C9:
3565                target[pos++] = 0x24E3;
3566                break;
3567
3568            case 0x24CA:
3569                target[pos++] = 0x24E4;
3570                break;
3571
3572            case 0x24CB:
3573                target[pos++] = 0x24E5;
3574                break;
3575
3576            case 0x24CC:
3577                target[pos++] = 0x24E6;
3578                break;
3579
3580            case 0x24CD:
3581                target[pos++] = 0x24E7;
3582                break;
3583
3584            case 0x24CE:
3585                target[pos++] = 0x24E8;
3586                break;
3587
3588            case 0x24CF:
3589                target[pos++] = 0x24E9;
3590                break;
3591
3592            case 0x3000:
3593                target[pos++] = 0x0020;
3594                break;
3595
3596            case 0x3371:
3597                target[pos++] = 0x0068;
3598                target[pos++] = 0x0070;
3599                target[pos++] = 0x0061;
3600                break;
3601
3602            case 0x3373:
3603                target[pos++] = 0x0061;
3604                target[pos++] = 0x0075;
3605                break;
3606
3607            case 0x3375:
3608                target[pos++] = 0x006F;
3609                target[pos++] = 0x0076;
3610                break;
3611
3612            case 0x3380:
3613                target[pos++] = 0x0070;
3614                target[pos++] = 0x0061;
3615                break;
3616
3617            case 0x3381:
3618                target[pos++] = 0x006E;
3619                target[pos++] = 0x0061;
3620                break;
3621
3622            case 0x3382:
3623                target[pos++] = 0x03BC;
3624                target[pos++] = 0x0061;
3625                break;
3626
3627            case 0x3383:
3628                target[pos++] = 0x006D;
3629                target[pos++] = 0x0061;
3630                break;
3631
3632            case 0x3384:
3633                target[pos++] = 0x006B;
3634                target[pos++] = 0x0061;
3635                break;
3636
3637            case 0x3385:
3638                target[pos++] = 0x006B;
3639                target[pos++] = 0x0062;
3640                break;
3641
3642            case 0x3386:
3643                target[pos++] = 0x006D;
3644                target[pos++] = 0x0062;
3645                break;
3646
3647            case 0x3387:
3648                target[pos++] = 0x0067;
3649                target[pos++] = 0x0062;
3650                break;
3651
3652            case 0x338A:
3653                target[pos++] = 0x0070;
3654                target[pos++] = 0x0066;
3655                break;
3656
3657            case 0x338B:
3658                target[pos++] = 0x006E;
3659                target[pos++] = 0x0066;
3660                break;
3661
3662            case 0x338C:
3663                target[pos++] = 0x03BC;
3664                target[pos++] = 0x0066;
3665                break;
3666
3667            case 0x3390:
3668                target[pos++] = 0x0068;
3669                target[pos++] = 0x007A;
3670                break;
3671
3672            case 0x3391:
3673                target[pos++] = 0x006B;
3674                target[pos++] = 0x0068;
3675                target[pos++] = 0x007A;
3676                break;
3677
3678            case 0x3392:
3679                target[pos++] = 0x006D;
3680                target[pos++] = 0x0068;
3681                target[pos++] = 0x007A;
3682                break;
3683
3684            case 0x3393:
3685                target[pos++] = 0x0067;
3686                target[pos++] = 0x0068;
3687                target[pos++] = 0x007A;
3688                break;
3689
3690            case 0x3394:
3691                target[pos++] = 0x0074;
3692                target[pos++] = 0x0068;
3693                target[pos++] = 0x007A;
3694                break;
3695
3696            case 0x33A9:
3697                target[pos++] = 0x0070;
3698                target[pos++] = 0x0061;
3699                break;
3700
3701            case 0x33AA:
3702                target[pos++] = 0x006B;
3703                target[pos++] = 0x0070;
3704                target[pos++] = 0x0061;
3705                break;
3706
3707            case 0x33AB:
3708                target[pos++] = 0x006D;
3709                target[pos++] = 0x0070;
3710                target[pos++] = 0x0061;
3711                break;
3712
3713            case 0x33AC:
3714                target[pos++] = 0x0067;
3715                target[pos++] = 0x0070;
3716                target[pos++] = 0x0061;
3717                break;
3718
3719            case 0x33B4:
3720                target[pos++] = 0x0070;
3721                target[pos++] = 0x0076;
3722                break;
3723
3724            case 0x33B5:
3725                target[pos++] = 0x006E;
3726                target[pos++] = 0x0076;
3727                break;
3728
3729            case 0x33B6:
3730                target[pos++] = 0x03BC;
3731                target[pos++] = 0x0076;
3732                break;
3733
3734            case 0x33B7:
3735                target[pos++] = 0x006D;
3736                target[pos++] = 0x0076;
3737                break;
3738
3739            case 0x33B8:
3740                target[pos++] = 0x006B;
3741                target[pos++] = 0x0076;
3742                break;
3743
3744            case 0x33B9:
3745                target[pos++] = 0x006D;
3746                target[pos++] = 0x0076;
3747                break;
3748
3749            case 0x33BA:
3750                target[pos++] = 0x0070;
3751                target[pos++] = 0x0077;
3752                break;
3753
3754            case 0x33BB:
3755                target[pos++] = 0x006E;
3756                target[pos++] = 0x0077;
3757                break;
3758
3759            case 0x33BC:
3760                target[pos++] = 0x03BC;
3761                target[pos++] = 0x0077;
3762                break;
3763
3764            case 0x33BD:
3765                target[pos++] = 0x006D;
3766                target[pos++] = 0x0077;
3767                break;
3768
3769            case 0x33BE:
3770                target[pos++] = 0x006B;
3771                target[pos++] = 0x0077;
3772                break;
3773
3774            case 0x33BF:
3775                target[pos++] = 0x006D;
3776                target[pos++] = 0x0077;
3777                break;
3778
3779            case 0x33C0:
3780                target[pos++] = 0x006B;
3781                target[pos++] = 0x03C9;
3782                break;
3783
3784            case 0x33C1:
3785                target[pos++] = 0x006D;
3786                target[pos++] = 0x03C9;
3787                break;
3788
3789            case 0x33C3:
3790                target[pos++] = 0x0062;
3791                target[pos++] = 0x0071;
3792                break;
3793
3794            case 0x33C6:
3795                target[pos++] = 0x0063;
3796                target[pos++] = 0x2215;
3797                target[pos++] = 0x006B;
3798                target[pos++] = 0x0067;
3799                break;
3800
3801            case 0x33C7:
3802                target[pos++] = 0x0063;
3803                target[pos++] = 0x006F;
3804                target[pos++] = 0x002E;
3805                break;
3806
3807            case 0x33C8:
3808                target[pos++] = 0x0064;
3809                target[pos++] = 0x0062;
3810                break;
3811
3812            case 0x33C9:
3813                target[pos++] = 0x0067;
3814                target[pos++] = 0x0079;
3815                break;
3816
3817            case 0x33CB:
3818                target[pos++] = 0x0068;
3819                target[pos++] = 0x0070;
3820                break;
3821
3822            case 0x33CD:
3823                target[pos++] = 0x006B;
3824                target[pos++] = 0x006B;
3825                break;
3826
3827            case 0x33CE:
3828                target[pos++] = 0x006B;
3829                target[pos++] = 0x006D;
3830                break;
3831
3832            case 0x33D7:
3833                target[pos++] = 0x0070;
3834                target[pos++] = 0x0068;
3835                break;
3836
3837            case 0x33D9:
3838                target[pos++] = 0x0070;
3839                target[pos++] = 0x0070;
3840                target[pos++] = 0x006D;
3841                break;
3842
3843            case 0x33DA:
3844                target[pos++] = 0x0070;
3845                target[pos++] = 0x0072;
3846                break;
3847
3848            case 0x33DC:
3849                target[pos++] = 0x0073;
3850                target[pos++] = 0x0076;
3851                break;
3852
3853            case 0x33DD:
3854                target[pos++] = 0x0077;
3855                target[pos++] = 0x0062;
3856                break;
3857
3858            case 0xFB00:
3859                target[pos++] = 0x0066;
3860                target[pos++] = 0x0066;
3861                break;
3862
3863            case 0xFB01:
3864                target[pos++] = 0x0066;
3865                target[pos++] = 0x0069;
3866                break;
3867
3868            case 0xFB02:
3869                target[pos++] = 0x0066;
3870                target[pos++] = 0x006C;
3871                break;
3872
3873            case 0xFB03:
3874                target[pos++] = 0x0066;
3875                target[pos++] = 0x0066;
3876                target[pos++] = 0x0069;
3877                break;
3878
3879            case 0xFB04:
3880                target[pos++] = 0x0066;
3881                target[pos++] = 0x0066;
3882                target[pos++] = 0x006C;
3883                break;
3884
3885            case 0xFB05:
3886                target[pos++] = 0x0073;
3887                target[pos++] = 0x0074;
3888                break;
3889
3890            case 0xFB06:
3891                target[pos++] = 0x0073;
3892                target[pos++] = 0x0074;
3893                break;
3894
3895            case 0xFB13:
3896                target[pos++] = 0x0574;
3897                target[pos++] = 0x0576;
3898                break;
3899
3900            case 0xFB14:
3901                target[pos++] = 0x0574;
3902                target[pos++] = 0x0565;
3903                break;
3904
3905            case 0xFB15:
3906                target[pos++] = 0x0574;
3907                target[pos++] = 0x056B;
3908                break;
3909
3910            case 0xFB16:
3911                target[pos++] = 0x057E;
3912                target[pos++] = 0x0576;
3913                break;
3914
3915            case 0xFB17:
3916                target[pos++] = 0x0574;
3917                target[pos++] = 0x056D;
3918                break;
3919
3920            case 0xFE00:
3921            case 0xFE01:
3922            case 0xFE02:
3923            case 0xFE03:
3924            case 0xFE04:
3925            case 0xFE05:
3926            case 0xFE06:
3927            case 0xFE07:
3928            case 0xFE08:
3929            case 0xFE09:
3930            case 0xFE0A:
3931            case 0xFE0B:
3932            case 0xFE0C:
3933            case 0xFE0D:
3934            case 0xFE0E:
3935            case 0xFE0F:
3936                break;
3937
3938            case 0xFEFF:
3939                break;
3940
3941            case 0xFF21:
3942                target[pos++] = 0xFF41;
3943                break;
3944
3945            case 0xFF22:
3946                target[pos++] = 0xFF42;
3947                break;
3948
3949            case 0xFF23:
3950                target[pos++] = 0xFF43;
3951                break;
3952
3953            case 0xFF24:
3954                target[pos++] = 0xFF44;
3955                break;
3956
3957            case 0xFF25:
3958                target[pos++] = 0xFF45;
3959                break;
3960
3961            case 0xFF26:
3962                target[pos++] = 0xFF46;
3963                break;
3964
3965            case 0xFF27:
3966                target[pos++] = 0xFF47;
3967                break;
3968
3969            case 0xFF28:
3970                target[pos++] = 0xFF48;
3971                break;
3972
3973            case 0xFF29:
3974                target[pos++] = 0xFF49;
3975                break;
3976
3977            case 0xFF2A:
3978                target[pos++] = 0xFF4A;
3979                break;
3980
3981            case 0xFF2B:
3982                target[pos++] = 0xFF4B;
3983                break;
3984
3985            case 0xFF2C:
3986                target[pos++] = 0xFF4C;
3987                break;
3988
3989            case 0xFF2D:
3990                target[pos++] = 0xFF4D;
3991                break;
3992
3993            case 0xFF2E:
3994                target[pos++] = 0xFF4E;
3995                break;
3996
3997            case 0xFF2F:
3998                target[pos++] = 0xFF4F;
3999                break;
4000
4001            case 0xFF30:
4002                target[pos++] = 0xFF50;
4003                break;
4004
4005            case 0xFF31:
4006                target[pos++] = 0xFF51;
4007                break;
4008
4009            case 0xFF32:
4010                target[pos++] = 0xFF52;
4011                break;
4012
4013            case 0xFF33:
4014                target[pos++] = 0xFF53;
4015                break;
4016
4017            case 0xFF34:
4018                target[pos++] = 0xFF54;
4019                break;
4020
4021            case 0xFF35:
4022                target[pos++] = 0xFF55;
4023                break;
4024
4025            case 0xFF36:
4026                target[pos++] = 0xFF56;
4027                break;
4028
4029            case 0xFF37:
4030                target[pos++] = 0xFF57;
4031                break;
4032
4033            case 0xFF38:
4034                target[pos++] = 0xFF58;
4035                break;
4036
4037            case 0xFF39:
4038                target[pos++] = 0xFF59;
4039                break;
4040
4041            case 0xFF3A:
4042                target[pos++] = 0xFF5A;
4043                break;
4044
4045            case 0xFFF9:
4046            case 0xFFFA:
4047            case 0xFFFB:
4048            case 0xFFFC:
4049                break;
4050
4051            default:
4052                // First, eliminate surrogates, and replace them by FFFD char
4053                if ( ( c >= 0xD800 ) && ( c <= 0xDFFF ) )
4054                {
4055                    target[pos++] = ( char ) 0xFFFD;
4056                    break;
4057                }
4058
4059                target[pos++] = c;
4060                break;
4061        }
4062
4063        return pos - start;
4064    }
4065
4066
4067    /**
4068     * 
4069     * Prohibit characters described in RFC 4518 :
4070     *  - Table A.1 of RFC 3454
4071     *  - Table C.3 of RFC 3454
4072     *  - Table C.4 of RFC 3454
4073     *  - Table C.5 of RFC 3454
4074     *  - Table C.8 of RFC 3454
4075     *  - character U-FFFD
4076     *
4077     * @param c The char to analyze
4078     * @throws InvalidCharacterException If any character is prohibited
4079     */
4080    private static void checkProhibited( char c ) throws InvalidCharacterException
4081    {
4082        // Shortcut chars above 0x0221
4083        if ( c < 0x221 )
4084        {
4085            return;
4086        }
4087
4088        // RFC 3454, Table A.1
4089        switch ( c )
4090        {
4091            case 0x0221:
4092            case 0x038B:
4093            case 0x038D:
4094            case 0x03A2:
4095            case 0x03CF:
4096            case 0x0487:
4097            case 0x04CF:
4098            case 0x0560:
4099            case 0x0588:
4100            case 0x05A2:
4101            case 0x05BA:
4102            case 0x0620:
4103            case 0x06FF:
4104            case 0x070E:
4105            case 0x0904:
4106            case 0x0984:
4107            case 0x09A9:
4108            case 0x09B1:
4109            case 0x09BD:
4110            case 0x09DE:
4111            case 0x0A29:
4112            case 0x0A31:
4113            case 0x0A34:
4114            case 0x0A37:
4115            case 0x0A3D:
4116            case 0x0A5D:
4117            case 0x0A84:
4118            case 0x0A8C:
4119            case 0x0A8E:
4120            case 0x0A92:
4121            case 0x0AA9:
4122            case 0x0AB1:
4123            case 0x0AB4:
4124            case 0x0AC6:
4125            case 0x0ACA:
4126            case 0x0B04:
4127            case 0x0B29:
4128            case 0x0B31:
4129            case 0x0B5E:
4130            case 0x0B84:
4131            case 0x0B91:
4132            case 0x0B9B:
4133            case 0x0B9D:
4134            case 0x0BB6:
4135            case 0x0BC9:
4136            case 0x0C04:
4137            case 0x0C0D:
4138            case 0x0C11:
4139            case 0x0C29:
4140            case 0x0C34:
4141            case 0x0C45:
4142            case 0x0C49:
4143            case 0x0C84:
4144            case 0x0C8D:
4145            case 0x0C91:
4146            case 0x0CA9:
4147            case 0x0CB4:
4148            case 0x0CC5:
4149            case 0x0CC9:
4150            case 0x0CDF:
4151            case 0x0D04:
4152            case 0x0D0D:
4153            case 0x0D11:
4154            case 0x0D29:
4155            case 0x0D49:
4156            case 0x0D84:
4157            case 0x0DB2:
4158            case 0x0DBC:
4159            case 0x0DD5:
4160            case 0x0DD7:
4161            case 0x0E83:
4162            case 0x0E89:
4163            case 0x0E98:
4164            case 0x0EA0:
4165            case 0x0EA4:
4166            case 0x0EA6:
4167            case 0x0EAC:
4168            case 0x0EBA:
4169            case 0x0EC5:
4170            case 0x0EC7:
4171            case 0x0F48:
4172            case 0x0F98:
4173            case 0x0FBD:
4174            case 0x1022:
4175            case 0x1028:
4176            case 0x102B:
4177            case 0x1207:
4178            case 0x1247:
4179            case 0x1249:
4180            case 0x1257:
4181            case 0x1259:
4182            case 0x1287:
4183            case 0x1289:
4184            case 0x12AF:
4185            case 0x12B1:
4186            case 0x12BF:
4187            case 0x12C1:
4188            case 0x12CF:
4189            case 0x12D7:
4190            case 0x12EF:
4191            case 0x130F:
4192            case 0x1311:
4193            case 0x131F:
4194            case 0x1347:
4195            case 0x170D:
4196            case 0x176D:
4197            case 0x1771:
4198            case 0x180F:
4199            case 0x1F58:
4200            case 0x1F5A:
4201            case 0x1F5C:
4202            case 0x1F5E:
4203            case 0x1FB5:
4204            case 0x1FC5:
4205            case 0x1FDC:
4206            case 0x1FF5:
4207            case 0x1FFF:
4208            case 0x24FF:
4209            case 0x2618:
4210            case 0x2705:
4211            case 0x2728:
4212            case 0x274C:
4213            case 0x274E:
4214            case 0x2757:
4215            case 0x27B0:
4216            case 0x2E9A:
4217            case 0x3040:
4218            case 0x318F:
4219            case 0x32FF:
4220            case 0x33FF:
4221            case 0xFB37:
4222            case 0xFB3D:
4223            case 0xFB3F:
4224            case 0xFB42:
4225            case 0xFB45:
4226            case 0xFE53:
4227            case 0xFE67:
4228            case 0xFE75:
4229            case 0xFF00:
4230            case 0xFFE7:
4231                throw new InvalidCharacterException( c );
4232            default:
4233                break;
4234        }
4235
4236        // RFC 3454, Table A.1, intervals
4237        if ( ( c >= 0x0234 ) && ( c <= 0x024F ) )
4238        {
4239            throw new InvalidCharacterException( c );
4240        }
4241
4242        if ( ( c >= 0x02AE ) && ( c <= 0x02AF ) )
4243        {
4244            throw new InvalidCharacterException( c );
4245        }
4246
4247        if ( ( c >= 0x02EF ) && ( c <= 0x02FF ) )
4248        {
4249            throw new InvalidCharacterException( c );
4250        }
4251
4252        if ( ( c >= 0x0350 ) && ( c <= 0x035F ) )
4253        {
4254            throw new InvalidCharacterException( c );
4255        }
4256
4257        if ( ( c >= 0x0370 ) && ( c <= 0x0373 ) )
4258        {
4259            throw new InvalidCharacterException( c );
4260        }
4261
4262        if ( ( c >= 0x0376 ) && ( c <= 0x0379 ) )
4263        {
4264            throw new InvalidCharacterException( c );
4265        }
4266
4267        if ( ( c >= 0x037B ) && ( c <= 0x037D ) )
4268        {
4269            throw new InvalidCharacterException( c );
4270        }
4271
4272        if ( ( c >= 0x037F ) && ( c <= 0x0383 ) )
4273        {
4274            throw new InvalidCharacterException( c );
4275        }
4276
4277        if ( ( c >= 0x03F7 ) && ( c <= 0x03FF ) )
4278        {
4279            throw new InvalidCharacterException( c );
4280        }
4281
4282        if ( ( c >= 0x04F6 ) && ( c <= 0x04F7 ) )
4283        {
4284            throw new InvalidCharacterException( c );
4285        }
4286
4287        if ( ( c >= 0x04FA ) && ( c <= 0x04FF ) )
4288        {
4289            throw new InvalidCharacterException( c );
4290        }
4291
4292        if ( ( c >= 0x0510 ) && ( c <= 0x0530 ) )
4293        {
4294            throw new InvalidCharacterException( c );
4295        }
4296
4297        if ( ( c >= 0x0557 ) && ( c <= 0x0558 ) )
4298        {
4299            throw new InvalidCharacterException( c );
4300        }
4301
4302        if ( ( c >= 0x058B ) && ( c <= 0x0590 ) )
4303        {
4304            throw new InvalidCharacterException( c );
4305        }
4306
4307        if ( ( c >= 0x05C5 ) && ( c <= 0x05CF ) )
4308        {
4309            throw new InvalidCharacterException( c );
4310        }
4311
4312        if ( ( c >= 0x05EB ) && ( c <= 0x05EF ) )
4313        {
4314            throw new InvalidCharacterException( c );
4315        }
4316
4317        if ( ( c >= 0x05F5 ) && ( c <= 0x060B ) )
4318        {
4319            throw new InvalidCharacterException( c );
4320        }
4321
4322        if ( ( c >= 0x060D ) && ( c <= 0x061A ) )
4323        {
4324            throw new InvalidCharacterException( c );
4325        }
4326
4327        if ( ( c >= 0x061C ) && ( c <= 0x061E ) )
4328        {
4329            throw new InvalidCharacterException( c );
4330        }
4331
4332        if ( ( c >= 0x063B ) && ( c <= 0x063F ) )
4333        {
4334            throw new InvalidCharacterException( c );
4335        }
4336
4337        if ( ( c >= 0x0656 ) && ( c <= 0x065F ) )
4338        {
4339            throw new InvalidCharacterException( c );
4340        }
4341
4342        if ( ( c >= 0x06EE ) && ( c <= 0x06EF ) )
4343        {
4344            throw new InvalidCharacterException( c );
4345        }
4346
4347        if ( ( c >= 0x072D ) && ( c <= 0x072F ) )
4348        {
4349            throw new InvalidCharacterException( c );
4350        }
4351
4352        if ( ( c >= 0x074B ) && ( c <= 0x077F ) )
4353        {
4354            throw new InvalidCharacterException( c );
4355        }
4356
4357        if ( ( c >= 0x07B2 ) && ( c <= 0x0900 ) )
4358        {
4359            throw new InvalidCharacterException( c );
4360        }
4361
4362        if ( ( c >= 0x093A ) && ( c <= 0x093B ) )
4363        {
4364            throw new InvalidCharacterException( c );
4365        }
4366
4367        if ( ( c >= 0x094E ) && ( c <= 0x094F ) )
4368        {
4369            throw new InvalidCharacterException( c );
4370        }
4371
4372        if ( ( c >= 0x0955 ) && ( c <= 0x0957 ) )
4373        {
4374            throw new InvalidCharacterException( c );
4375        }
4376
4377        if ( ( c >= 0x0971 ) && ( c <= 0x0980 ) )
4378        {
4379            throw new InvalidCharacterException( c );
4380        }
4381
4382        if ( ( c >= 0x098D ) && ( c <= 0x098E ) )
4383        {
4384            throw new InvalidCharacterException( c );
4385        }
4386
4387        if ( ( c >= 0x0991 ) && ( c <= 0x0992 ) )
4388        {
4389            throw new InvalidCharacterException( c );
4390        }
4391
4392        if ( ( c >= 0x09B3 ) && ( c <= 0x09B5 ) )
4393        {
4394            throw new InvalidCharacterException( c );
4395        }
4396
4397        if ( ( c >= 0x09BA ) && ( c <= 0x09BB ) )
4398        {
4399            throw new InvalidCharacterException( c );
4400        }
4401
4402        if ( ( c >= 0x09C5 ) && ( c <= 0x09C6 ) )
4403        {
4404            throw new InvalidCharacterException( c );
4405        }
4406
4407        if ( ( c >= 0x09C9 ) && ( c <= 0x09CA ) )
4408        {
4409            throw new InvalidCharacterException( c );
4410        }
4411
4412        if ( ( c >= 0x09CE ) && ( c <= 0x09D6 ) )
4413        {
4414            throw new InvalidCharacterException( c );
4415        }
4416
4417        if ( ( c >= 0x09D8 ) && ( c <= 0x09DB ) )
4418        {
4419            throw new InvalidCharacterException( c );
4420        }
4421
4422        if ( ( c >= 0x09E4 ) && ( c <= 0x09E5 ) )
4423        {
4424            throw new InvalidCharacterException( c );
4425        }
4426
4427        if ( ( c >= 0x09FB ) && ( c <= 0x0A01 ) )
4428        {
4429            throw new InvalidCharacterException( c );
4430        }
4431
4432        if ( ( c >= 0x0A03 ) && ( c <= 0x0A04 ) )
4433        {
4434            throw new InvalidCharacterException( c );
4435        }
4436
4437        if ( ( c >= 0x0A0B ) && ( c <= 0x0A0E ) )
4438        {
4439            throw new InvalidCharacterException( c );
4440        }
4441
4442        if ( ( c >= 0x0A11 ) && ( c <= 0x0A12 ) )
4443        {
4444            throw new InvalidCharacterException( c );
4445        }
4446
4447        if ( ( c >= 0x0A3A ) && ( c <= 0x0A3B ) )
4448        {
4449            throw new InvalidCharacterException( c );
4450        }
4451
4452        if ( ( c >= 0x0A43 ) && ( c <= 0x0A46 ) )
4453        {
4454            throw new InvalidCharacterException( c );
4455        }
4456
4457        if ( ( c >= 0x0A49 ) && ( c <= 0x0A4A ) )
4458        {
4459            throw new InvalidCharacterException( c );
4460        }
4461
4462        if ( ( c >= 0x0A4E ) && ( c <= 0x0A58 ) )
4463        {
4464            throw new InvalidCharacterException( c );
4465        }
4466
4467        if ( ( c >= 0x0A5F ) && ( c <= 0x0A65 ) )
4468        {
4469            throw new InvalidCharacterException( c );
4470        }
4471
4472        if ( ( c >= 0x0A75 ) && ( c <= 0x0A80 ) )
4473        {
4474            throw new InvalidCharacterException( c );
4475        }
4476
4477        if ( ( c >= 0x0ABA ) && ( c <= 0x0ABB ) )
4478        {
4479            throw new InvalidCharacterException( c );
4480        }
4481
4482        if ( ( c >= 0x0ACE ) && ( c <= 0x0ACF ) )
4483        {
4484            throw new InvalidCharacterException( c );
4485        }
4486
4487        if ( ( c >= 0x0AD1 ) && ( c <= 0x0ADF ) )
4488        {
4489            throw new InvalidCharacterException( c );
4490        }
4491
4492        if ( ( c >= 0x0AE1 ) && ( c <= 0x0AE5 ) )
4493        {
4494            throw new InvalidCharacterException( c );
4495        }
4496
4497        if ( ( c >= 0x0AF0 ) && ( c <= 0x0B00 ) )
4498        {
4499            throw new InvalidCharacterException( c );
4500        }
4501
4502        if ( ( c >= 0x0B0D ) && ( c <= 0x0B0E ) )
4503        {
4504            throw new InvalidCharacterException( c );
4505        }
4506
4507        if ( ( c >= 0x0B11 ) && ( c <= 0x0B12 ) )
4508        {
4509            throw new InvalidCharacterException( c );
4510        }
4511
4512        if ( ( c >= 0x0B34 ) && ( c <= 0x0B35 ) )
4513        {
4514            throw new InvalidCharacterException( c );
4515        }
4516
4517        if ( ( c >= 0x0B3A ) && ( c <= 0x0B3B ) )
4518        {
4519            throw new InvalidCharacterException( c );
4520        }
4521
4522        if ( ( c >= 0x0B44 ) && ( c <= 0x0B46 ) )
4523        {
4524            throw new InvalidCharacterException( c );
4525        }
4526
4527        if ( ( c >= 0x0B49 ) && ( c <= 0x0B4A ) )
4528        {
4529            throw new InvalidCharacterException( c );
4530        }
4531
4532        if ( ( c >= 0x0B4E ) && ( c <= 0x0B55 ) )
4533        {
4534            throw new InvalidCharacterException( c );
4535        }
4536
4537        if ( ( c >= 0x0B58 ) && ( c <= 0x0B5B ) )
4538        {
4539            throw new InvalidCharacterException( c );
4540        }
4541
4542        if ( ( c >= 0x0B62 ) && ( c <= 0x0B65 ) )
4543        {
4544            throw new InvalidCharacterException( c );
4545        }
4546
4547        if ( ( c >= 0x0B71 ) && ( c <= 0x0B81 ) )
4548        {
4549            throw new InvalidCharacterException( c );
4550        }
4551
4552        if ( ( c >= 0x0B8B ) && ( c <= 0x0B8D ) )
4553        {
4554            throw new InvalidCharacterException( c );
4555        }
4556
4557        if ( ( c >= 0x0B96 ) && ( c <= 0x0B98 ) )
4558        {
4559            throw new InvalidCharacterException( c );
4560        }
4561
4562        if ( ( c >= 0x0BA0 ) && ( c <= 0x0BA2 ) )
4563        {
4564            throw new InvalidCharacterException( c );
4565        }
4566
4567        if ( ( c >= 0x0BA5 ) && ( c <= 0x0BA7 ) )
4568        {
4569            throw new InvalidCharacterException( c );
4570        }
4571
4572        if ( ( c >= 0x0BAB ) && ( c <= 0x0BAD ) )
4573        {
4574            throw new InvalidCharacterException( c );
4575        }
4576
4577        if ( ( c >= 0x0BBA ) && ( c <= 0x0BBD ) )
4578        {
4579            throw new InvalidCharacterException( c );
4580        }
4581
4582        if ( ( c >= 0x0BC3 ) && ( c <= 0x0BC5 ) )
4583        {
4584            throw new InvalidCharacterException( c );
4585        }
4586
4587        if ( ( c >= 0x0BCE ) && ( c <= 0x0BD6 ) )
4588        {
4589            throw new InvalidCharacterException( c );
4590        }
4591
4592        if ( ( c >= 0x0BD8 ) && ( c <= 0x0BE6 ) )
4593        {
4594            throw new InvalidCharacterException( c );
4595        }
4596
4597        if ( ( c >= 0x0BF3 ) && ( c <= 0x0C00 ) )
4598        {
4599            throw new InvalidCharacterException( c );
4600        }
4601
4602        // RFC 3454, Table C.3
4603        if ( ( c >= 0xE000 ) && ( c <= 0xF8FF ) )
4604        {
4605            throw new InvalidCharacterException( c );
4606        }
4607
4608        // RFC 3454, Table C.4
4609        if ( ( c >= 0xFDD0 ) && ( c <= 0xFDEF ) )
4610        {
4611            throw new InvalidCharacterException( c );
4612        }
4613
4614        if ( ( c == 0xFFFE ) || ( c == 0xFFFF ) )
4615        {
4616            throw new InvalidCharacterException( c );
4617        }
4618
4619        // RFC 3454, Table C.5 (Surrogates)
4620        if ( ( c >= 0xD800 ) && ( c <= 0xDFFF ) )
4621        {
4622            throw new InvalidCharacterException( c );
4623        }
4624
4625        // RFC 3454, Table C.8 
4626        switch ( c )
4627        {
4628            case 0x0340: // COMBINING GRAVE TONE MARK
4629            case 0x0341: // COMBINING ACUTE TONE MARK
4630            case 0x200E: // LEFT-TO-RIGHT MARK
4631            case 0x200F: // RIGHT-TO-LEFT MARK
4632            case 0x202A: // LEFT-TO-RIGHT EMBEDDING
4633            case 0x202B: // RIGHT-TO-LEFT EMBEDDING
4634            case 0x202C: // POP DIRECTIONAL FORMATTING
4635            case 0x202D: // LEFT-TO-RIGHT OVERRIDE
4636            case 0x202E: // RIGHT-TO-LEFT OVERRIDE
4637            case 0x206A: // INHIBIT SYMMETRIC SWAPPING
4638            case 0x206B: // ACTIVATE SYMMETRIC SWAPPING
4639            case 0x206C: // INHIBIT ARABIC FORM SHAPING
4640            case 0x206D: // ACTIVATE ARABIC FORM SHAPING
4641            case 0x206E: // NATIONAL DIGIT SHAPES
4642            case 0x206F: // NOMINAL DIGIT SHAPES
4643                throw new InvalidCharacterException( c );
4644            default:
4645                break;
4646        }
4647
4648        if ( c == 0xFFFD )
4649        {
4650            throw new InvalidCharacterException( c );
4651        }
4652    }
4653
4654
4655    /**
4656     * 
4657     * Remove all bidirectionnal chars. This is not really clear in RFC 4518
4658     * what we should do with bidi chars :
4659     * "Bidirectional characters are ignored."
4660     * 
4661     * But it's not explained what is a bidi chars...
4662     * 
4663     * So this method just do nothing atm.
4664     *
4665     * @param str The string where bidi chars are to be removed
4666     * @return The cleaned string
4667     */
4668    public static String bidi( String str )
4669    {
4670        return str;
4671    }
4672
4673
4674    /**
4675     * 
4676     * Remove all bidirectionnal chars. This is not really clear in RFC 4518
4677     * what we should do with bidi chars :
4678     * "Bidirectional characters are ignored."
4679     * 
4680     * But it's not explained what is a bidi chars...
4681     * 
4682     * So this method just do nothing atm.
4683     *
4684     * @param array The char array where bidi chars are to be removed
4685     * @return The cleaned StringBuilder
4686     */
4687    public static StringBuilder bidi( char[] array )
4688    {
4689        StringBuilder sb = new StringBuilder( array == null ? 0 : array.length );
4690
4691        if ( array != null )
4692        {
4693            sb.append( array );
4694        }
4695
4696        return sb;
4697    }
4698
4699
4700    /**
4701     * 
4702     * Remove all insignifiant chars in a Telephone Number :
4703     * Hyphen and spaces. 
4704     * 
4705     * For instance, the following telephone number :
4706     * "+ (33) 1-123--456  789"
4707     * will be trasnformed to :
4708     * "+(33)1123456789"
4709     *
4710     * @param str The telephone number
4711     * @return The modified telephone number String
4712     */
4713    private static String insignifiantCharTelephoneNumber( String str )
4714    {
4715        if ( Strings.isEmpty( str ) )
4716        {
4717            return "";
4718        }
4719
4720        char[] array = str.toCharArray();
4721
4722        boolean isSpaceOrHyphen = false;
4723        char soh = '\0';
4724        int pos = 0;
4725
4726        for ( char c : array )
4727        {
4728            switch ( c )
4729            {
4730                case 0x0020: // SPACE
4731                case 0x002D: // HYPHEN-MINUS
4732                case 0x058A: // ARMENIAN HYPHEN
4733                case 0x2010: // HYPHEN
4734                case 0x2011: // NON-BREAKING HYPHEN
4735                case 0x2212: // MINUS SIGN
4736                case 0xFE63: // SMALL HYPHEN-MINUS
4737                case 0xFF0D: // FULLWIDTH HYPHEN-MINUS
4738                    soh = c;
4739                    break;
4740
4741                default:
4742                    if ( isSpaceOrHyphen && isCombiningMark( c ) )
4743                    {
4744                        array[pos++] = soh;
4745                        isSpaceOrHyphen = false;
4746                    }
4747
4748                    array[pos++] = c;
4749                    break;
4750            }
4751        }
4752
4753        return new String( array, 0, pos );
4754    }
4755
4756
4757    /**
4758     * 
4759     * Remove all insignifiant spaces in a numeric string. For
4760     * instance, the following numeric string :
4761     * "  123  456  789  "
4762     * will be transformed to :
4763     * "123456789"
4764     *
4765     * @param str The numeric String
4766     * @return The modified numeric StringBuilder
4767     */
4768    private static String insignifiantCharNumericString( String str )
4769    {
4770        if ( Strings.isEmpty( str ) )
4771        {
4772            return "";
4773        }
4774
4775        char[] array = str.toCharArray();
4776
4777        boolean isSpace = false;
4778        int pos = 0;
4779
4780        for ( char c : array )
4781        {
4782            if ( c != 0x20 )
4783            {
4784                if ( isSpace && isCombiningMark( c ) )
4785                {
4786                    array[pos++] = ' ';
4787                    isSpace = false;
4788                }
4789
4790                array[pos++] = c;
4791            }
4792            else
4793            {
4794                isSpace = true;
4795            }
4796        }
4797
4798        return new String( array, 0, pos );
4799    }
4800
4801
4802    /**
4803     * 
4804     * Remove all insignificant spaces in a string.
4805     * 
4806     * This method use a finite state machine to parse
4807     * the text.
4808     * 
4809     * @param str The String to modify
4810     * @param caseSensitive A flag telling if the chars must be lower cased
4811     * @return The modified StringBuilder
4812     * @throws InvalidCharacterException If an invalid character is found in the String
4813     */
4814    private static String insignifiantSpacesString( String str, boolean caseSensitive )
4815        throws InvalidCharacterException
4816    {
4817        if ( Strings.isEmpty( str ) )
4818        {
4819            // Special case : an empty strings is replaced by 2 spaces
4820            return "";
4821        }
4822
4823        char[] array = str.toCharArray();
4824
4825        // Create a target char array which is 3 times bigger than the original size. 
4826        // We have to do that because the map phase may transform a char to
4827        // three chars.
4828        // TODO : we have to find a way to prevent this waste of space.
4829        char[] target = new char[str.length() * 3 + 2];
4830
4831        int pos = 0;
4832        char lowerCase = ( char ) ( caseSensitive ? 0x00 : 0x20 );
4833
4834        // First pass to map the chars
4835        for ( char c : array )
4836        {
4837            pos += map( c, target, pos, lowerCase );
4838        }
4839
4840        int limit = pos;
4841        pos = 0;
4842
4843        // Second pass to remove spaces. We work on the target
4844        int i = 0;
4845        char c = '\0';
4846
4847        // First remove starting spaces
4848        for ( i = 0; i < limit; i++ )
4849        {
4850            c = target[i];
4851
4852            if ( c != ' ' )
4853            {
4854                checkProhibited( c );
4855                break;
4856            }
4857        }
4858
4859        // Now, 'i' will be the starting point. We will just handle the special
4860        // case of a combining character
4861        int start = i;
4862
4863        if ( start == limit )
4864        {
4865            // we only have spaces, we keep only one
4866            return " ";
4867        }
4868        else if ( isCombiningMark( c ) )
4869        {
4870            if ( start == 0 )
4871            {
4872                // The first char can't be a combining char
4873                throw new InvalidCharacterException( c );
4874            }
4875            else
4876            {
4877                target[pos++] = ' ';
4878                target[pos++] = c;
4879                start++;
4880            }
4881        }
4882        else
4883        {
4884            target[pos++] = c;
4885            start++;
4886        }
4887
4888        // Now remove the spaces at the end
4889        for ( i = limit - 1; i > start; i-- )
4890        {
4891            if ( target[i] != ' ' )
4892            {
4893                break;
4894            }
4895        }
4896
4897        limit = i + 1;
4898
4899        // Let's deal with the following chars. It will be
4900        // a list of chars and spaces. We will consider that
4901        // we have couples of chars and spaces :
4902        // (char * space*)*. We have a special case :
4903        // a space followed by a combining char.
4904        boolean spaceSeen = false;
4905        boolean space2Seen = false;
4906
4907        for ( i = start; i < limit; i++ )
4908        {
4909            c = target[i];
4910
4911            checkProhibited( c );
4912
4913            if ( isCombiningMark( c ) )
4914            {
4915                if ( spaceSeen )
4916                {
4917                    if ( space2Seen )
4918                    {
4919                        target[pos++] = ' ';
4920                    }
4921
4922                    target[pos++] = ' ';
4923                    target[pos++] = c;
4924                    spaceSeen = false;
4925                    space2Seen = false;
4926                }
4927                else
4928                {
4929                    target[pos++] = c;
4930                }
4931            }
4932            else if ( c == ' ' )
4933            {
4934                if ( spaceSeen )
4935                {
4936                    space2Seen = true;
4937                }
4938                else
4939                {
4940                    spaceSeen = true;
4941                }
4942            }
4943            else
4944            {
4945                if ( spaceSeen )
4946                {
4947                    target[pos++] = ' ';
4948                    spaceSeen = false;
4949                    space2Seen = false;
4950                }
4951
4952                target[pos++] = c;
4953            }
4954        }
4955
4956        return new String( target, 0, pos );
4957    }
4958
4959
4960    /**
4961     * Remove all insignificant spaces in a Ascii string.
4962     * 
4963     * This method use a finite state machine to parse
4964     * the text.
4965     * 
4966     * @param str The String to modify
4967     * @param caseSensitive A flag telling if the chars must be lower cased
4968     * @return The modified StringBuilder
4969     * @throws InvalidCharacterException If an invalid character is found in the String
4970     */
4971    private static String insignifiantSpacesStringAscii( String str, boolean caseSensitive )
4972        throws InvalidCharacterException
4973    {
4974        if ( Strings.isEmpty( str ) )
4975        {
4976            // Special case : an empty strings is replaced by 2 spaces
4977            return "";
4978        }
4979    
4980        char[] array = str.toCharArray();
4981    
4982        int pos = 0;
4983        char lowerCase = ( char ) ( caseSensitive ? 0x00 : 0x20 );
4984    
4985        // First pass to map the chars
4986        for ( char c : array )
4987        {
4988            pos += map( c, array, pos, lowerCase );
4989        }
4990    
4991        int limit = pos;
4992        pos = 0;
4993    
4994        // Second pass to remove spaces. We work on the target
4995        int i = 0;
4996        char c = '\0';
4997    
4998        // First remove starting spaces
4999        for ( i = 0; i < limit; i++ )
5000        {
5001            c = array[i];
5002    
5003            if ( c != ' ' )
5004            {
5005                checkProhibited( c );
5006                break;
5007            }
5008        }
5009    
5010        // Now, 'i' will be the starting point. We will just handle the special
5011        // case of a combining character
5012        int start = i;
5013    
5014        if ( start == limit )
5015        {
5016            // we only have spaces, we keep only one
5017            return " ";
5018        }
5019        else if ( isCombiningMark( c ) )
5020        {
5021            if ( start == 0 )
5022            {
5023                // The first char can't be a combining char
5024                throw new InvalidCharacterException( c );
5025            }
5026            else
5027            {
5028                throw new InvalidCharacterException( c );
5029            }
5030        }
5031        else
5032        {
5033            array[pos++] = c;
5034            start++;
5035        }
5036    
5037        // Now remove the spaces at the end
5038        for ( i = limit - 1; i > start; i-- )
5039        {
5040            if ( array[i] != ' ' )
5041            {
5042                break;
5043            }
5044        }
5045    
5046        limit = i + 1;
5047    
5048        // Let's deal with the following chars. It will be
5049        // a list of chars and spaces. We will consider that
5050        // we have couples of chars and spaces :
5051        // (char * space*)*. We have a special case :
5052        // a space followed by a combining char.
5053        boolean spaceSeen = false;
5054        boolean space2Seen = false;
5055    
5056        for ( i = start; i < limit; i++ )
5057        {
5058            c = array[i];
5059    
5060            checkProhibited( c );
5061    
5062            if ( isCombiningMark( c ) )
5063            {
5064                throw new InvalidCharacterException( c );
5065            }
5066            else if ( c == ' ' )
5067            {
5068                if ( spaceSeen )
5069                {
5070                    space2Seen = true;
5071                }
5072                else
5073                {
5074                    spaceSeen = true;
5075                }
5076            }
5077            else
5078            {
5079                if ( spaceSeen )
5080                {
5081                    array[pos++] = ' ';
5082                    spaceSeen = false;
5083                    space2Seen = false;
5084                }
5085    
5086                array[pos++] = c;
5087            }
5088        }
5089    
5090        return new String( array, 0, pos );
5091    }
5092}