View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  
21  package org.apache.directory.api.ldap.model.schema;
22  
23  
24  import java.io.IOException;
25  
26  import org.apache.directory.api.util.Strings;
27  import org.apache.directory.api.util.exception.InvalidCharacterException;
28  
29  
30  /**
31   * 
32   * This class implements the 6 steps described in RFC 4518
33   *
34   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
35   */
36  public final class PrepareString
37  {
38      /** A flag used to lowercase chars during the map process */
39      private static final boolean CASE_SENSITIVE = true;
40  
41      /** A flag used to keep casing during the map process */
42      private static final boolean IGNORE_CASE = false;
43  
44      /** All the possible combining marks */
45      private static final char[][] COMBINING_MARKS = new char[][]
46          {
47              { 0x0300, 0x034F },
48              { 0x0360, 0x036F },
49              { 0x0483, 0x0486 },
50              { 0x0488, 0x0489 },
51              { 0x0591, 0x05A1 },
52              { 0x05A3, 0x05B9 },
53              { 0x05BB, 0x05BC },
54              { 0x05BF, 0x05BF },
55              { 0x05C1, 0x05C2 },
56              { 0x05C4, 0x05C4 },
57              { 0x064B, 0x0655 },
58              { 0x0670, 0x0670 },
59              { 0x06D6, 0x06DC },
60              { 0x06DE, 0x06E4 },
61              { 0x06E7, 0x06E8 },
62              { 0x06EA, 0x06ED },
63              { 0x0711, 0x0711 },
64              { 0x0730, 0x074A },
65              { 0x07A6, 0x07B0 },
66              { 0x0901, 0x0903 },
67              { 0x093C, 0x093C },
68              { 0x093E, 0x094F },
69              { 0x0951, 0x0954 },
70              { 0x0962, 0x0963 },
71              { 0x0981, 0x0983 },
72              { 0x09BC, 0x09BC },
73              { 0x09BE, 0x09C4 },
74              { 0x09C7, 0x09C8 },
75              { 0x09CB, 0x09CD },
76              { 0x09D7, 0x09D7 },
77              { 0x09E2, 0x09E3 },
78              { 0x0A02, 0x0A02 },
79              { 0x0A3C, 0x0A3C },
80              { 0x0A3E, 0x0A42 },
81              { 0x0A47, 0x0A48 },
82              { 0x0A4B, 0x0A4D },
83              { 0x0A70, 0x0A71 },
84              { 0x0A81, 0x0A83 },
85              { 0x0ABC, 0x0ABC },
86              { 0x0ABE, 0x0AC5 },
87              { 0x0AC7, 0x0AC9 },
88              { 0x0ACB, 0x0ACD },
89              { 0x0B01, 0x0B03 },
90              { 0x0B3C, 0x0B3C },
91              { 0x0B3E, 0x0B43 },
92              { 0x0B47, 0x0B48 },
93              { 0x0B4B, 0x0B4D },
94              { 0x0B56, 0x0B57 },
95              { 0x0B82, 0x0B82 },
96              { 0x0BBE, 0x0BC2 },
97              { 0x0BC6, 0x0BC8 },
98              { 0x0BCA, 0x0BCD },
99              { 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 }