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