Method: equals(char[][], char[][])
1: /*
2: * #%~
3: * org.overture.ide.debug
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.ide.debug.utils;
23:
24: /**
25: * This class is a collection of helper methods to manipulate char arrays.
26: */
27: public final class CharOperation
28: {
29:
30:         /**
31:          * Constant for an empty char array
32:          */
33:         public static final char[] NO_CHAR = new char[0];
34:
35:         /**
36:          * Constant for an empty char array with two dimensions.
37:          */
38:         public static final char[][] NO_CHAR_CHAR = new char[0][];
39:
40:         /**
41:          * Constant for an empty String array.
42:          */
43:         public static final String[] NO_STRINGS = new String[0];
44:
45:         // private static final char MAX_OBVIOUS = 128;
46:
47:         /**
48:          * Answers a new array with appending the suffix character at the end of the array. <br>
49:          * <br>
50:          * For example:<br>
51:          * <ol>
52:          * <li>
53:          *
54:          * <pre>
55:          * array = { 'a', 'b' }
56:          * suffix = 'c'
57:          * => result = { 'a', 'b' , 'c' }
58:          * </pre>
59:          *
60:          * </li>
61:          * <li>
62:          *
63:          * <pre>
64:          * array = null
65:          * suffix = 'c'
66:          * => result = { 'c' }
67:          * </pre>
68:          *
69:          * </li>
70:          * </ol>
71:          *
72:          * @param array
73:          * the array that is concanated with the suffix character
74:          * @param suffix
75:          * the suffix character
76:          * @return the new array
77:          */
78:         public static final char[] append(char[] array, char suffix)
79:         {
80:                 if (array == null)
81:                 {
82:                         return new char[] { suffix };
83:                 }
84:                 int length = array.length;
85:                 System.arraycopy(array, 0, array = new char[length + 1], 0, length);
86:                 array[length] = suffix;
87:                 return array;
88:         }
89:
90:         /**
91:          * Append the given subarray to the target array starting at the given index in the target array. The start of the
92:          * subarray is inclusive, the end is exclusive. Answers a new target array if it needs to grow, otherwise answers
93:          * the same target array. <br>
94:          * For example:<br>
95:          * <ol>
96:          * <li>
97:          *
98:          * <pre>
99:          * target = { 'a', 'b', '0' }
100:          * index = 2
101:          * array = { 'c', 'd' }
102:          * start = 0
103:          * end = 1
104:          * => result = { 'a', 'b' , 'c' }
105:          * </pre>
106:          *
107:          * </li>
108:          * <li>
109:          *
110:          * <pre>
111:          * target = { 'a', 'b' }
112:          * index = 2
113:          * array = { 'c', 'd' }
114:          * start = 0
115:          * end = 1
116:          * => result = { 'a', 'b' , 'c', '0', '0' , '0' } (new array)
117:          * </pre>
118:          *
119:          * </li>
120:          * <li>
121:          *
122:          * <pre>
123:          * target = { 'a', 'b', 'c' }
124:          * index = 1
125:          * array = { 'c', 'd', 'e', 'f' }
126:          * start = 1
127:          * end = 4
128:          * => result = { 'a', 'd' , 'e', 'f', '0', '0', '0', '0' } (new array)
129:          * </pre>
130:          *
131:          * </li>
132:          * </ol>
133:          *
134:          * @param target
135:          * the given target
136:          * @param index
137:          * the given index
138:          * @param array
139:          * the given array
140:          * @param start
141:          * the given start index
142:          * @param end
143:          * the given end index
144:          * @return the new array
145:          * @throws NullPointerException
146:          * if the target array is null
147:          */
148:         public static final char[] append(char[] target, int index, char[] array,
149:                         int start, int end)
150:         {
151:                 int targetLength = target.length;
152:                 int subLength = end - start;
153:                 int newTargetLength = subLength + index;
154:                 if (newTargetLength > targetLength)
155:                 {
156:                         System.arraycopy(target, 0, target = new char[newTargetLength * 2], 0, index);
157:                 }
158:                 System.arraycopy(array, start, target, index, subLength);
159:                 return target;
160:         }
161:
162:         /**
163:          * Answers the concatenation of the two arrays. It answers null if the two arrays are null. If the first array is
164:          * null, then the second array is returned. If the second array is null, then the first array is returned. <br>
165:          * <br>
166:          * For example:
167:          * <ol>
168:          * <li>
169:          *
170:          * <pre>
171:          * first = null
172:          * second = null
173:          * => result = null
174:          * </pre>
175:          *
176:          * </li>
177:          * <li>
178:          *
179:          * <pre>
180:          * first = { { ' a' } }
181:          * second = null
182:          * => result = { { ' a' } }
183:          * </pre>
184:          *
185:          * </li>
186:          * <li>
187:          *
188:          * <pre>
189:          * first = null
190:          * second = { { ' a' } }
191:          * => result = { { ' a' } }
192:          * </pre>
193:          *
194:          * </li>
195:          * <li>
196:          *
197:          * <pre>
198:          * first = { { ' b' } }
199:          * second = { { ' a' } }
200:          * => result = { { ' b' }, { ' a' } }
201:          * </pre>
202:          *
203:          * </li>
204:          * </ol>
205:          *
206:          * @param first
207:          * the first array to concatenate
208:          * @param second
209:          * the second array to concatenate
210:          * @return the concatenation of the two arrays, or null if the two arrays are null.
211:          */
212:         public static final char[][] arrayConcat(char[][] first, char[][] second)
213:         {
214:                 if (first == null)
215:                 {
216:                         return second;
217:                 }
218:                 if (second == null)
219:                 {
220:                         return first;
221:                 }
222:
223:                 int length1 = first.length;
224:                 int length2 = second.length;
225:                 char[][] result = new char[length1 + length2][];
226:                 System.arraycopy(first, 0, result, 0, length1);
227:                 System.arraycopy(second, 0, result, length1, length2);
228:                 return result;
229:         }
230:
231:         /**
232:          * Returns the char arrays as an array of Strings
233:          *
234:          * @param charArrays
235:          * the char array to convert
236:          * @return the char arrays as an array of Strings or null if the given char arrays is null.
237:          */
238:         public static String[] charArrayToStringArray(char[][] charArrays)
239:         {
240:                 if (charArrays == null)
241:                 {
242:                         return null;
243:                 }
244:                 int length = charArrays.length;
245:                 if (length == 0)
246:                 {
247:                         return NO_STRINGS;
248:                 }
249:                 String[] strings = new String[length];
250:                 for (int i = 0; i < length; i++)
251:                 {
252:                         strings[i] = new String(charArrays[i]);
253:                 }
254:                 return strings;
255:         }
256:
257:         /**
258:          * Returns the char array as a String
259:          *
260:          * @param charArray
261:          * the char array to convert
262:          * @return the char array as a String or null if the given char array is null.
263:          */
264:         public static String charToString(char[] charArray)
265:         {
266:                 if (charArray == null)
267:                 {
268:                         return null;
269:                 }
270:                 return new String(charArray);
271:         }
272:
273:         /**
274:          * Answers a new array adding the second array at the end of first array. It answers null if the first and second
275:          * are null. If the first array is null, then a new array char[][] is created with second. If the second array is
276:          * null, then the first array is returned. <br>
277:          * <br>
278:          * For example:
279:          * <ol>
280:          * <li>
281:          *
282:          * <pre>
283:          * first = null
284:          * second = { 'a' }
285:          * => result = { { ' a' } }
286:          * </pre>
287:          * <li>
288:          *
289:          * <pre>
290:          * first = { { ' a' } }
291:          * second = null
292:          * => result = { { ' a' } }
293:          * </pre>
294:          *
295:          * </li>
296:          * <li>
297:          *
298:          * <pre>
299:          * first = { { ' a' } }
300:          * second = { ' b' }
301:          * => result = { { ' a' } , { ' b' } }
302:          * </pre>
303:          *
304:          * </li>
305:          * </ol>
306:          *
307:          * @param first
308:          * the first array to concatenate
309:          * @param second
310:          * the array to add at the end of the first array
311:          * @return a new array adding the second array at the end of first array, or null if the two arrays are null.
312:          */
313:         public static final char[][] arrayConcat(char[][] first, char[] second)
314:         {
315:                 if (second == null)
316:                 {
317:                         return first;
318:                 }
319:                 if (first == null)
320:                 {
321:                         return new char[][] { second };
322:                 }
323:
324:                 int length = first.length;
325:                 char[][] result = new char[length + 1][];
326:                 System.arraycopy(first, 0, result, 0, length);
327:                 result[length] = second;
328:                 return result;
329:         }
330:
331:         /**
332:          * Compares the contents of the two arrays array and prefix. Returns
333:          * <ul>
334:          * <li>zero if the array starts with the prefix contents</li>
335:          * <li>the difference between the first two characters that are not equal</li>
336:          * <li>one if array length is lower than the prefix length and that the prefix starts with the array contents.</li>
337:          * </ul>
338:          * <p>
339:          * For example:
340:          * <ol>
341:          * <li>
342:          *
343:          * <pre>
344:          * array = null
345:          * prefix = null
346:          * => result = NullPointerException
347:          * </pre>
348:          *
349:          * </li>
350:          * <li>
351:          *
352:          * <pre>
353:          * array = { 'a', 'b', 'c', 'd', 'e' }
354:          * prefix = { 'a', 'b', 'c'}
355:          * => result = 0
356:          * </pre>
357:          *
358:          * </li>
359:          * <li>
360:          *
361:          * <pre>
362:          * array = { 'a', 'b', 'c', 'd', 'e' }
363:          * prefix = { 'a', 'B', 'c'}
364:          * => result = 32
365:          * </pre>
366:          *
367:          * </li>
368:          * <li>
369:          *
370:          * <pre>
371:          * array = { 'd', 'b', 'c', 'd', 'e' }
372:          * prefix = { 'a', 'b', 'c'}
373:          * => result = 3
374:          * </pre>
375:          *
376:          * </li>
377:          * <li>
378:          *
379:          * <pre>
380:          * array = { 'a', 'b', 'c', 'd', 'e' }
381:          * prefix = { 'd', 'b', 'c'}
382:          * => result = -3
383:          * </pre>
384:          *
385:          * </li>
386:          * <li>
387:          *
388:          * <pre>
389:          * array = { 'a', 'a', 'c', 'd', 'e' }
390:          * prefix = { 'a', 'e', 'c'}
391:          * => result = -4
392:          * </pre>
393:          *
394:          * </li>
395:          * </ol>
396:          * </p>
397:          *
398:          * @param array
399:          * the given array
400:          * @param prefix
401:          * the given prefix
402:          * @return the result of the comparison (>=0 if array>prefix)
403:          * @throws NullPointerException
404:          * if either array or prefix is null
405:          */
406:         public static final int compareWith(char[] array, char[] prefix)
407:         {
408:                 int arrayLength = array.length;
409:                 int prefixLength = prefix.length;
410:                 int min = Math.min(arrayLength, prefixLength);
411:                 int i = 0;
412:                 while (min-- != 0)
413:                 {
414:                         char c1 = array[i];
415:                         char c2 = prefix[i++];
416:                         if (c1 != c2)
417:                         {
418:                                 return c1 - c2;
419:                         }
420:                 }
421:                 if (prefixLength == i)
422:                 {
423:                         return 0;
424:                 }
425:                 return -1; // array is shorter than prefix (e.g. array:'ab' <
426:                 // prefix:'abc').
427:         }
428:
429:         /**
430:          * Answers the concatenation of the two arrays. It answers null if the two arrays are null. If the first array is
431:          * null, then the second array is returned. If the second array is null, then the first array is returned. <br>
432:          * <br>
433:          * For example:
434:          * <ol>
435:          * <li>
436:          *
437:          * <pre>
438:          * first = null
439:          * second = { 'a' }
440:          * => result = { ' a' }
441:          * </pre>
442:          *
443:          * </li>
444:          * <li>
445:          *
446:          * <pre>
447:          * first = { ' a' }
448:          * second = null
449:          * => result = { ' a' }
450:          * </pre>
451:          *
452:          * </li>
453:          * <li>
454:          *
455:          * <pre>
456:          * first = { ' a' }
457:          * second = { ' b' }
458:          * => result = { ' a' , ' b' }
459:          * </pre>
460:          *
461:          * </li>
462:          * </ol>
463:          *
464:          * @param first
465:          * the first array to concatenate
466:          * @param second
467:          * the second array to concatenate
468:          * @return the concatenation of the two arrays, or null if the two arrays are null.
469:          */
470:         public static final char[] concat(char[] first, char[] second)
471:         {
472:                 if (first == null)
473:                 {
474:                         return second;
475:                 }
476:                 if (second == null)
477:                 {
478:                         return first;
479:                 }
480:
481:                 int length1 = first.length;
482:                 int length2 = second.length;
483:                 char[] result = new char[length1 + length2];
484:                 System.arraycopy(first, 0, result, 0, length1);
485:                 System.arraycopy(second, 0, result, length1, length2);
486:                 return result;
487:         }
488:
489:         /**
490:          * Answers the concatenation of the three arrays. It answers null if the three arrays are null. If first is null, it
491:          * answers the concatenation of second and third. If second is null, it answers the concatenation of first and
492:          * third. If third is null, it answers the concatenation of first and second. <br>
493:          * <br>
494:          * For example:
495:          * <ol>
496:          * <li>
497:          *
498:          * <pre>
499:          * first = null
500:          * second = { 'a' }
501:          * third = { 'b' }
502:          * => result = { ' a', 'b' }
503:          * </pre>
504:          *
505:          * </li>
506:          * <li>
507:          *
508:          * <pre>
509:          * first = { 'a' }
510:          * second = null
511:          * third = { 'b' }
512:          * => result = { ' a', 'b' }
513:          * </pre>
514:          *
515:          * </li>
516:          * <li>
517:          *
518:          * <pre>
519:          * first = { 'a' }
520:          * second = { 'b' }
521:          * third = null
522:          * => result = { ' a', 'b' }
523:          * </pre>
524:          *
525:          * </li>
526:          * <li>
527:          *
528:          * <pre>
529:          * first = null
530:          * second = null
531:          * third = null
532:          * => result = null
533:          * </pre>
534:          *
535:          * </li>
536:          * <li>
537:          *
538:          * <pre>
539:          * first = { 'a' }
540:          * second = { 'b' }
541:          * third = { 'c' }
542:          * => result = { 'a', 'b', 'c' }
543:          * </pre>
544:          *
545:          * </li>
546:          * </ol>
547:          *
548:          * @param first
549:          * the first array to concatenate
550:          * @param second
551:          * the second array to concatenate
552:          * @param third
553:          * the third array to concatenate
554:          * @return the concatenation of the three arrays, or null if the three arrays are null.
555:          */
556:         public static final char[] concat(char[] first, char[] second, char[] third)
557:         {
558:                 if (first == null)
559:                 {
560:                         return concat(second, third);
561:                 }
562:                 if (second == null)
563:                 {
564:                         return concat(first, third);
565:                 }
566:                 if (third == null)
567:                 {
568:                         return concat(first, second);
569:                 }
570:
571:                 int length1 = first.length;
572:                 int length2 = second.length;
573:                 int length3 = third.length;
574:                 char[] result = new char[length1 + length2 + length3];
575:                 System.arraycopy(first, 0, result, 0, length1);
576:                 System.arraycopy(second, 0, result, length1, length2);
577:                 System.arraycopy(third, 0, result, length1 + length2, length3);
578:                 return result;
579:         }
580:
581:         /**
582:          * Answers the concatenation of the two arrays inserting the separator character between the two arrays. It answers
583:          * null if the two arrays are null. If the first array is null, then the second array is returned. If the second
584:          * array is null, then the first array is returned. <br>
585:          * <br>
586:          * For example:
587:          * <ol>
588:          * <li>
589:          *
590:          * <pre>
591:          * first = null
592:          * second = { 'a' }
593:          * separator = '/'
594:          * => result = { ' a' }
595:          * </pre>
596:          *
597:          * </li>
598:          * <li>
599:          *
600:          * <pre>
601:          * first = { ' a' }
602:          * second = null
603:          * separator = '/'
604:          * => result = { ' a' }
605:          * </pre>
606:          *
607:          * </li>
608:          * <li>
609:          *
610:          * <pre>
611:          * first = { ' a' }
612:          * second = { ' b' }
613:          * separator = '/'
614:          * => result = { ' a' , '/', 'b' }
615:          * </pre>
616:          *
617:          * </li>
618:          * </ol>
619:          *
620:          * @param first
621:          * the first array to concatenate
622:          * @param second
623:          * the second array to concatenate
624:          * @param separator
625:          * the character to insert
626:          * @return the concatenation of the two arrays inserting the separator character between the two arrays , or null if
627:          * the two arrays are null.
628:          */
629:         public static final char[] concat(char[] first, char[] second,
630:                         char separator)
631:         {
632:                 if (first == null)
633:                 {
634:                         return second;
635:                 }
636:                 if (second == null)
637:                 {
638:                         return first;
639:                 }
640:
641:                 int length1 = first.length;
642:                 if (length1 == 0)
643:                 {
644:                         return second;
645:                 }
646:                 int length2 = second.length;
647:                 if (length2 == 0)
648:                 {
649:                         return first;
650:                 }
651:
652:                 char[] result = new char[length1 + length2 + 1];
653:                 System.arraycopy(first, 0, result, 0, length1);
654:                 result[length1] = separator;
655:                 System.arraycopy(second, 0, result, length1 + 1, length2);
656:                 return result;
657:         }
658:
659:         public static final char[] concatWithSeparator(char[] first, char[] second,
660:                         char[] separator)
661:         {
662:                 if (first == null)
663:                 {
664:                         return second;
665:                 }
666:                 if (second == null)
667:                 {
668:                         return first;
669:                 }
670:
671:                 int length1 = first.length;
672:                 if (length1 == 0)
673:                 {
674:                         return second;
675:                 }
676:                 int length2 = second.length;
677:                 if (length2 == 0)
678:                 {
679:                         return first;
680:                 }
681:                 int length3 = separator.length;
682:
683:                 char[] result = new char[length1 + length2 + length3];
684:                 System.arraycopy(first, 0, result, 0, length1);
685:                 System.arraycopy(separator, 0, result, length1, length3);
686:                 System.arraycopy(second, 0, result, length1 + length3, length2);
687:                 return result;
688:         }
689:
690:         /**
691:          * Answers the concatenation of the three arrays inserting the sep1 character between the first two arrays and sep2
692:          * between the last two. It answers null if the three arrays are null. If the first array is null, then it answers
693:          * the concatenation of second and third inserting the sep2 character between them. If the second array is null,
694:          * then it answers the concatenation of first and third inserting the sep1 character between them. If the third
695:          * array is null, then it answers the concatenation of first and second inserting the sep1 character between them. <br>
696:          * <br>
697:          * For example:
698:          * <ol>
699:          * <li>
700:          *
701:          * <pre>
702:          * first = null
703:          * sep1 = '/'
704:          * second = { 'a' }
705:          * sep2 = ':'
706:          * third = { 'b' }
707:          * => result = { ' a' , ':', 'b' }
708:          * </pre>
709:          *
710:          * </li>
711:          * <li>
712:          *
713:          * <pre>
714:          * first = { 'a' }
715:          * sep1 = '/'
716:          * second = null
717:          * sep2 = ':'
718:          * third = { 'b' }
719:          * => result = { ' a' , '/', 'b' }
720:          * </pre>
721:          *
722:          * </li>
723:          * <li>
724:          *
725:          * <pre>
726:          * first = { 'a' }
727:          * sep1 = '/'
728:          * second = { 'b' }
729:          * sep2 = ':'
730:          * third = null
731:          * => result = { ' a' , '/', 'b' }
732:          * </pre>
733:          *
734:          * </li>
735:          * <li>
736:          *
737:          * <pre>
738:          * first = { 'a' }
739:          * sep1 = '/'
740:          * second = { 'b' }
741:          * sep2 = ':'
742:          * third = { 'c' }
743:          * => result = { ' a' , '/', 'b' , ':', 'c' }
744:          * </pre>
745:          *
746:          * </li>
747:          * </ol>
748:          *
749:          * @param first
750:          * the first array to concatenate
751:          * @param sep1
752:          * the character to insert
753:          * @param second
754:          * the second array to concatenate
755:          * @param sep2
756:          * the character to insert
757:          * @param third
758:          * the second array to concatenate
759:          * @return the concatenation of the three arrays inserting the sep1 character between the two arrays and sep2
760:          * between the last two.
761:          */
762:         public static final char[] concat(char[] first, char sep1, char[] second,
763:                         char sep2, char[] third)
764:         {
765:                 if (first == null)
766:                 {
767:                         return concat(second, third, sep2);
768:                 }
769:                 if (second == null)
770:                 {
771:                         return concat(first, third, sep1);
772:                 }
773:                 if (third == null)
774:                 {
775:                         return concat(first, second, sep1);
776:                 }
777:
778:                 int length1 = first.length;
779:                 int length2 = second.length;
780:                 int length3 = third.length;
781:                 char[] result = new char[length1 + length2 + length3 + 2];
782:                 System.arraycopy(first, 0, result, 0, length1);
783:                 result[length1] = sep1;
784:                 System.arraycopy(second, 0, result, length1 + 1, length2);
785:                 result[length1 + length2 + 1] = sep2;
786:                 System.arraycopy(third, 0, result, length1 + length2 + 2, length3);
787:                 return result;
788:         }
789:
790:         /**
791:          * Answers a new array with prepending the prefix character and appending the suffix character at the end of the
792:          * array. If array is null, it answers a new array containing the prefix and the suffix characters. <br>
793:          * <br>
794:          * For example:<br>
795:          * <ol>
796:          * <li>
797:          *
798:          * <pre>
799:          * prefix = 'a'
800:          * array = { 'b' }
801:          * suffix = 'c'
802:          * => result = { 'a', 'b' , 'c' }
803:          * </pre>
804:          *
805:          * </li>
806:          * <li>
807:          *
808:          * <pre>
809:          * prefix = 'a'
810:          * array = null
811:          * suffix = 'c'
812:          * => result = { 'a', 'c' }
813:          * </pre>
814:          *
815:          * </li>
816:          * </ol>
817:          *
818:          * @param prefix
819:          * the prefix character
820:          * @param array
821:          * the array that is concanated with the prefix and suffix characters
822:          * @param suffix
823:          * the suffix character
824:          * @return the new array
825:          */
826:         public static final char[] concat(char prefix, char[] array, char suffix)
827:         {
828:                 if (array == null)
829:                 {
830:                         return new char[] { prefix, suffix };
831:                 }
832:
833:                 int length = array.length;
834:                 char[] result = new char[length + 2];
835:                 result[0] = prefix;
836:                 System.arraycopy(array, 0, result, 1, length);
837:                 result[length + 1] = suffix;
838:                 return result;
839:         }
840:
841:         /**
842:          * Answers the concatenation of the given array parts using the given separator between each part and appending the
843:          * given name at the end. <br>
844:          * <br>
845:          * For example:<br>
846:          * <ol>
847:          * <li>
848:          *
849:          * <pre>
850:          * name = { 'c' }
851:          * array = { { 'a' }, { 'b' } }
852:          * separator = '.'
853:          * => result = { 'a', '.', 'b' , '.', 'c' }
854:          * </pre>
855:          *
856:          * </li>
857:          * <li>
858:          *
859:          * <pre>
860:          * name = null
861:          * array = { { 'a' }, { 'b' } }
862:          * separator = '.'
863:          * => result = { 'a', '.', 'b' }
864:          * </pre>
865:          *
866:          * </li>
867:          * <li>
868:          *
869:          * <pre>
870:          * name = { ' c' }
871:          * array = null
872:          * separator = '.'
873:          * => result = { 'c' }
874:          * </pre>
875:          *
876:          * </li>
877:          * </ol>
878:          *
879:          * @param name
880:          * the given name
881:          * @param array
882:          * the given array
883:          * @param separator
884:          * the given separator
885:          * @return the concatenation of the given array parts using the given separator between each part and appending the
886:          * given name at the end
887:          */
888:         public static final char[] concatWith(char[] name, char[][] array,
889:                         char separator)
890:         {
891:                 int nameLength = name == null ? 0 : name.length;
892:                 if (nameLength == 0)
893:                 {
894:                         return concatWith(array, separator);
895:                 }
896:
897:                 int length = array == null ? 0 : array.length;
898:                 if (length == 0)
899:                 {
900:                         return name;
901:                 }
902:
903:                 int size = nameLength;
904:                 int index = length;
905:                 while (--index >= 0)
906:                 {
907:                         if (array[index].length > 0)
908:                         {
909:                                 size += array[index].length + 1;
910:                         }
911:                 }
912:                 char[] result = new char[size];
913:                 index = size;
914:                 for (int i = length - 1; i >= 0; i--)
915:                 {
916:                         int subLength = array[i].length;
917:                         if (subLength > 0)
918:                         {
919:                                 index -= subLength;
920:                                 System.arraycopy(array[i], 0, result, index, subLength);
921:                                 result[--index] = separator;
922:                         }
923:                 }
924:                 System.arraycopy(name, 0, result, 0, nameLength);
925:                 return result;
926:         }
927:
928:         /**
929:          * Answers the concatenation of the given array parts using the given separator between each part and appending the
930:          * given name at the end. <br>
931:          * <br>
932:          * For example:<br>
933:          * <ol>
934:          * <li>
935:          *
936:          * <pre>
937:          * name = { 'c' }
938:          * array = { { 'a' }, { 'b' } }
939:          * separator = '.'
940:          * => result = { 'a', '.', 'b' , '.', 'c' }
941:          * </pre>
942:          *
943:          * </li>
944:          * <li>
945:          *
946:          * <pre>
947:          * name = null
948:          * array = { { 'a' }, { 'b' } }
949:          * separator = '.'
950:          * => result = { 'a', '.', 'b' }
951:          * </pre>
952:          *
953:          * </li>
954:          * <li>
955:          *
956:          * <pre>
957:          * name = { ' c' }
958:          * array = null
959:          * separator = '.'
960:          * => result = { 'c' }
961:          * </pre>
962:          *
963:          * </li>
964:          * </ol>
965:          *
966:          * @param array
967:          * the given array
968:          * @param name
969:          * the given name
970:          * @param separator
971:          * the given separator
972:          * @return the concatenation of the given array parts using the given separator between each part and appending the
973:          * given name at the end
974:          */
975:         public static final char[] concatWith(char[][] array, char[] name,
976:                         char separator)
977:         {
978:                 int nameLength = name == null ? 0 : name.length;
979:                 if (nameLength == 0)
980:                 {
981:                         return concatWith(array, separator);
982:                 }
983:
984:                 int length = array == null ? 0 : array.length;
985:                 if (length == 0)
986:                 {
987:                         return name;
988:                 }
989:
990:                 int size = nameLength;
991:                 int index = length;
992:                 while (--index >= 0)
993:                 {
994:                         if (array[index].length > 0)
995:                         {
996:                                 size += array[index].length + 1;
997:                         }
998:                 }
999:                 char[] result = new char[size];
1000:                 index = 0;
1001:                 for (int i = 0; i < length; i++)
1002:                 {
1003:                         int subLength = array[i].length;
1004:                         if (subLength > 0)
1005:                         {
1006:                                 System.arraycopy(array[i], 0, result, index, subLength);
1007:                                 index += subLength;
1008:                                 result[index++] = separator;
1009:                         }
1010:                 }
1011:                 System.arraycopy(name, 0, result, index, nameLength);
1012:                 return result;
1013:         }
1014:
1015:         /**
1016:          * Answers the concatenation of the given array parts using the given separator between each part. <br>
1017:          * <br>
1018:          * For example:<br>
1019:          * <ol>
1020:          * <li>
1021:          *
1022:          * <pre>
1023:          * array = { { 'a' }, { 'b' } }
1024:          * separator = '.'
1025:          * => result = { 'a', '.', 'b' }
1026:          * </pre>
1027:          *
1028:          * </li>
1029:          * <li>
1030:          *
1031:          * <pre>
1032:          * array = null
1033:          * separator = '.'
1034:          * => result = { }
1035:          * </pre>
1036:          *
1037:          * </li>
1038:          * </ol>
1039:          *
1040:          * @param array
1041:          * the given array
1042:          * @param separator
1043:          * the given separator
1044:          * @return the concatenation of the given array parts using the given separator between each part
1045:          */
1046:         public static final char[] concatWith(char[][] array, char separator)
1047:         {
1048:                 int length = array == null ? 0 : array.length;
1049:                 if (length == 0)
1050:                 {
1051:                         return CharOperation.NO_CHAR;
1052:                 }
1053:
1054:                 int size = length - 1;
1055:                 int index = length;
1056:                 while (--index >= 0)
1057:                 {
1058:                         if (array[index].length == 0)
1059:                         {
1060:                                 size--;
1061:                         } else
1062:                         {
1063:                                 size += array[index].length;
1064:                         }
1065:                 }
1066:                 if (size <= 0)
1067:                 {
1068:                         return CharOperation.NO_CHAR;
1069:                 }
1070:                 char[] result = new char[size];
1071:                 index = length;
1072:                 while (--index >= 0)
1073:                 {
1074:                         length = array[index].length;
1075:                         if (length > 0)
1076:                         {
1077:                                 System.arraycopy(array[index], 0, result, size -= length, length);
1078:                                 if (--size >= 0)
1079:                                 {
1080:                                         result[size] = separator;
1081:                                 }
1082:                         }
1083:                 }
1084:                 return result;
1085:         }
1086:
1087:         public static final char[] concatWith(String[] array, char separator)
1088:         {
1089:                 int length = array == null ? 0 : array.length;
1090:                 if (length == 0)
1091:                 {
1092:                         return CharOperation.NO_CHAR;
1093:                 }
1094:
1095:                 int size = length - 1;
1096:                 int index = length;
1097:                 while (--index >= 0)
1098:                 {
1099:                         final int len = array[index].length();
1100:                         if (len == 0)
1101:                         {
1102:                                 size--;
1103:                         } else
1104:                         {
1105:                                 size += len;
1106:                         }
1107:                 }
1108:                 if (size <= 0)
1109:                 {
1110:                         return CharOperation.NO_CHAR;
1111:                 }
1112:                 char[] result = new char[size];
1113:                 index = length;
1114:                 while (--index >= 0)
1115:                 {
1116:                         length = array[index].length();
1117:                         if (length > 0)
1118:                         {
1119:                                 array[index].getChars(0, length, result, size -= length);
1120:                                 if (--size >= 0)
1121:                                 {
1122:                                         result[size] = separator;
1123:                                 }
1124:                         }
1125:                 }
1126:                 return result;
1127:         }
1128:
1129:         /**
1130:          * Answers true if the array contains an occurrence of character, false otherwise. <br>
1131:          * <br>
1132:          * For example:
1133:          * <ol>
1134:          * <li>
1135:          *
1136:          * <pre>
1137:          * character = 'c'
1138:          * array = { { ' a' }, { ' b' } }
1139:          * result => false
1140:          * </pre>
1141:          *
1142:          * </li>
1143:          * <li>
1144:          *
1145:          * <pre>
1146:          * character = 'a'
1147:          * array = { { ' a' }, { ' b' } }
1148:          * result => true
1149:          * </pre>
1150:          *
1151:          * </li>
1152:          * </ol>
1153:          *
1154:          * @param character
1155:          * the character to search
1156:          * @param array
1157:          * the array in which the search is done
1158:          * @return true if the array contains an occurrence of character, false otherwise.
1159:          * @throws NullPointerException
1160:          * if array is null.
1161:          */
1162:         public static final boolean contains(char character, char[][] array)
1163:         {
1164:                 for (int i = array.length; --i >= 0;)
1165:                 {
1166:                         char[] subarray = array[i];
1167:                         for (int j = subarray.length; --j >= 0;)
1168:                         {
1169:                                 if (subarray[j] == character)
1170:                                 {
1171:                                         return true;
1172:                                 }
1173:                         }
1174:                 }
1175:                 return false;
1176:         }
1177:
1178:         /**
1179:          * Answers true if the array contains an occurrence of character, false otherwise. <br>
1180:          * <br>
1181:          * For example:
1182:          * <ol>
1183:          * <li>
1184:          *
1185:          * <pre>
1186:          * character = 'c'
1187:          * array = { ' b' }
1188:          * result => false
1189:          * </pre>
1190:          *
1191:          * </li>
1192:          * <li>
1193:          *
1194:          * <pre>
1195:          * character = 'a'
1196:          * array = { ' a' , ' b' }
1197:          * result => true
1198:          * </pre>
1199:          *
1200:          * </li>
1201:          * </ol>
1202:          *
1203:          * @param character
1204:          * the character to search
1205:          * @param array
1206:          * the array in which the search is done
1207:          * @return true if the array contains an occurrence of character, false otherwise.
1208:          * @throws NullPointerException
1209:          * if array is null.
1210:          */
1211:         public static final boolean contains(char character, char[] array)
1212:         {
1213:                 for (int i = array.length; --i >= 0;)
1214:                 {
1215:                         if (array[i] == character)
1216:                         {
1217:                                 return true;
1218:                         }
1219:                 }
1220:                 return false;
1221:         }
1222:
1223:         /**
1224:          * Answers true if the array contains an occurrence of one of the characters, false otherwise. <br>
1225:          * <br>
1226:          * For example:
1227:          * <ol>
1228:          * <li>
1229:          *
1230:          * <pre>
1231:          * characters = { 'c', 'd' }
1232:          * array = { 'a', ' b' }
1233:          * result => false
1234:          * </pre>
1235:          *
1236:          * </li>
1237:          * <li>
1238:          *
1239:          * <pre>
1240:          * characters = { 'c', 'd' }
1241:          * array = { 'a', ' b', 'c' }
1242:          * result => true
1243:          * </pre>
1244:          *
1245:          * </li>
1246:          * </ol>
1247:          *
1248:          * @param characters
1249:          * the characters to search
1250:          * @param array
1251:          * the array in which the search is done
1252:          * @return true if the array contains an occurrence of one of the characters, false otherwise.
1253:          * @throws NullPointerException
1254:          * if array is null.
1255:          */
1256:         public static final boolean contains(char[] characters, char[] array)
1257:         {
1258:                 for (int i = array.length; --i >= 0;)
1259:                 {
1260:                         for (int j = characters.length; --j >= 0;)
1261:                         {
1262:                                 if (array[i] == characters[j])
1263:                                 {
1264:                                         return true;
1265:                                 }
1266:                         }
1267:                 }
1268:                 return false;
1269:         }
1270:
1271:         /**
1272:          * Answers a deep copy of the toCopy array.
1273:          *
1274:          * @param toCopy
1275:          * the array to copy
1276:          * @return a deep copy of the toCopy array.
1277:          */
1278:
1279:         public static final char[][] deepCopy(char[][] toCopy)
1280:         {
1281:                 int toCopyLength = toCopy.length;
1282:                 char[][] result = new char[toCopyLength][];
1283:                 for (int i = 0; i < toCopyLength; i++)
1284:                 {
1285:                         char[] toElement = toCopy[i];
1286:                         int toElementLength = toElement.length;
1287:                         char[] resultElement = new char[toElementLength];
1288:                         System.arraycopy(toElement, 0, resultElement, 0, toElementLength);
1289:                         result[i] = resultElement;
1290:                 }
1291:                 return result;
1292:         }
1293:
1294:         /**
1295:          * Return <code>true</code> if array starts with the sequence of characters contained in toBeFound, otherwise
1296:          * <code>false</code>.
1297:          *
1298:          * @param array
1299:          * @param toBeFound
1300:          * @return
1301:          */
1302:         public static final boolean startsWith(char[] array, char[] toBeFound)
1303:         {
1304:                 int i = toBeFound.length;
1305:                 if (array.length < i)
1306:                 {
1307:                         return false;
1308:                 }
1309:                 while (--i >= 0)
1310:                 {
1311:                         if (toBeFound[i] != array[i])
1312:                         {
1313:                                 return false;
1314:                         }
1315:                 }
1316:                 return true;
1317:         }
1318:
1319:         /**
1320:          * Return true if array ends with the sequence of characters contained in toBeFound, otherwise false. <br>
1321:          * <br>
1322:          * For example:
1323:          * <ol>
1324:          * <li>
1325:          *
1326:          * <pre>
1327:          * array = { 'a', 'b', 'c', 'd' }
1328:          * toBeFound = { 'b', 'c' }
1329:          * result => false
1330:          * </pre>
1331:          *
1332:          * </li>
1333:          * <li>
1334:          *
1335:          * <pre>
1336:          * array = { 'a', 'b', 'c' }
1337:          * toBeFound = { 'b', 'c' }
1338:          * result => true
1339:          * </pre>
1340:          *
1341:          * </li>
1342:          * </ol>
1343:          *
1344:          * @param array
1345:          * the array to check
1346:          * @param toBeFound
1347:          * the array to find
1348:          * @return true if array ends with the sequence of characters contained in toBeFound, otherwise false.
1349:          * @throws NullPointerException
1350:          * if array is null or toBeFound is null
1351:          */
1352:         public static final boolean endsWith(char[] array, char[] toBeFound)
1353:         {
1354:                 int i = toBeFound.length;
1355:                 int j = array.length - i;
1356:
1357:                 if (j < 0)
1358:                 {
1359:                         return false;
1360:                 }
1361:                 while (--i >= 0)
1362:                 {
1363:                         if (toBeFound[i] != array[i + j])
1364:                         {
1365:                                 return false;
1366:                         }
1367:                 }
1368:                 return true;
1369:         }
1370:
1371:         /**
1372:          * Answers true if the two arrays are identical character by character, otherwise false. The equality is case
1373:          * sensitive. <br>
1374:          * <br>
1375:          * For example:
1376:          * <ol>
1377:          * <li>
1378:          *
1379:          * <pre>
1380:          * first = null
1381:          * second = null
1382:          * result => true
1383:          * </pre>
1384:          *
1385:          * </li>
1386:          * <li>
1387:          *
1388:          * <pre>
1389:          * first = { { } }
1390:          * second = null
1391:          * result => false
1392:          * </pre>
1393:          *
1394:          * </li>
1395:          * <li>
1396:          *
1397:          * <pre>
1398:          * first = { { 'a' } }
1399:          * second = { { 'a' } }
1400:          * result => true
1401:          * </pre>
1402:          *
1403:          * </li>
1404:          * <li>
1405:          *
1406:          * <pre>
1407:          * first = { { 'A' } }
1408:          * second = { { 'a' } }
1409:          * result => false
1410:          * </pre>
1411:          *
1412:          * </li>
1413:          * </ol>
1414:          *
1415:          * @param first
1416:          * the first array
1417:          * @param second
1418:          * the second array
1419:          * @return true if the two arrays are identical character by character, otherwise false
1420:          */
1421:         public static final boolean equals(char[][] first, char[][] second)
1422:         {
1423:•                if (first == second)
1424:                 {
1425:                         return true;
1426:                 }
1427:•                if (first == null || second == null)
1428:                 {
1429:                         return false;
1430:                 }
1431:•                if (first.length != second.length)
1432:                 {
1433:                         return false;
1434:                 }
1435:
1436:•                for (int i = first.length; --i >= 0;)
1437:                 {
1438:•                        if (!equals(first[i], second[i]))
1439:                         {
1440:                                 return false;
1441:                         }
1442:                 }
1443:                 return true;
1444:         }
1445:
1446:         /**
1447:          * Compares two strings null-safe.
1448:          *
1449:          * @param first
1450:          * @param second
1451:          * @return
1452:          */
1453:         public static final boolean equals(String first, String second)
1454:         {
1455:                 if (first == second)
1456:                 {
1457:                         return true;
1458:                 } else if (first == null || second == null)
1459:                 {
1460:                         return false;
1461:                 } else
1462:                 {
1463:                         return first.equals(second);
1464:                 }
1465:         }
1466:
1467:         public static final boolean equals(String[] first, String[] second)
1468:         {
1469:                 if (first == second)
1470:                 {
1471:                         return true;
1472:                 }
1473:                 if (first == null || second == null)
1474:                 {
1475:                         return false;
1476:                 }
1477:                 if (first.length != second.length)
1478:                 {
1479:                         return false;
1480:                 }
1481:
1482:                 for (int i = first.length; --i >= 0;)
1483:                 {
1484:                         if (first[i] == null && second[i] != null)
1485:                         {
1486:                                 return false;
1487:                         }
1488:                         if (first[i] != null && second[i] == null)
1489:                         {
1490:                                 return false;
1491:                         }
1492:                         if (first[i] != null && !first[i].equals(second[i]))
1493:                         {
1494:                                 return false;
1495:                         }
1496:                 }
1497:                 return true;
1498:         }
1499:
1500:         /**
1501:          * If isCaseSensite is true, answers true if the two arrays are identical character by character, otherwise false.
1502:          * If it is false, answers true if the two arrays are identical character by character without checking the case,
1503:          * otherwise false. <br>
1504:          * <br>
1505:          * For example:
1506:          * <ol>
1507:          * <li>
1508:          *
1509:          * <pre>
1510:          * first = null
1511:          * second = null
1512:          * isCaseSensitive = true
1513:          * result => true
1514:          * </pre>
1515:          *
1516:          * </li>
1517:          * <li>
1518:          *
1519:          * <pre>
1520:          * first = { { } }
1521:          * second = null
1522:          * isCaseSensitive = true
1523:          * result => false
1524:          * </pre>
1525:          *
1526:          * </li>
1527:          * <li>
1528:          *
1529:          * <pre>
1530:          * first = { { 'A' } }
1531:          * second = { { 'a' } }
1532:          * isCaseSensitive = true
1533:          * result => false
1534:          * </pre>
1535:          *
1536:          * </li>
1537:          * <li>
1538:          *
1539:          * <pre>
1540:          * first = { { 'A' } }
1541:          * second = { { 'a' } }
1542:          * isCaseSensitive = false
1543:          * result => true
1544:          * </pre>
1545:          *
1546:          * </li>
1547:          * </ol>
1548:          *
1549:          * @param first
1550:          * the first array
1551:          * @param second
1552:          * the second array
1553:          * @param isCaseSensitive
1554:          * check whether or not the equality should be case sensitive
1555:          * @return true if the two arrays are identical character by character according to the value of isCaseSensitive,
1556:          * otherwise false
1557:          */
1558:         public static final boolean equals(char[][] first, char[][] second,
1559:                         boolean isCaseSensitive)
1560:         {
1561:
1562:                 if (isCaseSensitive)
1563:                 {
1564:                         return equals(first, second);
1565:                 }
1566:                 if (first == second)
1567:                 {
1568:                         return true;
1569:                 }
1570:                 if (first == null || second == null)
1571:                 {
1572:                         return false;
1573:                 }
1574:                 if (first.length != second.length)
1575:                 {
1576:                         return false;
1577:                 }
1578:
1579:                 for (int i = first.length; --i >= 0;)
1580:                 {
1581:                         if (!equals(first[i], second[i], false))
1582:                         {
1583:                                 return false;
1584:                         }
1585:                 }
1586:                 return true;
1587:         }
1588:
1589:         /**
1590:          * Answers true if the two arrays are identical character by character, otherwise false. The equality is case
1591:          * sensitive. <br>
1592:          * <br>
1593:          * For example:
1594:          * <ol>
1595:          * <li>
1596:          *
1597:          * <pre>
1598:          * first = null
1599:          * second = null
1600:          * result => true
1601:          * </pre>
1602:          *
1603:          * </li>
1604:          * <li>
1605:          *
1606:          * <pre>
1607:          * first = { }
1608:          * second = null
1609:          * result => false
1610:          * </pre>
1611:          *
1612:          * </li>
1613:          * <li>
1614:          *
1615:          * <pre>
1616:          * first = { 'a' }
1617:          * second = { 'a' }
1618:          * result => true
1619:          * </pre>
1620:          *
1621:          * </li>
1622:          * <li>
1623:          *
1624:          * <pre>
1625:          * first = { 'a' }
1626:          * second = { 'A' }
1627:          * result => false
1628:          * </pre>
1629:          *
1630:          * </li>
1631:          * </ol>
1632:          *
1633:          * @param first
1634:          * the first array
1635:          * @param second
1636:          * the second array
1637:          * @return true if the two arrays are identical character by character, otherwise false
1638:          */
1639:         public static final boolean equals(char[] first, char[] second)
1640:         {
1641:                 if (first == second)
1642:                 {
1643:                         return true;
1644:                 }
1645:                 if (first == null || second == null)
1646:                 {
1647:                         return false;
1648:                 }
1649:                 if (first.length != second.length)
1650:                 {
1651:                         return false;
1652:                 }
1653:
1654:                 for (int i = first.length; --i >= 0;)
1655:                 {
1656:                         if (first[i] != second[i])
1657:                         {
1658:                                 return false;
1659:                         }
1660:                 }
1661:                 return true;
1662:         }
1663:
1664:         /**
1665:          * Answers true if the first array is identical character by character to a portion of the second array delimited
1666:          * from position secondStart (inclusive) to secondEnd(exclusive), otherwise false. The equality is case sensitive. <br>
1667:          * <br>
1668:          * For example:
1669:          * <ol>
1670:          * <li>
1671:          *
1672:          * <pre>
1673:          * first = null
1674:          * second = null
1675:          * secondStart = 0
1676:          * secondEnd = 0
1677:          * result => true
1678:          * </pre>
1679:          *
1680:          * </li>
1681:          * <li>
1682:          *
1683:          * <pre>
1684:          * first = { }
1685:          * second = null
1686:          * secondStart = 0
1687:          * secondEnd = 0
1688:          * result => false
1689:          * </pre>
1690:          *
1691:          * </li>
1692:          * <li>
1693:          *
1694:          * <pre>
1695:          * first = { 'a' }
1696:          * second = { 'a' }
1697:          * secondStart = 0
1698:          * secondEnd = 1
1699:          * result => true
1700:          * </pre>
1701:          *
1702:          * </li>
1703:          * <li>
1704:          *
1705:          * <pre>
1706:          * first = { 'a' }
1707:          * second = { 'A' }
1708:          * secondStart = 0
1709:          * secondEnd = 1
1710:          * result => false
1711:          * </pre>
1712:          *
1713:          * </li>
1714:          * </ol>
1715:          *
1716:          * @param first
1717:          * the first array
1718:          * @param second
1719:          * the second array
1720:          * @param secondStart
1721:          * inclusive start position in the second array to compare
1722:          * @param secondEnd
1723:          * exclusive end position in the second array to compare
1724:          * @return true if the first array is identical character by character to fragment of second array ranging from
1725:          * secondStart to secondEnd-1, otherwise false
1726:          */
1727:         public static final boolean equals(char[] first, char[] second,
1728:                         int secondStart, int secondEnd)
1729:         {
1730:                 if (first == second)
1731:                 {
1732:                         return true;
1733:                 }
1734:                 if (first == null || second == null)
1735:                 {
1736:                         return false;
1737:                 }
1738:                 if (first.length != secondEnd - secondStart)
1739:                 {
1740:                         return false;
1741:                 }
1742:
1743:                 for (int i = first.length; --i >= 0;)
1744:                 {
1745:                         if (first[i] != second[i + secondStart])
1746:                         {
1747:                                 return false;
1748:                         }
1749:                 }
1750:                 return true;
1751:         }
1752:
1753:         /**
1754:          * If isCaseSensite is true, answers true if the two arrays are identical character by character, otherwise false.
1755:          * If it is false, answers true if the two arrays are identical character by character without checking the case,
1756:          * otherwise false. <br>
1757:          * <br>
1758:          * For example:
1759:          * <ol>
1760:          * <li>
1761:          *
1762:          * <pre>
1763:          * first = null
1764:          * second = null
1765:          * isCaseSensitive = true
1766:          * result => true
1767:          * </pre>
1768:          *
1769:          * </li>
1770:          * <li>
1771:          *
1772:          * <pre>
1773:          * first = { }
1774:          * second = null
1775:          * isCaseSensitive = true
1776:          * result => false
1777:          * </pre>
1778:          *
1779:          * </li>
1780:          * <li>
1781:          *
1782:          * <pre>
1783:          * first = { 'A' }
1784:          * second = { 'a' }
1785:          * isCaseSensitive = true
1786:          * result => false
1787:          * </pre>
1788:          *
1789:          * </li>
1790:          * <li>
1791:          *
1792:          * <pre>
1793:          * first = { 'A' }
1794:          * second = { 'a' }
1795:          * isCaseSensitive = false
1796:          * result => true
1797:          * </pre>
1798:          *
1799:          * </li>
1800:          * </ol>
1801:          *
1802:          * @param first
1803:          * the first array
1804:          * @param second
1805:          * the second array
1806:          * @param isCaseSensitive
1807:          * check whether or not the equality should be case sensitive
1808:          * @return true if the two arrays are identical character by character according to the value of isCaseSensitive,
1809:          * otherwise false
1810:          */
1811:         public static final boolean equals(char[] first, char[] second,
1812:                         boolean isCaseSensitive)
1813:         {
1814:
1815:                 if (isCaseSensitive)
1816:                 {
1817:                         return equals(first, second);
1818:                 }
1819:                 if (first == second)
1820:                 {
1821:                         return true;
1822:                 }
1823:                 if (first == null || second == null)
1824:                 {
1825:                         return false;
1826:                 }
1827:                 if (first.length != second.length)
1828:                 {
1829:                         return false;
1830:                 }
1831:
1832:                 for (int i = first.length; --i >= 0;)
1833:                 {
1834:                         if (Character.toLowerCase(first[i]) != Character.toLowerCase(second[i]))
1835:                         {
1836:                                 return false;
1837:                         }
1838:                 }
1839:                 return true;
1840:         }
1841:
1842:         /**
1843:          * If isCaseSensite is true, the equality is case sensitive, otherwise it is case insensitive. Answers true if the
1844:          * name contains the fragment at the starting index startIndex, otherwise false. <br>
1845:          * <br>
1846:          * For example:
1847:          * <ol>
1848:          * <li>
1849:          *
1850:          * <pre>
1851:          * fragment = { 'b', 'c' , 'd' }
1852:          * name = { 'a', 'b', 'c' , 'd' }
1853:          * startIndex = 1
1854:          * isCaseSensitive = true
1855:          * result => true
1856:          * </pre>
1857:          *
1858:          * </li>
1859:          * <li>
1860:          *
1861:          * <pre>
1862:          * fragment = { 'b', 'c' , 'd' }
1863:          * name = { 'a', 'b', 'C' , 'd' }
1864:          * startIndex = 1
1865:          * isCaseSensitive = true
1866:          * result => false
1867:          * </pre>
1868:          *
1869:          * </li>
1870:          * <li>
1871:          *
1872:          * <pre>
1873:          * fragment = { 'b', 'c' , 'd' }
1874:          * name = { 'a', 'b', 'C' , 'd' }
1875:          * startIndex = 0
1876:          * isCaseSensitive = false
1877:          * result => false
1878:          * </pre>
1879:          *
1880:          * </li>
1881:          * <li>
1882:          *
1883:          * <pre>
1884:          * fragment = { 'b', 'c' , 'd' }
1885:          * name = { 'a', 'b'}
1886:          * startIndex = 0
1887:          * isCaseSensitive = true
1888:          * result => false
1889:          * </pre>
1890:          *
1891:          * </li>
1892:          * </ol>
1893:          *
1894:          * @param fragment
1895:          * the fragment to check
1896:          * @param name
1897:          * the array to check
1898:          * @param startIndex
1899:          * the starting index
1900:          * @param isCaseSensitive
1901:          * check whether or not the equality should be case sensitive
1902:          * @return true if the name contains the fragment at the starting index startIndex according to the value of
1903:          * isCaseSensitive, otherwise false.
1904:          * @throws NullPointerException
1905:          * if fragment or name is null.
1906:          */
1907:         public static final boolean fragmentEquals(char[] fragment, char[] name,
1908:                         int startIndex, boolean isCaseSensitive)
1909:         {
1910:
1911:                 int max = fragment.length;
1912:                 if (name.length < max + startIndex)
1913:                 {
1914:                         return false;
1915:                 }
1916:                 if (isCaseSensitive)
1917:                 {
1918:                         for (int i = max; --i >= 0;)
1919:                         {
1920:                                 // assumes the prefix is not larger than the name
1921:                                 if (fragment[i] != name[i + startIndex])
1922:                                 {
1923:                                         return false;
1924:                                 }
1925:                         }
1926:                         return true;
1927:                 }
1928:                 for (int i = max; --i >= 0;)
1929:                 {
1930:                         // assumes the prefix is not larger than the name
1931:                         if (Character.toLowerCase(fragment[i]) != Character.toLowerCase(name[i
1932:                                         + startIndex]))
1933:                         {
1934:                                 return false;
1935:                         }
1936:                 }
1937:                 return true;
1938:         }
1939:
1940:         /**
1941:          * Answers a hashcode for the array
1942:          *
1943:          * @param array
1944:          * the array for which a hashcode is required
1945:          * @return the hashcode
1946:          * @throws NullPointerException
1947:          * if array is null
1948:          */
1949:         public static final int hashCode(char[] array)
1950:         {
1951:                 int length = array.length;
1952:                 int hash = length == 0 ? 31 : array[0];
1953:                 if (length < 8)
1954:                 {
1955:                         for (int i = length; --i > 0;)
1956:                         {
1957:                                 hash = hash * 31 + array[i];
1958:                         }
1959:                 } else
1960:                 {
1961:                         // 8 characters is enough to compute a decent hash code, don't waste
1962:                         // time examining every character
1963:                         for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2)
1964:                         {
1965:                                 hash = hash * 31 + array[i];
1966:                         }
1967:                 }
1968:                 return hash & 0x7FFFFFFF;
1969:         }
1970:
1971:         /**
1972:          * Answers true if c is a whitespace according to the JLS (\u000a, \u000c, \u000d, \u0009),
1973:          * otherwise false. <br>
1974:          * <br>
1975:          * For example:
1976:          * <ol>
1977:          * <li>
1978:          *
1979:          * <pre>
1980:          * c = ' '
1981:          * result => true
1982:          * </pre>
1983:          *
1984:          * </li>
1985:          * <li>
1986:          *
1987:          * <pre>
1988:          * c = ' \u3000'
1989:          * result => false
1990:          * </pre>
1991:          *
1992:          * </li>
1993:          * </ol>
1994:          *
1995:          * @param c
1996:          * the character to check
1997:          * @return true if c is a whitespace according to the JLS, otherwise false.
1998:          */
1999:         public static boolean isWhitespace(char c)
2000:         {
2001:                 switch (c)
2002:                 {
2003:                         case 10: /* \ u000a: LINE FEED */
2004:                         case 12: /* \ u000c: FORM FEED */
2005:                         case 13: /* \ u000d: CARRIAGE RETURN */
2006:                         case 32: /* \ u0020: SPACE */
2007:                         case 9: /* \ u0009: HORIZONTAL TABULATION */
2008:                                 return true;
2009:                         default:
2010:                                 return false;
2011:                 }
2012:         }
2013:
2014:         /**
2015:          * Answers the first index in the array for which the corresponding character is equal to toBeFound. Answers -1 if
2016:          * no occurrence of this character is found. <br>
2017:          * <br>
2018:          * For example:
2019:          * <ol>
2020:          * <li>
2021:          *
2022:          * <pre>
2023:          * toBeFound = 'c'
2024:          * array = { ' a', 'b', 'c', 'd' }
2025:          * result => 2
2026:          * </pre>
2027:          *
2028:          * </li>
2029:          * <li>
2030:          *
2031:          * <pre>
2032:          * toBeFound = 'e'
2033:          * array = { ' a', 'b', 'c', 'd' }
2034:          * result => -1
2035:          * </pre>
2036:          *
2037:          * </li>
2038:          * </ol>
2039:          *
2040:          * @param toBeFound
2041:          * the character to search
2042:          * @param array
2043:          * the array to be searched
2044:          * @return the first index in the array for which the corresponding character is equal to toBeFound, -1 otherwise
2045:          * @throws NullPointerException
2046:          * if array is null
2047:          */
2048:         public static final int indexOf(char toBeFound, char[] array)
2049:         {
2050:                 return indexOf(toBeFound, array, 0);
2051:         }
2052:
2053:         /**
2054:          * Answers the first index in the array for which the toBeFound array is a matching subarray following the case
2055:          * rule. Answers -1 if no match is found. <br>
2056:          * <br>
2057:          * For example:
2058:          * <ol>
2059:          * <li>
2060:          *
2061:          * <pre>
2062:          * toBeFound = { 'c' }
2063:          * array = { ' a', 'b', 'c', 'd' }
2064:          * result => 2
2065:          * </pre>
2066:          *
2067:          * </li>
2068:          * <li>
2069:          *
2070:          * <pre>
2071:          * toBeFound = { 'e' }
2072:          * array = { ' a', 'b', 'c', 'd' }
2073:          * result => -1
2074:          * </pre>
2075:          *
2076:          * </li>
2077:          * </ol>
2078:          *
2079:          * @param toBeFound
2080:          * the subarray to search
2081:          * @param array
2082:          * the array to be searched
2083:          * @param isCaseSensitive
2084:          * flag to know if the matching should be case sensitive
2085:          * @return the first index in the array for which the toBeFound array is a matching subarray following the case
2086:          * rule, -1 otherwise
2087:          * @throws NullPointerException
2088:          * if array is null or toBeFound is null
2089:          */
2090:         public static final int indexOf(char[] toBeFound, char[] array,
2091:                         boolean isCaseSensitive)
2092:         {
2093:                 return indexOf(toBeFound, array, isCaseSensitive, 0);
2094:         }
2095:
2096:         /**
2097:          * Answers the first index in the array for which the toBeFound array is a matching subarray following the case rule
2098:          * starting at the index start. Answers -1 if no match is found. <br>
2099:          * <br>
2100:          * For example:
2101:          * <ol>
2102:          * <li>
2103:          *
2104:          * <pre>
2105:          * toBeFound = { 'c' }
2106:          * array = { ' a', 'b', 'c', 'd' }
2107:          * result => 2
2108:          * </pre>
2109:          *
2110:          * </li>
2111:          * <li>
2112:          *
2113:          * <pre>
2114:          * toBeFound = { 'e' }
2115:          * array = { ' a', 'b', 'c', 'd' }
2116:          * result => -1
2117:          * </pre>
2118:          *
2119:          * </li>
2120:          * </ol>
2121:          *
2122:          * @param toBeFound
2123:          * the subarray to search
2124:          * @param array
2125:          * the array to be searched
2126:          * @param isCaseSensitive
2127:          * flag to know if the matching should be case sensitive
2128:          * @param start
2129:          * the starting index
2130:          * @return the first index in the array for which the toBeFound array is a matching subarray following the case rule
2131:          * starting at the index start, -1 otherwise
2132:          * @throws NullPointerException
2133:          * if array is null or toBeFound is null
2134:          */
2135:         public static final int indexOf(final char[] toBeFound, final char[] array,
2136:                         final boolean isCaseSensitive, final int start)
2137:         {
2138:                 return indexOf(toBeFound, array, isCaseSensitive, start, array.length);
2139:         }
2140:
2141:         /**
2142:          * Answers the first index in the array for which the toBeFound array is a matching subarray following the case rule
2143:          * starting at the index start. Answers -1 if no match is found. <br>
2144:          * <br>
2145:          * For example:
2146:          * <ol>
2147:          * <li>
2148:          *
2149:          * <pre>
2150:          * toBeFound = { 'c' }
2151:          * array = { ' a', 'b', 'c', 'd' }
2152:          * result => 2
2153:          * </pre>
2154:          *
2155:          * </li>
2156:          * <li>
2157:          *
2158:          * <pre>
2159:          * toBeFound = { 'e' }
2160:          * array = { ' a', 'b', 'c', 'd' }
2161:          * result => -1
2162:          * </pre>
2163:          *
2164:          * </li>
2165:          * </ol>
2166:          *
2167:          * @param toBeFound
2168:          * the subarray to search
2169:          * @param array
2170:          * the array to be searched
2171:          * @param isCaseSensitive
2172:          * flag to know if the matching should be case sensitive
2173:          * @param start
2174:          * the starting index (inclusive)
2175:          * @param end
2176:          * the end index (exclusive)
2177:          * @return the first index in the array for which the toBeFound array is a matching subarray following the case rule
2178:          * starting at the index start, -1 otherwise
2179:          * @throws NullPointerException
2180:          * if array is null or toBeFound is null
2181:          */
2182:         public static final int indexOf(final char[] toBeFound, final char[] array,
2183:                         final boolean isCaseSensitive, final int start, final int end)
2184:         {
2185:                 final int arrayLength = end;
2186:                 final int toBeFoundLength = toBeFound.length;
2187:                 if (toBeFoundLength > arrayLength)
2188:                 {
2189:                         return -1;
2190:                 }
2191:                 if (toBeFoundLength == 0)
2192:                 {
2193:                         return 0;
2194:                 }
2195:                 if (toBeFoundLength == arrayLength)
2196:                 {
2197:                         if (isCaseSensitive)
2198:                         {
2199:                                 for (int i = start; i < arrayLength; i++)
2200:                                 {
2201:                                         if (array[i] != toBeFound[i])
2202:                                         {
2203:                                                 return -1;
2204:                                         }
2205:                                 }
2206:                                 return 0;
2207:                         } else
2208:                         {
2209:                                 for (int i = start; i < arrayLength; i++)
2210:                                 {
2211:                                         if (Character.toLowerCase(array[i]) != Character.toLowerCase(toBeFound[i]))
2212:                                         {
2213:                                                 return -1;
2214:                                         }
2215:                                 }
2216:                                 return 0;
2217:                         }
2218:                 }
2219:                 if (isCaseSensitive)
2220:                 {
2221:                         arrayLoop: for (int i = start, max = arrayLength - toBeFoundLength
2222:                                         + 1; i < max; i++)
2223:                         {
2224:                                 if (array[i] == toBeFound[0])
2225:                                 {
2226:                                         for (int j = 1; j < toBeFoundLength; j++)
2227:                                         {
2228:                                                 if (array[i + j] != toBeFound[j])
2229:                                                 {
2230:                                                         continue arrayLoop;
2231:                                                 }
2232:                                         }
2233:                                         return i;
2234:                                 }
2235:                         }
2236:                 } else
2237:                 {
2238:                         arrayLoop: for (int i = start, max = arrayLength - toBeFoundLength
2239:                                         + 1; i < max; i++)
2240:                         {
2241:                                 if (Character.toLowerCase(array[i]) == Character.toLowerCase(toBeFound[0]))
2242:                                 {
2243:                                         for (int j = 1; j < toBeFoundLength; j++)
2244:                                         {
2245:                                                 if (Character.toLowerCase(array[i + j]) != Character.toLowerCase(toBeFound[j]))
2246:                                                 {
2247:                                                         continue arrayLoop;
2248:                                                 }
2249:                                         }
2250:                                         return i;
2251:                                 }
2252:                         }
2253:                 }
2254:                 return -1;
2255:         }
2256:
2257:         /**
2258:          * Answers the first index in the array for which the corresponding character is equal to toBeFound starting the
2259:          * search at index start. Answers -1 if no occurrence of this character is found. <br>
2260:          * <br>
2261:          * For example:
2262:          * <ol>
2263:          * <li>
2264:          *
2265:          * <pre>
2266:          * toBeFound = 'c'
2267:          * array = { ' a', 'b', 'c', 'd' }
2268:          * start = 2
2269:          * result => 2
2270:          * </pre>
2271:          *
2272:          * </li>
2273:          * <li>
2274:          *
2275:          * <pre>
2276:          * toBeFound = 'c'
2277:          * array = { ' a', 'b', 'c', 'd' }
2278:          * start = 3
2279:          * result => -1
2280:          * </pre>
2281:          *
2282:          * </li>
2283:          * <li>
2284:          *
2285:          * <pre>
2286:          * toBeFound = 'e'
2287:          * array = { ' a', 'b', 'c', 'd' }
2288:          * start = 1
2289:          * result => -1
2290:          * </pre>
2291:          *
2292:          * </li>
2293:          * </ol>
2294:          *
2295:          * @param toBeFound
2296:          * the character to search
2297:          * @param array
2298:          * the array to be searched
2299:          * @param start
2300:          * the starting index
2301:          * @return the first index in the array for which the corresponding character is equal to toBeFound, -1 otherwise
2302:          * @throws NullPointerException
2303:          * if array is null
2304:          * @throws ArrayIndexOutOfBoundsException
2305:          * if start is lower than 0
2306:          */
2307:         public static final int indexOf(char toBeFound, char[] array, int start)
2308:         {
2309:                 for (int i = start; i < array.length; i++)
2310:                 {
2311:                         if (toBeFound == array[i])
2312:                         {
2313:                                 return i;
2314:                         }
2315:                 }
2316:                 return -1;
2317:         }
2318:
2319:         /**
2320:          * Answers the first index in the array for which the corresponding character is equal to toBeFound starting the
2321:          * search at index start and before the ending index. Answers -1 if no occurrence of this character is found. <br>
2322:          * <br>
2323:          * For example:
2324:          * <ol>
2325:          * <li>
2326:          *
2327:          * <pre>
2328:          * toBeFound = 'c'
2329:          * array = { ' a', 'b', 'c', 'd' }
2330:          * start = 2
2331:          * result => 2
2332:          * </pre>
2333:          *
2334:          * </li>
2335:          * <li>
2336:          *
2337:          * <pre>
2338:          * toBeFound = 'c'
2339:          * array = { ' a', 'b', 'c', 'd' }
2340:          * start = 3
2341:          * result => -1
2342:          * </pre>
2343:          *
2344:          * </li>
2345:          * <li>
2346:          *
2347:          * <pre>
2348:          * toBeFound = 'e'
2349:          * array = { ' a', 'b', 'c', 'd' }
2350:          * start = 1
2351:          * result => -1
2352:          * </pre>
2353:          *
2354:          * </li>
2355:          * </ol>
2356:          *
2357:          * @param toBeFound
2358:          * the character to search
2359:          * @param array
2360:          * the array to be searched
2361:          * @param start
2362:          * the starting index (inclusive)
2363:          * @param end
2364:          * the ending index (exclusive)
2365:          * @return the first index in the array for which the corresponding character is equal to toBeFound, -1 otherwise
2366:          * @throws NullPointerException
2367:          * if array is null
2368:          * @throws ArrayIndexOutOfBoundsException
2369:          * if start is lower than 0 or ending greater than array length
2370:          */
2371:         public static final int indexOf(char toBeFound, char[] array, int start,
2372:                         int end)
2373:         {
2374:                 for (int i = start; i < end; i++)
2375:                 {
2376:                         if (toBeFound == array[i])
2377:                         {
2378:                                 return i;
2379:                         }
2380:                 }
2381:                 return -1;
2382:         }
2383:
2384:         /**
2385:          * Answers the last index in the array for which the corresponding character is equal to toBeFound starting from the
2386:          * end of the array. Answers -1 if no occurrence of this character is found. <br>
2387:          * <br>
2388:          * For example:
2389:          * <ol>
2390:          * <li>
2391:          *
2392:          * <pre>
2393:          * toBeFound = 'c'
2394:          * array = { ' a', 'b', 'c', 'd' , 'c', 'e' }
2395:          * result => 4
2396:          * </pre>
2397:          *
2398:          * </li>
2399:          * <li>
2400:          *
2401:          * <pre>
2402:          * toBeFound = 'e'
2403:          * array = { ' a', 'b', 'c', 'd' }
2404:          * result => -1
2405:          * </pre>
2406:          *
2407:          * </li>
2408:          * </ol>
2409:          *
2410:          * @param toBeFound
2411:          * the character to search
2412:          * @param array
2413:          * the array to be searched
2414:          * @return the last index in the array for which the corresponding character is equal to toBeFound starting from the
2415:          * end of the array, -1 otherwise
2416:          * @throws NullPointerException
2417:          * if array is null
2418:          */
2419:         public static final int lastIndexOf(char toBeFound, char[] array)
2420:         {
2421:                 for (int i = array.length; --i >= 0;)
2422:                 {
2423:                         if (toBeFound == array[i])
2424:                         {
2425:                                 return i;
2426:                         }
2427:                 }
2428:                 return -1;
2429:         }
2430:
2431:         /**
2432:          * Answers the last index in the array for which the corresponding character is equal to toBeFound stopping at the
2433:          * index startIndex. Answers -1 if no occurrence of this character is found. <br>
2434:          * <br>
2435:          * For example:
2436:          * <ol>
2437:          * <li>
2438:          *
2439:          * <pre>
2440:          * toBeFound = 'c'
2441:          * array = { ' a', 'b', 'c', 'd' }
2442:          * startIndex = 2
2443:          * result => 2
2444:          * </pre>
2445:          *
2446:          * </li>
2447:          * <li>
2448:          *
2449:          * <pre>
2450:          * toBeFound = 'c'
2451:          * array = { ' a', 'b', 'c', 'd', 'e' }
2452:          * startIndex = 3
2453:          * result => -1
2454:          * </pre>
2455:          *
2456:          * </li>
2457:          * <li>
2458:          *
2459:          * <pre>
2460:          * toBeFound = 'e'
2461:          * array = { ' a', 'b', 'c', 'd' }
2462:          * startIndex = 0
2463:          * result => -1
2464:          * </pre>
2465:          *
2466:          * </li>
2467:          * </ol>
2468:          *
2469:          * @param toBeFound
2470:          * the character to search
2471:          * @param array
2472:          * the array to be searched
2473:          * @param startIndex
2474:          * the stopping index
2475:          * @return the last index in the array for which the corresponding character is equal to toBeFound stopping at the
2476:          * index startIndex, -1 otherwise
2477:          * @throws NullPointerException
2478:          * if array is null
2479:          * @throws ArrayIndexOutOfBoundsException
2480:          * if startIndex is lower than 0
2481:          */
2482:         public static final int lastIndexOf(char toBeFound, char[] array,
2483:                         int startIndex)
2484:         {
2485:                 for (int i = array.length; --i >= startIndex;)
2486:                 {
2487:                         if (toBeFound == array[i])
2488:                         {
2489:                                 return i;
2490:                         }
2491:                 }
2492:                 return -1;
2493:         }
2494:
2495:         /**
2496:          * Answers the last index in the array for which the corresponding character is equal to toBeFound starting from
2497:          * endIndex to startIndex. Answers -1 if no occurrence of this character is found. <br>
2498:          * <br>
2499:          * For example:
2500:          * <ol>
2501:          * <li>
2502:          *
2503:          * <pre>
2504:          * toBeFound = 'c'
2505:          * array = { ' a', 'b', 'c', 'd' }
2506:          * startIndex = 2
2507:          * endIndex = 2
2508:          * result => 2
2509:          * </pre>
2510:          *
2511:          * </li>
2512:          * <li>
2513:          *
2514:          * <pre>
2515:          * toBeFound = 'c'
2516:          * array = { ' a', 'b', 'c', 'd', 'e' }
2517:          * startIndex = 3
2518:          * endIndex = 4
2519:          * result => -1
2520:          * </pre>
2521:          *
2522:          * </li>
2523:          * <li>
2524:          *
2525:          * <pre>
2526:          * toBeFound = 'e'
2527:          * array = { ' a', 'b', 'c', 'd' }
2528:          * startIndex = 0
2529:          * endIndex = 3
2530:          * result => -1
2531:          * </pre>
2532:          *
2533:          * </li>
2534:          * </ol>
2535:          *
2536:          * @param toBeFound
2537:          * the character to search
2538:          * @param array
2539:          * the array to be searched
2540:          * @param startIndex
2541:          * the stopping index
2542:          * @param endIndex
2543:          * the starting index
2544:          * @return the last index in the array for which the corresponding character is equal to toBeFound starting from
2545:          * endIndex to startIndex, -1 otherwise
2546:          * @throws NullPointerException
2547:          * if array is null
2548:          * @throws ArrayIndexOutOfBoundsException
2549:          * if endIndex is greater or equals to array length or starting is lower than 0
2550:          */
2551:         public static final int lastIndexOf(char toBeFound, char[] array,
2552:                         int startIndex, int endIndex)
2553:         {
2554:                 for (int i = endIndex; --i >= startIndex;)
2555:                 {
2556:                         if (toBeFound == array[i])
2557:                         {
2558:                                 return i;
2559:                         }
2560:                 }
2561:                 return -1;
2562:         }
2563:
2564:         /**
2565:          * Answers the last portion of a name given a separator. <br>
2566:          * <br>
2567:          * For example,
2568:          *
2569:          * <pre>
2570:          *         lastSegment("java.lang.Object".toCharArray(),'.') --> Object
2571:          * </pre>
2572:          *
2573:          * @param array
2574:          * the array
2575:          * @param separator
2576:          * the given separator
2577:          * @return the last portion of a name given a separator
2578:          * @throws NullPointerException
2579:          * if array is null
2580:          */
2581:         final static public char[] lastSegment(char[] array, char separator)
2582:         {
2583:                 int pos = lastIndexOf(separator, array);
2584:                 if (pos < 0)
2585:                 {
2586:                         return array;
2587:                 }
2588:                 return subarray(array, pos + 1, array.length);
2589:         }
2590:
2591:         /**
2592:          * Answers true if the pattern matches the given name, false otherwise. This char[] pattern matching accepts
2593:          * wild-cards '*' and '?'. When not case sensitive, the pattern is assumed to already be lowercased, the name will
2594:          * be lowercased character per character as comparing. If name is null, the answer is false. If pattern is null, the
2595:          * answer is true if name is not null. <br>
2596:          * <br>
2597:          * For example:
2598:          * <ol>
2599:          * <li>
2600:          *
2601:          * <pre>
2602:          * pattern = { '?', 'b', '*' }
2603:          * name = { 'a', 'b', 'c' , 'd' }
2604:          * isCaseSensitive = true
2605:          * result => true
2606:          * </pre>
2607:          *
2608:          * </li>
2609:          * <li>
2610:          *
2611:          * <pre>
2612:          * pattern = { '?', 'b', '?' }
2613:          * name = { 'a', 'b', 'c' , 'd' }
2614:          * isCaseSensitive = true
2615:          * result => false
2616:          * </pre>
2617:          *
2618:          * </li>
2619:          * <li>
2620:          *
2621:          * <pre>
2622:          * pattern = { 'b', '*' }
2623:          * name = { 'a', 'b', 'c' , 'd' }
2624:          * isCaseSensitive = true
2625:          * result => false
2626:          * </pre>
2627:          *
2628:          * </li>
2629:          * </ol>
2630:          *
2631:          * @param pattern
2632:          * the given pattern
2633:          * @param name
2634:          * the given name
2635:          * @param isCaseSensitive
2636:          * flag to know whether or not the matching should be case sensitive
2637:          * @return true if the pattern matches the given name, false otherwise
2638:          */
2639:         public static final boolean match(char[] pattern, char[] name,
2640:                         boolean isCaseSensitive)
2641:         {
2642:
2643:                 if (name == null)
2644:                 {
2645:                         return false; // null name cannot match
2646:                 }
2647:                 if (pattern == null)
2648:                 {
2649:                         return true; // null pattern is equivalent to '*'
2650:                 }
2651:
2652:                 return match(pattern, 0, pattern.length, name, 0, name.length, isCaseSensitive);
2653:         }
2654:
2655:         /**
2656:          * Answers true if a sub-pattern matches the subpart of the given name, false otherwise. char[] pattern matching,
2657:          * accepting wild-cards '*' and '?'. Can match only subset of name/pattern. end positions are non-inclusive. The
2658:          * subpattern is defined by the patternStart and pattternEnd positions. When not case sensitive, the pattern is
2659:          * assumed to already be lowercased, the name will be lowercased character per character as comparing. <br>
2660:          * <br>
2661:          * For example:
2662:          * <ol>
2663:          * <li>
2664:          *
2665:          * <pre>
2666:          * pattern = { '?', 'b', '*' }
2667:          * patternStart = 1
2668:          * patternEnd = 3
2669:          * name = { 'a', 'b', 'c' , 'd' }
2670:          * nameStart = 1
2671:          * nameEnd = 4
2672:          * isCaseSensitive = true
2673:          * result => true
2674:          * </pre>
2675:          *
2676:          * </li>
2677:          * <li>
2678:          *
2679:          * <pre>
2680:          * pattern = { '?', 'b', '*' }
2681:          * patternStart = 1
2682:          * patternEnd = 2
2683:          * name = { 'a', 'b', 'c' , 'd' }
2684:          * nameStart = 1
2685:          * nameEnd = 2
2686:          * isCaseSensitive = true
2687:          * result => false
2688:          * </pre>
2689:          *
2690:          * </li>
2691:          * </ol>
2692:          *
2693:          * @param pattern
2694:          * the given pattern
2695:          * @param patternStart
2696:          * the given pattern start
2697:          * @param patternEnd
2698:          * the given pattern end
2699:          * @param name
2700:          * the given name
2701:          * @param nameStart
2702:          * the given name start
2703:          * @param nameEnd
2704:          * the given name end
2705:          * @param isCaseSensitive
2706:          * flag to know if the matching should be case sensitive
2707:          * @return true if a sub-pattern matches the subpart of the given name, false otherwise
2708:          */
2709:         public static final boolean match(char[] pattern, int patternStart,
2710:                         int patternEnd, char[] name, int nameStart, int nameEnd,
2711:                         boolean isCaseSensitive)
2712:         {
2713:
2714:                 if (name == null)
2715:                 {
2716:                         return false; // null name cannot match
2717:                 }
2718:                 if (pattern == null)
2719:                 {
2720:                         return true; // null pattern is equivalent to '*'
2721:                 }
2722:                 int iPattern = patternStart;
2723:                 int iName = nameStart;
2724:
2725:                 if (patternEnd < 0)
2726:                 {
2727:                         patternEnd = pattern.length;
2728:                 }
2729:                 if (nameEnd < 0)
2730:                 {
2731:                         nameEnd = name.length;
2732:                 }
2733:
2734:                 /* check first segment */
2735:                 char patternChar = 0;
2736:                 while (iPattern < patternEnd
2737:                                 && (patternChar = pattern[iPattern]) != '*')
2738:                 {
2739:                         if (iName == nameEnd)
2740:                         {
2741:                                 return false;
2742:                         }
2743:                         if (patternChar != (isCaseSensitive ? name[iName]
2744:                                         : Character.toLowerCase(name[iName])) && patternChar != '?')
2745:                         {
2746:                                 return false;
2747:                         }
2748:                         iName++;
2749:                         iPattern++;
2750:                 }
2751:                 /* check sequence of star+segment */
2752:                 int segmentStart;
2753:                 if (patternChar == '*')
2754:                 {
2755:                         segmentStart = ++iPattern; // skip star
2756:                 } else
2757:                 {
2758:                         segmentStart = 0; // force iName check
2759:                 }
2760:                 int prefixStart = iName;
2761:                 checkSegment: while (iName < nameEnd)
2762:                 {
2763:                         if (iPattern == patternEnd)
2764:                         {
2765:                                 iPattern = segmentStart; // mismatch - restart current
2766:                                 // segment
2767:                                 iName = ++prefixStart;
2768:                                 continue checkSegment;
2769:                         }
2770:                         /* segment is ending */
2771:                         if ((patternChar = pattern[iPattern]) == '*')
2772:                         {
2773:                                 segmentStart = ++iPattern; // skip start
2774:                                 if (segmentStart == patternEnd)
2775:                                 {
2776:                                         return true;
2777:                                 }
2778:                                 prefixStart = iName;
2779:                                 continue checkSegment;
2780:                         }
2781:                         /* check current name character */
2782:                         if ((isCaseSensitive ? name[iName]
2783:                                         : Character.toLowerCase(name[iName])) != patternChar
2784:                                         && patternChar != '?')
2785:                         {
2786:                                 iPattern = segmentStart; // mismatch - restart current
2787:                                 // segment
2788:                                 iName = ++prefixStart;
2789:                                 continue checkSegment;
2790:                         }
2791:                         iName++;
2792:                         iPattern++;
2793:                 }
2794:
2795:                 return segmentStart == patternEnd || iName == nameEnd
2796:                                 && iPattern == patternEnd || iPattern == patternEnd - 1
2797:                                 && pattern[iPattern] == '*';
2798:         }
2799:
2800:         /**
2801:          * Answers true if the pattern matches the filepath using the pathSepatator, false otherwise. Path char[] pattern
2802:          * matching, accepting wild-cards '**', '*' and '?' (using Ant directory tasks conventions, also see
2803:          * "http://jakarta.apache.org/ant/manual/dirtasks.html#defaultexcludes"). Path pattern matching is enhancing regular
2804:          * pattern matching in supporting extra rule where '**' represent any folder combination. Special rule: - foo\ is
2805:          * equivalent to foo\** When not case sensitive, the pattern is assumed to already be lowercased, the name will be
2806:          * lowercased character per character as comparing.
2807:          *
2808:          * @param pattern
2809:          * the given pattern
2810:          * @param filepath
2811:          * the given path
2812:          * @param isCaseSensitive
2813:          * to find out whether or not the matching should be case sensitive
2814:          * @param pathSeparator
2815:          * the given path separator
2816:          * @return true if the pattern matches the filepath using the pathSepatator, false otherwise
2817:          */
2818:         public static final boolean pathMatch(char[] pattern, char[] filepath,
2819:                         boolean isCaseSensitive, char pathSeparator)
2820:         {
2821:
2822:                 if (filepath == null)
2823:                 {
2824:                         return false; // null name cannot match
2825:                 }
2826:                 if (pattern == null)
2827:                 {
2828:                         return true; // null pattern is equivalent to '*'
2829:                 }
2830:
2831:                 // offsets inside pattern
2832:                 int pSegmentStart = pattern[0] == pathSeparator ? 1 : 0;
2833:                 int pLength = pattern.length;
2834:                 int pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart + 1);
2835:                 if (pSegmentEnd < 0)
2836:                 {
2837:                         pSegmentEnd = pLength;
2838:                 }
2839:
2840:                 // special case: pattern foo\ is equivalent to foo\**
2841:                 boolean freeTrailingDoubleStar = pattern[pLength - 1] == pathSeparator;
2842:
2843:                 // offsets inside filepath
2844:                 int fSegmentStart, fLength = filepath.length;
2845:                 if (filepath[0] != pathSeparator)
2846:                 {
2847:                         fSegmentStart = 0;
2848:                 } else
2849:                 {
2850:                         fSegmentStart = 1;
2851:                 }
2852:                 if (fSegmentStart != pSegmentStart)
2853:                 {
2854:                         return false; // both must start with a separator or none.
2855:                 }
2856:                 int fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, fSegmentStart + 1);
2857:                 if (fSegmentEnd < 0)
2858:                 {
2859:                         fSegmentEnd = fLength;
2860:                 }
2861:
2862:                 // first segments
2863:                 while (pSegmentStart < pLength
2864:                                 && !(pSegmentEnd == pLength && freeTrailingDoubleStar || pSegmentEnd == pSegmentStart + 2
2865:                                                 && pattern[pSegmentStart] == '*'
2866:                                                 && pattern[pSegmentStart + 1] == '*'))
2867:                 {
2868:
2869:                         if (fSegmentStart >= fLength)
2870:                         {
2871:                                 return false;
2872:                         }
2873:                         if (!CharOperation.match(pattern, pSegmentStart, pSegmentEnd, filepath, fSegmentStart, fSegmentEnd, isCaseSensitive))
2874:                         {
2875:                                 return false;
2876:                         }
2877:
2878:                         // jump to next segment
2879:                         pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentEnd + 1);
2880:                         // skip separator
2881:                         if (pSegmentEnd < 0)
2882:                         {
2883:                                 pSegmentEnd = pLength;
2884:                         }
2885:
2886:                         fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentEnd + 1);
2887:                         // skip separator
2888:                         if (fSegmentEnd < 0)
2889:                         {
2890:                                 fSegmentEnd = fLength;
2891:                         }
2892:                 }
2893:
2894:                 /* check sequence of doubleStar+segment */
2895:                 int pSegmentRestart;
2896:                 if (pSegmentStart >= pLength && freeTrailingDoubleStar
2897:                                 || pSegmentEnd == pSegmentStart + 2
2898:                                 && pattern[pSegmentStart] == '*'
2899:                                 && pattern[pSegmentStart + 1] == '*')
2900:                 {
2901:                         pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentEnd + 1);
2902:                         // skip separator
2903:                         if (pSegmentEnd < 0)
2904:                         {
2905:                                 pSegmentEnd = pLength;
2906:                         }
2907:                         pSegmentRestart = pSegmentStart;
2908:                 } else
2909:                 {
2910:                         if (pSegmentStart >= pLength)
2911:                         {
2912:                                 return fSegmentStart >= fLength; // true if filepath is done
2913:                         }
2914:                         // too.
2915:                         pSegmentRestart = 0; // force fSegmentStart check
2916:                 }
2917:                 int fSegmentRestart = fSegmentStart;
2918:                 checkSegment: while (fSegmentStart < fLength)
2919:                 {
2920:
2921:                         if (pSegmentStart >= pLength)
2922:                         {
2923:                                 if (freeTrailingDoubleStar)
2924:                                 {
2925:                                         return true;
2926:                                 }
2927:                                 // mismatch - restart current path segment
2928:                                 pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentRestart);
2929:                                 if (pSegmentEnd < 0)
2930:                                 {
2931:                                         pSegmentEnd = pLength;
2932:                                 }
2933:
2934:                                 fSegmentRestart = CharOperation.indexOf(pathSeparator, filepath, fSegmentRestart + 1);
2935:                                 // skip separator
2936:                                 if (fSegmentRestart < 0)
2937:                                 {
2938:                                         fSegmentRestart = fLength;
2939:                                 } else
2940:                                 {
2941:                                         fSegmentRestart++;
2942:                                 }
2943:                                 fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentRestart);
2944:                                 if (fSegmentEnd < 0)
2945:                                 {
2946:                                         fSegmentEnd = fLength;
2947:                                 }
2948:                                 continue checkSegment;
2949:                         }
2950:
2951:                         /* path segment is ending */
2952:                         if (pSegmentEnd == pSegmentStart + 2
2953:                                         && pattern[pSegmentStart] == '*'
2954:                                         && pattern[pSegmentStart + 1] == '*')
2955:                         {
2956:                                 pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentEnd + 1);
2957:                                 // skip separator
2958:                                 if (pSegmentEnd < 0)
2959:                                 {
2960:                                         pSegmentEnd = pLength;
2961:                                 }
2962:                                 pSegmentRestart = pSegmentStart;
2963:                                 fSegmentRestart = fSegmentStart;
2964:                                 if (pSegmentStart >= pLength)
2965:                                 {
2966:                                         return true;
2967:                                 }
2968:                                 continue checkSegment;
2969:                         }
2970:                         /* chech current path segment */
2971:                         if (!CharOperation.match(pattern, pSegmentStart, pSegmentEnd, filepath, fSegmentStart, fSegmentEnd, isCaseSensitive))
2972:                         {
2973:                                 // mismatch - restart current path segment
2974:                                 pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentRestart);
2975:                                 if (pSegmentEnd < 0)
2976:                                 {
2977:                                         pSegmentEnd = pLength;
2978:                                 }
2979:
2980:                                 fSegmentRestart = CharOperation.indexOf(pathSeparator, filepath, fSegmentRestart + 1);
2981:                                 // skip separator
2982:                                 if (fSegmentRestart < 0)
2983:                                 {
2984:                                         fSegmentRestart = fLength;
2985:                                 } else
2986:                                 {
2987:                                         fSegmentRestart++;
2988:                                 }
2989:                                 fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentRestart);
2990:                                 if (fSegmentEnd < 0)
2991:                                 {
2992:                                         fSegmentEnd = fLength;
2993:                                 }
2994:                                 continue checkSegment;
2995:                         }
2996:                         // jump to next segment
2997:                         pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentEnd + 1);
2998:                         // skip separator
2999:                         if (pSegmentEnd < 0)
3000:                         {
3001:                                 pSegmentEnd = pLength;
3002:                         }
3003:
3004:                         fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentEnd + 1);
3005:                         // skip separator
3006:                         if (fSegmentEnd < 0)
3007:                         {
3008:                                 fSegmentEnd = fLength;
3009:                         }
3010:                 }
3011:
3012:                 return pSegmentRestart >= pSegmentEnd || fSegmentStart >= fLength
3013:                                 && pSegmentStart >= pLength || pSegmentStart == pLength - 2
3014:                                 && pattern[pSegmentStart] == '*'
3015:                                 && pattern[pSegmentStart + 1] == '*'
3016:                                 || pSegmentStart == pLength && freeTrailingDoubleStar;
3017:         }
3018:
3019:         /**
3020:          * Answers the number of occurrences of the given character in the given array, 0 if any. <br>
3021:          * <br>
3022:          * For example:
3023:          * <ol>
3024:          * <li>
3025:          *
3026:          * <pre>
3027:          * toBeFound = 'b'
3028:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3029:          * result => 3
3030:          * </pre>
3031:          *
3032:          * </li>
3033:          * <li>
3034:          *
3035:          * <pre>
3036:          * toBeFound = 'c'
3037:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3038:          * result => 0
3039:          * </pre>
3040:          *
3041:          * </li>
3042:          * </ol>
3043:          *
3044:          * @param toBeFound
3045:          * the given character
3046:          * @param array
3047:          * the given array
3048:          * @return the number of occurrences of the given character in the given array, 0 if any
3049:          * @throws NullPointerException
3050:          * if array is null
3051:          */
3052:         public static final int occurencesOf(char toBeFound, char[] array)
3053:         {
3054:                 int count = 0;
3055:                 for (int i = 0; i < array.length; i++)
3056:                 {
3057:                         if (toBeFound == array[i])
3058:                         {
3059:                                 count++;
3060:                         }
3061:                 }
3062:                 return count;
3063:         }
3064:
3065:         /**
3066:          * Answers the number of occurrences of the given character in the given array starting at the given index, 0 if
3067:          * any. <br>
3068:          * <br>
3069:          * For example:
3070:          * <ol>
3071:          * <li>
3072:          *
3073:          * <pre>
3074:          * toBeFound = 'b'
3075:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3076:          * start = 2
3077:          * result => 2
3078:          * </pre>
3079:          *
3080:          * </li>
3081:          * <li>
3082:          *
3083:          * <pre>
3084:          * toBeFound = 'c'
3085:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3086:          * start = 0
3087:          * result => 0
3088:          * </pre>
3089:          *
3090:          * </li>
3091:          * </ol>
3092:          *
3093:          * @param toBeFound
3094:          * the given character
3095:          * @param array
3096:          * the given array
3097:          * @param start
3098:          * the given index
3099:          * @return the number of occurrences of the given character in the given array, 0 if any
3100:          * @throws NullPointerException
3101:          * if array is null
3102:          * @throws ArrayIndexOutOfBoundsException
3103:          * if start is lower than 0
3104:          */
3105:         public static final int occurencesOf(char toBeFound, char[] array, int start)
3106:         {
3107:                 int count = 0;
3108:                 for (int i = start; i < array.length; i++)
3109:                 {
3110:                         if (toBeFound == array[i])
3111:                         {
3112:                                 count++;
3113:                         }
3114:                 }
3115:                 return count;
3116:         }
3117:
3118:         /**
3119:          * Answers true if the given name starts with the given prefix, false otherwise. The comparison is case sensitive. <br>
3120:          * <br>
3121:          * For example:
3122:          * <ol>
3123:          * <li>
3124:          *
3125:          * <pre>
3126:          * prefix = { 'a' , 'b' }
3127:          * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3128:          * result => true
3129:          * </pre>
3130:          *
3131:          * </li>
3132:          * <li>
3133:          *
3134:          * <pre>
3135:          * prefix = { 'a' , 'c' }
3136:          * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3137:          * result => false
3138:          * </pre>
3139:          *
3140:          * </li>
3141:          * </ol>
3142:          *
3143:          * @param prefix
3144:          * the given prefix
3145:          * @param name
3146:          * the given name
3147:          * @return true if the given name starts with the given prefix, false otherwise
3148:          * @throws NullPointerException
3149:          * if the given name is null or if the given prefix is null
3150:          */
3151:         public static final boolean prefixEquals(char[] prefix, char[] name)
3152:         {
3153:
3154:                 int max = prefix.length;
3155:                 if (name.length < max)
3156:                 {
3157:                         return false;
3158:                 }
3159:                 for (int i = max; --i >= 0;)
3160:                 {
3161:                         // assumes the prefix is not larger than the name
3162:                         if (prefix[i] != name[i])
3163:                         {
3164:                                 return false;
3165:                         }
3166:                 }
3167:                 return true;
3168:         }
3169:
3170:         /**
3171:          * Answers true if the given name starts with the given prefix, false otherwise. isCaseSensitive is used to find out
3172:          * whether or not the comparison should be case sensitive. <br>
3173:          * <br>
3174:          * For example:
3175:          * <ol>
3176:          * <li>
3177:          *
3178:          * <pre>
3179:          * prefix = { 'a' , 'B' }
3180:          * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3181:          * isCaseSensitive = false
3182:          * result => true
3183:          * </pre>
3184:          *
3185:          * </li>
3186:          * <li>
3187:          *
3188:          * <pre>
3189:          * prefix = { 'a' , 'B' }
3190:          * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3191:          * isCaseSensitive = true
3192:          * result => false
3193:          * </pre>
3194:          *
3195:          * </li>
3196:          * </ol>
3197:          *
3198:          * @param prefix
3199:          * the given prefix
3200:          * @param name
3201:          * the given name
3202:          * @param isCaseSensitive
3203:          * to find out whether or not the comparison should be case sensitive
3204:          * @return true if the given name starts with the given prefix, false otherwise
3205:          * @throws NullPointerException
3206:          * if the given name is null or if the given prefix is null
3207:          */
3208:         public static final boolean prefixEquals(char[] prefix, char[] name,
3209:                         boolean isCaseSensitive)
3210:         {
3211:
3212:                 int max = prefix.length;
3213:                 if (name.length < max)
3214:                 {
3215:                         return false;
3216:                 }
3217:                 if (isCaseSensitive)
3218:                 {
3219:                         for (int i = max; --i >= 0;)
3220:                         {
3221:                                 // assumes the prefix is not larger than the name
3222:                                 if (prefix[i] != name[i])
3223:                                 {
3224:                                         return false;
3225:                                 }
3226:                         }
3227:                         return true;
3228:                 }
3229:
3230:                 for (int i = max; --i >= 0;)
3231:                 {
3232:                         // assumes the prefix is not larger than the name
3233:                         if (Character.toLowerCase(prefix[i]) != Character.toLowerCase(name[i]))
3234:                         {
3235:                                 return false;
3236:                         }
3237:                 }
3238:                 return true;
3239:         }
3240:
3241:         /**
3242:          * Replace all occurrence of the character to be replaced with the remplacement character in the given array. <br>
3243:          * <br>
3244:          * For example:
3245:          * <ol>
3246:          * <li>
3247:          *
3248:          * <pre>
3249:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3250:          * toBeReplaced = 'b'
3251:          * replacementChar = 'a'
3252:          * result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
3253:          * </pre>
3254:          *
3255:          * </li>
3256:          * <li>
3257:          *
3258:          * <pre>
3259:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3260:          * toBeReplaced = 'c'
3261:          * replacementChar = 'a'
3262:          * result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'a', 'b', 'a' }
3263:          * </pre>
3264:          *
3265:          * </li>
3266:          * </ol>
3267:          *
3268:          * @param array
3269:          * the given array
3270:          * @param toBeReplaced
3271:          * the character to be replaced
3272:          * @param replacementChar
3273:          * the replacement character
3274:          * @throws NullPointerException
3275:          * if the given array is null
3276:          */
3277:         public static final void replace(char[] array, char toBeReplaced,
3278:                         char replacementChar)
3279:         {
3280:                 if (toBeReplaced != replacementChar)
3281:                 {
3282:                         for (int i = 0, max = array.length; i < max; i++)
3283:                         {
3284:                                 if (array[i] == toBeReplaced)
3285:                                 {
3286:                                         array[i] = replacementChar;
3287:                                 }
3288:                         }
3289:                 }
3290:         }
3291:
3292:         /**
3293:          * Replace all occurrence of characters to be replaced with the remplacement character in the given array. <br>
3294:          * <br>
3295:          * For example:
3296:          * <ol>
3297:          * <li>
3298:          *
3299:          * <pre>
3300:          * array = { 'a' , 'b', 'b', 'c', 'a', 'b', 'c', 'a' }
3301:          * toBeReplaced = { 'b', 'c' }
3302:          * replacementChar = 'a'
3303:          * result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
3304:          * </pre>
3305:          *
3306:          * </li>
3307:          * </ol>
3308:          *
3309:          * @param array
3310:          * the given array
3311:          * @param toBeReplaced
3312:          * characters to be replaced
3313:          * @param replacementChar
3314:          * the replacement character
3315:          * @throws NullPointerException
3316:          * if arrays are null.
3317:          */
3318:         public static final void replace(char[] array, char[] toBeReplaced,
3319:                         char replacementChar)
3320:         {
3321:                 for (int i = array.length; --i >= 0;)
3322:                 {
3323:                         for (int j = toBeReplaced.length; --j >= 0;)
3324:                         {
3325:                                 if (array[i] == toBeReplaced[j])
3326:                                 {
3327:                                         array[i] = replacementChar;
3328:                                 }
3329:                         }
3330:                 }
3331:         }
3332:
3333:         /**
3334:          * Answers a new array of characters with substitutions. No side-effect is operated on the original array, in case
3335:          * no substitution happened, then the result is the same as the original one. <br>
3336:          * <br>
3337:          * For example:
3338:          * <ol>
3339:          * <li>
3340:          *
3341:          * <pre>
3342:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3343:          * toBeReplaced = { 'b' }
3344:          * replacementChar = { 'a', 'a' }
3345:          * result => { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
3346:          * </pre>
3347:          *
3348:          * </li>
3349:          * <li>
3350:          *
3351:          * <pre>
3352:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3353:          * toBeReplaced = { 'c' }
3354:          * replacementChar = { 'a' }
3355:          * result => { 'a' , 'b', 'b', 'a', 'b', 'a' }
3356:          * </pre>
3357:          *
3358:          * </li>
3359:          * </ol>
3360:          *
3361:          * @param array
3362:          * the given array
3363:          * @param toBeReplaced
3364:          * characters to be replaced
3365:          * @param replacementChars
3366:          * the replacement characters
3367:          * @return a new array of characters with substitutions or the given array if none
3368:          * @throws NullPointerException
3369:          * if the given array is null
3370:          */
3371:         public static final char[] replace(char[] array, char[] toBeReplaced,
3372:                         char[] replacementChars)
3373:         {
3374:
3375:                 int max = array.length;
3376:                 int replacedLength = toBeReplaced.length;
3377:                 int replacementLength = replacementChars.length;
3378:
3379:                 int[] starts = new int[5];
3380:                 int occurrenceCount = 0;
3381:
3382:                 if (!equals(toBeReplaced, replacementChars))
3383:                 {
3384:
3385:                         next: for (int i = 0; i < max; i++)
3386:                         {
3387:                                 int j = 0;
3388:                                 while (j < replacedLength)
3389:                                 {
3390:                                         if (i + j == max)
3391:                                         {
3392:                                                 continue next;
3393:                                         }
3394:                                         if (array[i + j] != toBeReplaced[j++])
3395:                                         {
3396:                                                 continue next;
3397:                                         }
3398:                                 }
3399:                                 if (occurrenceCount == starts.length)
3400:                                 {
3401:                                         System.arraycopy(starts, 0, starts = new int[occurrenceCount * 2], 0, occurrenceCount);
3402:                                 }
3403:                                 starts[occurrenceCount++] = i;
3404:                         }
3405:                 }
3406:                 if (occurrenceCount == 0)
3407:                 {
3408:                         return array;
3409:                 }
3410:                 char[] result = new char[max + occurrenceCount
3411:                                 * (replacementLength - replacedLength)];
3412:                 int inStart = 0, outStart = 0;
3413:                 for (int i = 0; i < occurrenceCount; i++)
3414:                 {
3415:                         int offset = starts[i] - inStart;
3416:                         System.arraycopy(array, inStart, result, outStart, offset);
3417:                         inStart += offset;
3418:                         outStart += offset;
3419:                         System.arraycopy(replacementChars, 0, result, outStart, replacementLength);
3420:                         inStart += replacedLength;
3421:                         outStart += replacementLength;
3422:                 }
3423:                 System.arraycopy(array, inStart, result, outStart, max - inStart);
3424:                 return result;
3425:         }
3426:
3427:         /**
3428:          * Replace all occurrence of the character to be replaced with the remplacement character in a copy of the given
3429:          * array. Returns the given array if no occurrences of the character to be replaced are found. <br>
3430:          * <br>
3431:          * For example:
3432:          * <ol>
3433:          * <li>
3434:          *
3435:          * <pre>
3436:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3437:          * toBeReplaced = 'b'
3438:          * replacementChar = 'a'
3439:          * result => A new array that is equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
3440:          * </pre>
3441:          *
3442:          * </li>
3443:          * <li>
3444:          *
3445:          * <pre>
3446:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3447:          * toBeReplaced = 'c'
3448:          * replacementChar = 'a'
3449:          * result => The original array that remains unchanged.
3450:          * </pre>
3451:          *
3452:          * </li>
3453:          * </ol>
3454:          *
3455:          * @param array
3456:          * the given array
3457:          * @param toBeReplaced
3458:          * the character to be replaced
3459:          * @param replacementChar
3460:          * the replacement character
3461:          * @throws NullPointerException
3462:          * if the given array is null
3463:          */
3464:         public static final char[] replaceOnCopy(char[] array, char toBeReplaced,
3465:                         char replacementChar)
3466:         {
3467:
3468:                 char[] result = null;
3469:                 for (int i = 0, length = array.length; i < length; i++)
3470:                 {
3471:                         char c = array[i];
3472:                         if (c == toBeReplaced)
3473:                         {
3474:                                 if (result == null)
3475:                                 {
3476:                                         result = new char[length];
3477:                                         System.arraycopy(array, 0, result, 0, i);
3478:                                 }
3479:                                 result[i] = replacementChar;
3480:                         } else if (result != null)
3481:                         {
3482:                                 result[i] = c;
3483:                         }
3484:                 }
3485:                 if (result == null)
3486:                 {
3487:                         return array;
3488:                 }
3489:                 return result;
3490:         }
3491:
3492:         /**
3493:          * Return a new array which is the split of the given array using the given divider and triming each subarray to
3494:          * remove whitespaces equals to ' '. <br>
3495:          * <br>
3496:          * For example:
3497:          * <ol>
3498:          * <li>
3499:          *
3500:          * <pre>
3501:          * divider = 'b'
3502:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3503:          * result => { { 'a' }, { }, { 'a' }, { 'a' } }
3504:          * </pre>
3505:          *
3506:          * </li>
3507:          * <li>
3508:          *
3509:          * <pre>
3510:          * divider = 'c'
3511:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3512:          * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
3513:          * </pre>
3514:          *
3515:          * </li>
3516:          * <li>
3517:          *
3518:          * <pre>
3519:          * divider = 'b'
3520:          * array = { 'a' , ' ', 'b', 'b', 'a', 'b', 'a' }
3521:          * result => { { 'a' }, { }, { 'a' }, { 'a' } }
3522:          * </pre>
3523:          *
3524:          * </li>
3525:          * <li>
3526:          *
3527:          * <pre>
3528:          * divider = 'c'
3529:          * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
3530:          * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
3531:          * </pre>
3532:          *
3533:          * </li>
3534:          * </ol>
3535:          *
3536:          * @param divider
3537:          * the given divider
3538:          * @param array
3539:          * the given array
3540:          * @return a new array which is the split of the given array using the given divider and triming each subarray to
3541:          * remove whitespaces equals to ' '
3542:          */
3543:         public static final char[][] splitAndTrimOn(char divider, char[] array)
3544:         {
3545:                 int length = array == null ? 0 : array.length;
3546:                 if (length == 0)
3547:                 {
3548:                         return NO_CHAR_CHAR;
3549:                 }
3550:
3551:                 int wordCount = 1;
3552:                 for (int i = 0; i < length; i++)
3553:                 {
3554:                         if (array[i] == divider)
3555:                         {
3556:                                 wordCount++;
3557:                         }
3558:                 }
3559:                 char[][] split = new char[wordCount][];
3560:                 int last = 0, currentWord = 0;
3561:                 for (int i = 0; i < length; i++)
3562:                 {
3563:                         if (array[i] == divider)
3564:                         {
3565:                                 int start = last, end = i - 1;
3566:                                 while (start < i && array[start] == ' ')
3567:                                 {
3568:                                         start++;
3569:                                 }
3570:                                 while (end > start && array[end] == ' ')
3571:                                 {
3572:                                         end--;
3573:                                 }
3574:                                 split[currentWord] = new char[end - start + 1];
3575:                                 System.arraycopy(array, start, split[currentWord++], 0, end
3576:                                                 - start + 1);
3577:                                 last = i + 1;
3578:                         }
3579:                 }
3580:                 int start = last, end = length - 1;
3581:                 while (start < length && array[start] == ' ')
3582:                 {
3583:                         start++;
3584:                 }
3585:                 while (end > start && array[end] == ' ')
3586:                 {
3587:                         end--;
3588:                 }
3589:                 split[currentWord] = new char[end - start + 1];
3590:                 System.arraycopy(array, start, split[currentWord++], 0, end - start + 1);
3591:                 return split;
3592:         }
3593:
3594:         /**
3595:          * Return a new array which is the split of the given array using the given divider. <br>
3596:          * <br>
3597:          * For example:
3598:          * <ol>
3599:          * <li>
3600:          *
3601:          * <pre>
3602:          * divider = 'b'
3603:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3604:          * result => { { 'a' }, { }, { 'a' }, { 'a' } }
3605:          * </pre>
3606:          *
3607:          * </li>
3608:          * <li>
3609:          *
3610:          * <pre>
3611:          * divider = 'c'
3612:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3613:          * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
3614:          * </pre>
3615:          *
3616:          * </li>
3617:          * <li>
3618:          *
3619:          * <pre>
3620:          * divider = 'c'
3621:          * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
3622:          * result => { { ' ', 'a', 'b', 'b', 'a', 'b', 'a', ' ' } }
3623:          * </pre>
3624:          *
3625:          * </li>
3626:          * </ol>
3627:          *
3628:          * @param divider
3629:          * the given divider
3630:          * @param array
3631:          * the given array
3632:          * @return a new array which is the split of the given array using the given divider
3633:          */
3634:         public static final char[][] splitOn(char divider, char[] array)
3635:         {
3636:                 int length = array == null ? 0 : array.length;
3637:                 if (length == 0)
3638:                 {
3639:                         return NO_CHAR_CHAR;
3640:                 }
3641:
3642:                 int wordCount = 1;
3643:                 for (int i = 0; i < length; i++)
3644:                 {
3645:                         if (array[i] == divider)
3646:                         {
3647:                                 wordCount++;
3648:                         }
3649:                 }
3650:                 char[][] split = new char[wordCount][];
3651:                 int last = 0, currentWord = 0;
3652:                 for (int i = 0; i < length; i++)
3653:                 {
3654:                         if (array[i] == divider)
3655:                         {
3656:                                 split[currentWord] = new char[i - last];
3657:                                 System.arraycopy(array, last, split[currentWord++], 0, i - last);
3658:                                 last = i + 1;
3659:                         }
3660:                 }
3661:                 split[currentWord] = new char[length - last];
3662:                 System.arraycopy(array, last, split[currentWord], 0, length - last);
3663:                 return split;
3664:         }
3665:
3666:         /**
3667:          * Return a new array which is the split of the given array using the given divider.
3668:          *
3669:          * @param divider
3670:          * the given divider
3671:          * @param array
3672:          * the given array
3673:          * @return a new array which is the split of the given array using the given divider or <code>null</code> if
3674:          * {@code array} parameter is <code>null</code>.
3675:          */
3676:         public static final char[][] splitOn(char[] divider, char[] array)
3677:         {
3678:                 if (array == null)
3679:                 {
3680:                         return null;
3681:                 }
3682:                 int length = array.length;
3683:                 if (length == 0)
3684:                 {
3685:                         return NO_CHAR_CHAR;
3686:                 }
3687:
3688:                 int wordCount = 1;
3689:                 {
3690:                         int i = 0;
3691:                         while (i + divider.length <= length)
3692:                         {
3693:                                 i = indexOf(divider, array, false, i);
3694:                                 if (i == -1)
3695:                                 {
3696:                                         break;
3697:                                 }
3698:                                 ++wordCount;
3699:                                 i += divider.length;
3700:                         }
3701:                 }
3702:                 char[][] split = new char[wordCount][];
3703:                 int last = 0, currentWord = 0;
3704:                 int i = 0;
3705:                 while (i + divider.length <= length)
3706:                 {
3707:                         i = indexOf(divider, array, false, i);
3708:                         if (i == -1)
3709:                         {
3710:                                 break;
3711:                         }
3712:                         split[currentWord] = new char[i - last];
3713:                         System.arraycopy(array, last, split[currentWord++], 0, i - last);
3714:                         i += divider.length;
3715:                         last = i;
3716:                 }
3717:                 split[currentWord] = new char[length - last];
3718:                 System.arraycopy(array, last, split[currentWord], 0, length - last);
3719:                 return split;
3720:         }
3721:
3722:         /**
3723:          * Return a new array which is the split of the given array using the given divider. The given end is exclusive and
3724:          * the given start is inclusive. <br>
3725:          * <br>
3726:          * For example:
3727:          * <ol>
3728:          * <li>
3729:          *
3730:          * <pre>
3731:          * divider = 'b'
3732:          * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
3733:          * start = 2
3734:          * end = 5
3735:          * result => { { }, { 'a' }, { } }
3736:          * </pre>
3737:          *
3738:          * </li>
3739:          * </ol>
3740:          *
3741:          * @param divider
3742:          * the given divider
3743:          * @param array
3744:          * the given array
3745:          * @param start
3746:          * the given starting index
3747:          * @param end
3748:          * the given ending index
3749:          * @return a new array which is the split of the given array using the given divider
3750:          * @throws ArrayIndexOutOfBoundsException
3751:          * if start is lower than 0 or end is greater than the array length
3752:          */
3753:         public static final char[][] splitOn(char divider, char[] array, int start,
3754:                         int end)
3755:         {
3756:                 int length = array == null ? 0 : array.length;
3757:                 if (length == 0 || start > end)
3758:                 {
3759:                         return NO_CHAR_CHAR;
3760:                 }
3761:
3762:                 int wordCount = 1;
3763:                 for (int i = start; i < end; i++)
3764:                 {
3765:                         if (array[i] == divider)
3766:                         {
3767:                                 wordCount++;
3768:                         }
3769:                 }
3770:                 char[][] split = new char[wordCount][];
3771:                 int last = start, currentWord = 0;
3772:                 for (int i = start; i < end; i++)
3773:                 {
3774:                         if (array[i] == divider)
3775:                         {
3776:                                 split[currentWord] = new char[i - last];
3777:                                 System.arraycopy(array, last, split[currentWord++], 0, i - last);
3778:                                 last = i + 1;
3779:                         }
3780:                 }
3781:                 split[currentWord] = new char[end - last];
3782:                 System.arraycopy(array, last, split[currentWord], 0, end - last);
3783:                 return split;
3784:         }
3785:
3786:         /**
3787:          * Answers a new array which is a copy of the given array starting at the given start and ending at the given end.
3788:          * The given start is inclusive and the given end is exclusive. Answers null if start is greater than end, if start
3789:          * is lower than 0 or if end is greater than the length of the given array. If end equals -1, it is converted to the
3790:          * array length. <br>
3791:          * <br>
3792:          * For example:
3793:          * <ol>
3794:          * <li>
3795:          *
3796:          * <pre>
3797:          * array = { { 'a' } , { 'b' } }
3798:          * start = 0
3799:          * end = 1
3800:          * result => { { 'a' } }
3801:          * </pre>
3802:          *
3803:          * </li>
3804:          * <li>
3805:          *
3806:          * <pre>
3807:          * array = { { 'a' } , { 'b' } }
3808:          * start = 0
3809:          * end = -1
3810:          * result => { { 'a' }, { 'b' } }
3811:          * </pre>
3812:          *
3813:          * </li>
3814:          * </ol>
3815:          *
3816:          * @param array
3817:          * the given array
3818:          * @param start
3819:          * the given starting index
3820:          * @param end
3821:          * the given ending index
3822:          * @return a new array which is a copy of the given array starting at the given start and ending at the given end
3823:          * @throws NullPointerException
3824:          * if the given array is null
3825:          */
3826:         public static final char[][] subarray(char[][] array, int start, int end)
3827:         {
3828:                 if (end == -1)
3829:                 {
3830:                         end = array.length;
3831:                 }
3832:                 if (start > end)
3833:                 {
3834:                         return null;
3835:                 }
3836:                 if (start < 0)
3837:                 {
3838:                         return null;
3839:                 }
3840:                 if (end > array.length)
3841:                 {
3842:                         return null;
3843:                 }
3844:
3845:                 char[][] result = new char[end - start][];
3846:                 System.arraycopy(array, start, result, 0, end - start);
3847:                 return result;
3848:         }
3849:
3850:         /**
3851:          * Answers a new array which is a copy of the given array starting at the given start and ending at the given end.
3852:          * The given start is inclusive and the given end is exclusive. Answers null if start is greater than end, if start
3853:          * is lower than 0 or if end is greater than the length of the given array. If end equals -1, it is converted to the
3854:          * array length. <br>
3855:          * <br>
3856:          * For example:
3857:          * <ol>
3858:          * <li>
3859:          *
3860:          * <pre>
3861:          * array = { 'a' , 'b' }
3862:          * start = 0
3863:          * end = 1
3864:          * result => { 'a' }
3865:          * </pre>
3866:          *
3867:          * </li>
3868:          * <li>
3869:          *
3870:          * <pre>
3871:          * array = { 'a', 'b' }
3872:          * start = 0
3873:          * end = -1
3874:          * result => { 'a' , 'b' }
3875:          * </pre>
3876:          *
3877:          * </li>
3878:          * </ol>
3879:          *
3880:          * @param array
3881:          * the given array
3882:          * @param start
3883:          * the given starting index
3884:          * @param end
3885:          * the given ending index
3886:          * @return a new array which is a copy of the given array starting at the given start and ending at the given end
3887:          * @throws NullPointerException
3888:          * if the given array is null
3889:          */
3890:         public static final char[] subarray(char[] array, int start, int end)
3891:         {
3892:                 if (end == -1)
3893:                 {
3894:                         end = array.length;
3895:                 }
3896:                 if (start > end)
3897:                 {
3898:                         return null;
3899:                 }
3900:                 if (start < 0)
3901:                 {
3902:                         return null;
3903:                 }
3904:                 if (end > array.length)
3905:                 {
3906:                         return null;
3907:                 }
3908:
3909:                 char[] result = new char[end - start];
3910:                 System.arraycopy(array, start, result, 0, end - start);
3911:                 return result;
3912:         }
3913:
3914:         /**
3915:          * Answers the result of a char[] conversion to lowercase. Answers null if the given chars array is null. <br>
3916:          * NOTE: If no conversion was necessary, then answers back the argument one. <br>
3917:          * <br>
3918:          * For example:
3919:          * <ol>
3920:          * <li>
3921:          *
3922:          * <pre>
3923:          * chars = { 'a' , 'b' }
3924:          * result => { 'a' , 'b' }
3925:          * </pre>
3926:          *
3927:          * </li>
3928:          * <li>
3929:          *
3930:          * <pre>
3931:          * array = { 'A', 'b' }
3932:          * result => { 'a' , 'b' }
3933:          * </pre>
3934:          *
3935:          * </li>
3936:          * </ol>
3937:          *
3938:          * @param chars
3939:          * the chars to convert
3940:          * @return the result of a char[] conversion to lowercase
3941:          */
3942:         final static public char[] toLowerCase(char[] chars)
3943:         {
3944:                 if (chars == null)
3945:                 {
3946:                         return null;
3947:                 }
3948:                 int length = chars.length;
3949:                 char[] lowerChars = null;
3950:                 for (int i = 0; i < length; i++)
3951:                 {
3952:                         char c = chars[i];
3953:                         char lc = Character.toLowerCase(c);
3954:                         if (c != lc || lowerChars != null)
3955:                         {
3956:                                 if (lowerChars == null)
3957:                                 {
3958:                                         System.arraycopy(chars, 0, lowerChars = new char[length], 0, i);
3959:                                 }
3960:                                 lowerChars[i] = lc;
3961:                         }
3962:                 }
3963:                 return lowerChars == null ? chars : lowerChars;
3964:         }
3965:
3966:         /**
3967:          * Answers a new array removing leading and trailing spaces (' '). Answers the given array if there is no space
3968:          * characters to remove. <br>
3969:          * <br>
3970:          * For example:
3971:          * <ol>
3972:          * <li>
3973:          *
3974:          * <pre>
3975:          * chars = { ' ', 'a' , 'b', ' ', ' ' }
3976:          * result => { 'a' , 'b' }
3977:          * </pre>
3978:          *
3979:          * </li>
3980:          * <li>
3981:          *
3982:          * <pre>
3983:          * array = { 'A', 'b' }
3984:          * result => { 'A' , 'b' }
3985:          * </pre>
3986:          *
3987:          * </li>
3988:          * </ol>
3989:          *
3990:          * @param chars
3991:          * the given array
3992:          * @return a new array removing leading and trailing spaces (' ')
3993:          */
3994:         final static public char[] trim(char[] chars)
3995:         {
3996:
3997:                 if (chars == null)
3998:                 {
3999:                         return null;
4000:                 }
4001:
4002:                 int start = 0, length = chars.length, end = length - 1;
4003:                 while (start < length && chars[start] == ' ')
4004:                 {
4005:                         start++;
4006:                 }
4007:                 while (end > start && chars[end] == ' ')
4008:                 {
4009:                         end--;
4010:                 }
4011:                 if (start != 0 || end != length - 1)
4012:                 {
4013:                         return subarray(chars, start, end + 1);
4014:                 }
4015:                 return chars;
4016:         }
4017:
4018:         /**
4019:          * Answers a string which is the concatenation of the given array using the '.' as a separator. <br>
4020:          * <br>
4021:          * For example:
4022:          * <ol>
4023:          * <li>
4024:          *
4025:          * <pre>
4026:          * array = { { 'a' } , { 'b' } }
4027:          * result => "a.b"
4028:          * </pre>
4029:          *
4030:          * </li>
4031:          * <li>
4032:          *
4033:          * <pre>
4034:          * array = { { ' ', 'a' } , { 'b' } }
4035:          * result => " a.b"
4036:          * </pre>
4037:          *
4038:          * </li>
4039:          * </ol>
4040:          *
4041:          * @param array
4042:          * the given array
4043:          * @return a string which is the concatenation of the given array using the '.' as a separator
4044:          */
4045:         final static public String toString(char[][] array)
4046:         {
4047:                 char[] result = concatWith(array, '.');
4048:                 return new String(result);
4049:         }
4050:
4051:         /**
4052:          * Answers an array of strings from the given array of char array.
4053:          *
4054:          * @param array
4055:          * the given array
4056:          * @return an array of strings
4057:          */
4058:         final static public String[] toStrings(char[][] array)
4059:         {
4060:                 if (array == null)
4061:                 {
4062:                         return NO_STRINGS;
4063:                 }
4064:                 int length = array.length;
4065:                 if (length == 0)
4066:                 {
4067:                         return NO_STRINGS;
4068:                 }
4069:                 String[] result = new String[length];
4070:                 for (int i = 0; i < length; i++)
4071:                 {
4072:                         result[i] = new String(array[i]);
4073:                 }
4074:                 return result;
4075:         }
4076:
4077:         /**
4078:          * @param name
4079:          * @param separator
4080:          * @return
4081:          */
4082:         public static String lastSegment(String name, char separator)
4083:         {
4084:                 int pos = name.lastIndexOf(separator);
4085:                 if (pos >= 0)
4086:                 {
4087:                         return name.substring(pos + 1);
4088:                 } else
4089:                 {
4090:                         return name;
4091:                 }
4092:         }
4093: }