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